<commit_before>const skipPunctuation = /[,.'’“”!]/g;
const spacePunctuation = /[()]/g;
const firstRegex = /\b1st/;
const secondRegex = /\b2nd/;
const thirdRegex = /\b3rd/;

// Implementation of Lazy derived from the code at
// https://dev.to/nestedsoftware/lazy-evaluation-in-javascript-with-generators-map-filter-and-reduce--36h5
class Lazy {
    constructor(iterable, callback) {
        this.iterable = iterable
        this.callback = callback
    }

    filter(callback) {
        return new LazyFilter(this, callback)
    }

    map(callback) {
        return new LazyMap(this, callback)
    }

    [Symbol.iterator]() {
        return {
            next: () => {
                return this.iterable.next();
            }
        }
    }

    next() {
        return this.iterable.next()
    }

    take(n) {
        const values = []
        for (let i = 0; i < n; i++) {
            values.push(this.next().value)
        }

        return values
    }
}

class LazyFilter extends Lazy {
    next() {
        while (true) {
            const item = this.iterable.next()

            if (this.callback(item.value)) {
                return item
            }
        }
    }
}

class LazyMap extends Lazy {
    next() {
        const item = this.iterable.next()

        const mappedValue = this.callback(item.value)
        return {
            value: mappedValue,
            done: item.done
        }
    }
}

function CamelCase(string, withSpaces = false) {
    if (string == null) {
        return "";
    }

    if (string.includes("&")) {
        string = string.replace("&", "and");
    }
    if (string.includes("#")) {
        string = string.replace("#", "Hash");
    }
    if (string.includes("*")) {
        string = string.replace("*", "Asterisk");
    }
    if (skipPunctuation.test(string)) {
        string = string.replace(skipPunctuation, "");
    }
    if (spacePunctuation.test(string)) {
        string = string.replace(spacePunctuation, " ");
    }
    if (firstRegex.test(string)) {
        string = string.replace(firstRegex, "First");
    }
    if (secondRegex.test(string)) {
        string = string.replace(secondRegex, "Second");
    }
    if (thirdRegex.test(string)) {
        string = string.replace(thirdRegex, "Third");
    }

    let result = new Array(string.length);
    let capitalize = true;
    for (const c of string) {
        if (c == " " || c == "-" || c == "_" || c == ':') {
            capitalize = true;
            if (withSpaces) {
                result.push(" ");
            }
            continue;
        }
        if (capitalize) {
            result.push(c.toUpperCase());
            capitalize = false;
        } else {
            result.push(c.toLowerCase());
        }
    }

    return result.join("");
}

function makeStringArray(keywords) {
    return keywords
        .split(/[ \-_:]/)
        .map(word => word.replace(skipPunctuation, ""))
        .map(word => word.replace(spacePunctuation, ""))
        .filter(word => word.length > 0)
        .map(word => word.toLowerCase())
        .filter(word => !/^(of|with|without|and|or|&|on|the|in)$/.test(word))
        .map(word => `"${word}"`)
        .join(", ");
}

function makeSortedSet(name, emoji) {
    result = `public static readonly SortedSet<SingleEmoji> ${name} = new SortedSet<SingleEmoji>() {
`;

    for (const e of emoji) {
        result += `\t/* ${e.symbol} */ ${CamelCase(e.name)},
`;
    }
    result += `};

`;

    $("#results").append(document.createTextNode(result))
}

function isBasicEmoji(emoji) {
    return !emoji.name.match(/skin tone|keycap/i);
}

function isGeneredEmoji(emoji) {
    return !emoji.name.startsWith("person");
}

function isUngenderedEmoji(emoji) {
    return !emoji.name.startsWith("man") && !emoji.name.startsWith("woman");
}

function emojiToCSharp(emoji) {
    return `/* ${emoji.symbol} */
public static readonly SingleEmoji ${CamelCase(emoji.name)} = new SingleEmoji(
        sequence: new UnicodeSequence("${emoji.sequence}"),
        name: "${emoji.name}",
        searchTerms: new [] { ${makeStringArray(emoji.name)} },
        sortOrder: ${emoji.index},
    );

`;
}

function loadFont(fontPath, callback) {
    var xhr = new XMLHttpRequest();
    xhr.overrideMimeType("text/plain");
    xhr.open('GET', fontPath, true);
    xhr.responseType = 'arraybuffer';

    xhr.onload = function(e) {
        if (this.status != 200) {
            console.log("Load font failed!");
            console.log(e);
            return;
        }

        var fkBlob = this.response;
        var fkBuffer = new Buffer(fkBlob);
        var font = fontkit.create(fkBuffer);
        callback(font);
    }
    xhr.send();
}

const menWomenRegex = /\b(men|women)\b/;

function fontSupportsEmoji(font, emoji) {
    // Hard-coded elimination: glyphs for Men* and Women* are the basic ungendered emoji
    // in Segoe UI Emoji, but with the gender icon tacked on.
    if (menWomenRegex.test(emoji.name)) {
        return false;
    }

    // We consider an emoji to be "supported" if it has a glyph in the COLR table, that
    // glyph has an id that is not 0, and it is rendered as only one, single glyph.
    let layout = font.layout(emoji.symbol);
    if (layout.glyphs.length != 1) {
        // This is not being rendered as a single emoji, which means it's not actually
        // supported.
        return false;
    }
    if (layout.glyphs[0].id == 0) {
        // This would be rendered as a placeholder for a missing glyph, so also not
        // supported.
        return false;
    }

    // All clear!
    return true;
}

function *parse(data) {
    const parser = /(.*?)\s+;.*# (\S+) (.*)/;
    const lines = data.split("\n");

    for (let i = 0; i < lines.length; ++i) {
        const line = lines[i];
        if (line.startsWith("#") || !line.includes("fully-qualified")) {
            continue;
        }

        let results = line.match(parser);

        let emoji = {
            "sequence": results[1],
            "symbol": results[2],
            "name": results[3],
            "index": i++,
        };

        yield emoji;
    }
}

function parseEmoji(data) {
    return new Lazy(parse(data), () => true);
}

const manWomanRegex = /^(man|woman)/i;
const manWomanRegexPlus = /^(man|woman) */i;

// This should not be passed a generator but rather a full-on Array
function ungenderedEmoji(emoji) {
    // Yes, this is insanely slow and could be optimized by making a trimmed & sorted
    // second/third list and taking the distinct union, but who cares?
    return emoji.filter(e => !manWomanRegex.test(e.name) ||
        !emoji.some(e2 => (e2.name.toLowerCase() == e.name.replace(manWomanRegex, "person").toLowerCase() ||
            e2.name.toLowerCase() == e.name.replace(manWomanRegexPlus, "").toLowerCase())));
}

loadFont("./seguiemj.ttf", font => {
    // emoji-test.txt from http://unicode.org/Public/emoji/5.0/emoji-test.txt

    var xhr = new XMLHttpRequest();
    xhr.overrideMimeType("text/plain");
    xhr.open('GET', "emoji-test.txt", true);
    xhr.responseType = 'text';

    xhr.onload = function(e) {
        if (this.status != 200) {
            console.log("Load emoji-test.txt failed!");
            console.log(e);
            return;
        }

        let emoji = Array.from(parseEmoji(this.responseText)); // all emoji

        // Dump actual emoji objects. All other operations print only references to these.
        for (const e of emoji) {
            $("#results").append(document.createTextNode(emojiToCSharp(e)))
        }

        // Dump all emoji list
        makeSortedSet("All", emoji);

        // Some partial lists of emoji filtered by certain criteria
        let basicEmoji = emoji.filter(isBasicEmoji); // removes meta emoji
        let basicUngenderedEmoji = ungenderedEmoji(Array.from(basicEmoji));

        // Narrow it down to emoji supported by Segoe UI Emoji
        let supportedEmoji = basicUngenderedEmoji
            .filter(isBasicEmoji)
            .filter(e => fontSupportsEmoji(font, e));

        // Dump list of ungendered emoji
        makeSortedSet("Basic", supportedEmoji);
    };

    xhr.send();
});
<commit_msg>Add importing of basic group and subgroup properties<commit_after>const skipPunctuation = /[,.'’“”!]/g;
const spacePunctuation = /[()]/g;
const firstRegex = /\b1st/;
const secondRegex = /\b2nd/;
const thirdRegex = /\b3rd/;

// Implementation of Lazy derived from the code at
// https://dev.to/nestedsoftware/lazy-evaluation-in-javascript-with-generators-map-filter-and-reduce--36h5
class Lazy {
    constructor(iterable, callback) {
        this.iterable = iterable
        this.callback = callback
    }

    filter(callback) {
        return new LazyFilter(this, callback)
    }

    map(callback) {
        return new LazyMap(this, callback)
    }

    [Symbol.iterator]() {
        return {
            next: () => {
                return this.iterable.next();
            }
        }
    }

    next() {
        return this.iterable.next()
    }

    take(n) {
        const values = []
        for (let i = 0; i < n; i++) {
            values.push(this.next().value)
        }

        return values
    }
}

class LazyFilter extends Lazy {
    next() {
        while (true) {
            const item = this.iterable.next()

            if (this.callback(item.value)) {
                return item
            }
        }
    }
}

class LazyMap extends Lazy {
    next() {
        const item = this.iterable.next()

        const mappedValue = this.callback(item.value)
        return {
            value: mappedValue,
            done: item.done
        }
    }
}

function CamelCase(string, withSpaces = false) {
    if (string == null) {
        return "";
    }

    if (string.includes("&")) {
        string = string.replace("&", "and");
    }
    if (string.includes("#")) {
        string = string.replace("#", "Hash");
    }
    if (string.includes("*")) {
        string = string.replace("*", "Asterisk");
    }
    if (skipPunctuation.test(string)) {
        string = string.replace(skipPunctuation, "");
    }
    if (spacePunctuation.test(string)) {
        string = string.replace(spacePunctuation, " ");
    }
    if (firstRegex.test(string)) {
        string = string.replace(firstRegex, "First");
    }
    if (secondRegex.test(string)) {
        string = string.replace(secondRegex, "Second");
    }
    if (thirdRegex.test(string)) {
        string = string.replace(thirdRegex, "Third");
    }

    let result = new Array(string.length);
    let capitalize = true;
    for (const c of string) {
        if (c == " " || c == "-" || c == "_" || c == ':') {
            capitalize = true;
            if (withSpaces) {
                result.push(" ");
            }
            continue;
        }
        if (capitalize) {
            result.push(c.toUpperCase());
            capitalize = false;
        } else {
            result.push(c.toLowerCase());
        }
    }

    return result.join("");
}

function makeStringArray(keywords) {
    return keywords
        .split(/[ \-_:]/)
        .map(word => word.replace(skipPunctuation, ""))
        .map(word => word.replace(spacePunctuation, ""))
        .filter(word => word.length > 0)
        .map(word => word.toLowerCase())
        .filter(word => !/^(of|with|without|and|or|&|on|the|in)$/.test(word))
        .map(word => `"${word}"`)
        .join(", ");
}

function makeSortedSet(name, emoji) {
    result = `public static readonly SortedSet<SingleEmoji> ${name} = new SortedSet<SingleEmoji>() {
`;

    for (const e of emoji) {
        result += `\t/* ${e.symbol} */ ${CamelCase(e.name)},
`;
    }
    result += `};

`;

    $("#results").append(document.createTextNode(result))
}

function isBasicEmoji(emoji) {
    return !emoji.name.match(/skin tone|keycap/i);
}

function isGeneredEmoji(emoji) {
    return !emoji.name.startsWith("person");
}

function isUngenderedEmoji(emoji) {
    return !emoji.name.startsWith("man") && !emoji.name.startsWith("woman");
}

function emojiToCSharp(emoji) {
    return `/* ${emoji.symbol} */
public static readonly SingleEmoji ${CamelCase(emoji.name)} = new SingleEmoji(
        sequence: new UnicodeSequence("${emoji.sequence}"),
        name: "${emoji.name}",
        group: "${emoji.group}",
        subgroup: "${emoji.subgroup}",
        searchTerms: new [] { ${makeStringArray(emoji.name)} },
        sortOrder: ${emoji.index},
    );

`;
}

function loadFont(fontPath, callback) {
    var xhr = new XMLHttpRequest();
    xhr.overrideMimeType("text/plain");
    xhr.open('GET', fontPath, true);
    xhr.responseType = 'arraybuffer';

    xhr.onload = function(e) {
        if (this.status != 200) {
            console.log("Load font failed!");
            console.log(e);
            return;
        }

        var fkBlob = this.response;
        var fkBuffer = new Buffer(fkBlob);
        var font = fontkit.create(fkBuffer);
        callback(font);
    }
    xhr.send();
}

const menWomenRegex = /\b(men|women)\b/;

function fontSupportsEmoji(font, emoji) {
    // Hard-coded elimination: glyphs for Men* and Women* are the basic ungendered emoji
    // in Segoe UI Emoji, but with the gender icon tacked on.
    if (menWomenRegex.test(emoji.name)) {
        return false;
    }

    // We consider an emoji to be "supported" if it has a glyph in the COLR table, that
    // glyph has an id that is not 0, and it is rendered as only one, single glyph.
    let layout = font.layout(emoji.symbol);
    if (layout.glyphs.length != 1) {
        // This is not being rendered as a single emoji, which means it's not actually
        // supported.
        return false;
    }
    if (layout.glyphs[0].id == 0) {
        // This would be rendered as a placeholder for a missing glyph, so also not
        // supported.
        return false;
    }

    // All clear!
    return true;
}

function *parse(data) {
    const parser = /(.*?)\s+;.*# (\S+) (.*)/;
    const lines = data.split("\n");
    const groupRegex = /\bgroup: \s*(\S.+?)\s*$/;
    const subgroupRegex = /subgroup: \s*(\S.+?)\s*$/;

    let group = "";
    let subgroup = "";
    for (let i = 0; i < lines.length; ++i) {
        const line = lines[i];
        if (line.startsWith("#") || !line.includes("fully-qualified")) {
            if (match = line.match(groupRegex)) {
                group = (match[1]);
            } else if (match = line.match(subgroupRegex)) {
                subgroup = (match[1]);
            }
            continue;
        }

        let results = line.match(parser);

        yield {
            "sequence": results[1],
            "symbol": results[2],
            "name": results[3],
            "index": i++,
            "group": group,
            "subgroup": subgroup,
        };
    }
}

function parseEmoji(data) {
    return new Lazy(parse(data), () => true);
}

const manWomanRegex = /^(man|woman)/i;
const manWomanRegexPlus = /^(man|woman) */i;

// This should not be passed a generator but rather a full-on Array
function ungenderedEmoji(emoji) {
    // Yes, this is insanely slow and could be optimized by making a trimmed & sorted
    // second/third list and taking the distinct union, but who cares?
    return emoji.filter(e => !manWomanRegex.test(e.name) ||
        !emoji.some(e2 => (e2.name.toLowerCase() == e.name.replace(manWomanRegex, "person").toLowerCase() ||
            e2.name.toLowerCase() == e.name.replace(manWomanRegexPlus, "").toLowerCase())));
}

loadFont("./seguiemj.ttf", font => {
    // emoji-test.txt from http://unicode.org/Public/emoji/5.0/emoji-test.txt

    var xhr = new XMLHttpRequest();
    xhr.overrideMimeType("text/plain");
    xhr.open('GET', "emoji-test.txt", true);
    xhr.responseType = 'text';

    xhr.onload = function(e) {
        if (this.status != 200) {
            console.log("Load emoji-test.txt failed!");
            console.log(e);
            return;
        }

        let emoji = Array.from(parseEmoji(this.responseText)); // all emoji

        // Dump actual emoji objects. All other operations print only references to these.
        for (const e of emoji) {
            $("#results").append(document.createTextNode(emojiToCSharp(e)))
        }

        // Dump all emoji list
        makeSortedSet("All", emoji);

        // Some partial lists of emoji filtered by certain criteria
        let basicEmoji = emoji.filter(isBasicEmoji); // removes meta emoji
        let basicUngenderedEmoji = ungenderedEmoji(Array.from(basicEmoji));

        // Narrow it down to emoji supported by Segoe UI Emoji
        let supportedEmoji = basicUngenderedEmoji
            .filter(isBasicEmoji)
            .filter(e => fontSupportsEmoji(font, e));

        // Dump list of ungendered emoji
        makeSortedSet("Basic", supportedEmoji);
    };

    xhr.send();
});
<|endoftext|>


<commit_before>var
	Session
		= (function()
	{
		var
			messageHandlers
				= {},

			ws,

			// ...

			open
				= function(deviceConnectionUrl, supports)
			{
				var
					supportsParam
						= '';

				// ...

				for (var i = 0; i < supports.length; i++)
				{
					supportsParam += supports[i];

					if (i !== supports.length - 1)
					{
						supportsParam += ',';
					}
				}

				// ...

				ws
					= new WebSocket(deviceConnectionUrl + '&supports=' + supportsParam);

				// ...

				ws.onopen
					= function()
				{
					// ...
				};

				ws.onmessage
					= function(e)
				{
					var
						message
							= JSON.parse(e.data);

					// ...

					if (messageHandlers[message.type])
					{
						messageHandlers[message.type](message.data);
					}
				};

				ws.onclose
					= function()
				{
					messageHandlers['session.close']();

					ws = null;
				};
			},

			send
				= function(messageObject)
			{
				if (ws)
				{
					ws.send(JSON.stringify(messageObject));
				}
			};

		// ...

		messageHandlers['session.close']
			= function()
		{
			Video.stop();
		};

		messageHandlers['session.load']
			= function(data)
		{
			Video.load(data.mediaRef, data.startPosition);
		};

		messageHandlers['session.pause']
			= function()
		{
			Video.pause();
		};

		messageHandlers['session.resume']
			= function()
		{
			Video.resume();
		};

		messageHandlers['session.seek']
			= function(data)
		{
			Video.seek(data.position);
		};

		messageHandlers['session.stop']
			= function()
		{
			Video.stop();
		};

		// ...

		return {
			open: open,
			send: send
		};

	}()),

	Video
		= (function()
	{
		var
			videoElement,

			loaded,

			duration,

			_relativeStartPosition,

			// ...

			mediaStatus
				= (function()
			{
				var
					CHANGE_DELTA
						= 0.75,

					// ...

					changed
						= function(data)
					{
						var
							args
								= Array.prototype.slice.call(arguments),

							argsObject
								= {};

						for (var i = 0; i < args.length; i += 2)
						{
							argsObject[args[i]] = args[i + 1];
						}

						// ...

						Session.send(
							{
								type: 'session.mediaStatus',
								data: argsObject
							}
						)
					},

					// ...

					state,
					position,

					// ...

					transitionTo
						=
					{
						loading:
							function()
							{
								changed('state', 'loading');
							},

						playing:
							function()
							{
								changed('state', 'playing');
							},

						paused:
							function()
							{
								changed('state', 'paused');
							},

						idle:
							function(reason)
							{
								changed('state', 'idle', 'idleReason', reason);
							}
					};

				// ...

				return {
					state:
						function()
						{
							return state;
						},

					updateState:
						function(newState, data)
						{
							if (state !== newState)
							{
								transitionTo[newState](data);

								state = newState;
							}
						},

					updatePosition:
						function(pos)
						{
							if (pos)
							{
								position = pos;
							}
							else
							{
								(function()
								{
									var
										currentPosition
											= videoElement.currentTime;

									// ...

									if (currentPosition - position > CHANGE_DELTA)
									{
										position = currentPosition;

										changed('position', position);
									}
								}());
							}
						}
				};

			}()),

			// ...

			onloadedmetadata
				= function()
			{
				duration
					= videoElement.duration;
			},

			oncanplay
				= function()
			{
				videoElement.currentTime
					= _relativeStartPosition * duration;

				videoElement.play();
			},

			ontimeupdate
				= function()
			{
				mediaStatus.updatePosition();
			},

			onloadstart
				= function()
			{
				mediaStatus.updateState('loading');
			},

			onstalled
				= function()
			{
				if (mediaStatus.state() !== 'idle')
				{
					mediaStatus.updateState('loading');
				}
			},

			onwaiting
				= function()
			{
				mediaStatus.updateState('loading');
			},

			onplaying
				= function()
			{
				mediaStatus.updateState('playing');
			},

			onpause
				= function()
			{
				mediaStatus.updateState('paused');
			},

			onseeked
				= function()
			{
				mediaStatus.updatePosition(videoElement.currentTime);
			},

			onended
				= function()
			{
				mediaStatus.updateState('idle', 'ended');
			},

			onerror
				= function()
			{
				videoElement.src = '';

				mediaStatus.updateState('idle', 'cancelled');
			},

			// ...

			load
				= function(mediaRef, relativeStartPosition)
			{
				if (!loaded)
				{
					videoElement.addEventListener('loadedmetadata', onloadedmetadata);
					videoElement.addEventListener('canplay', oncanplay);

					// position.

					videoElement.addEventListener('timeupdate', ontimeupdate);
					videoElement.addEventListener('seeked', onseeked);

					// state.

					videoElement.addEventListener('loadstart', onloadstart);
					videoElement.addEventListener('stalled', onstalled);
					videoElement.addEventListener('waiting', onwaiting);
					videoElement.addEventListener('playing', onplaying);
					videoElement.addEventListener('pause', onpause);
					videoElement.addEventListener('ended', onended);

					// ...

					videoElement.addEventListener('error', onerror);

					loaded = true;
				}

				// ...

				_relativeStartPosition
					= relativeStartPosition;

				videoElement.src
					= mediaRef;
			},

			resume
				= function()
			{
				videoElement.play();
			},

			pause
				= function()
			{
				videoElement.pause();
			},

			seek
				= function(position)
			{
				videoElement.currentTime
					= position;
			},

			stop
				= function()
			{
				videoElement.removeEventListener('loadedmetadata', onloadedmetadata);
				videoElement.removeEventListener('canplay', oncanplay);

				// position.

				videoElement.removeEventListener('timeupdate', ontimeupdate);
				videoElement.removeEventListener('seeked', onseeked);

				// state.

				videoElement.removeEventListener('loadstart', onloadstart);
				videoElement.removeEventListener('stalled', onstalled);
				videoElement.removeEventListener('waiting', onwaiting);
				videoElement.removeEventListener('playing', onplaying);
				videoElement.removeEventListener('pause', onpause);
				videoElement.removeEventListener('ended', onended);

				// ...

				videoElement.removeEventListener('error', onerror);

				loaded = false;

				// ...

				videoElement.src = '';

				mediaStatus.updateState('idle', 'stopped');
			};

		// ...

		videoElement
			= $('video').get(0);

		// ...

		return {
			load:
				load,

			resume:
				resume,

			pause:
				pause,

			seek:
				seek,

			stop:
				stop
		};
	}());

// ...

$(
	function()
	{
		var
			argumentString
				= window.location.search.replace('?', ''),

			args,
			tokens,

			result
				= {};

		// ...

		// STV emulator bug: '/' added to end of argument list.
		argumentString
			= argumentString.substr(0, argumentString.length - 1);

		// ...

		args
			= argumentString.split('&');

		for (var arg in args)
		{
			tokens = args[arg].split('=');

			result[tokens[0]] = tokens[1];
		}

		// ...

		Session.open(decodeURIComponent(result['deviceConnectionUrl']), ['video']);
	}
);<commit_msg>Updated parsing of DIAL query parameters<commit_after>var
	Session
		= (function()
	{
		var
			messageHandlers
				= {},

			ws,

			// ...

			open
				= function(deviceConnectionUrl, supports)
			{
				var
					supportsParam
						= '';

				// ...

				for (var i = 0; i < supports.length; i++)
				{
					supportsParam += supports[i];

					if (i !== supports.length - 1)
					{
						supportsParam += ',';
					}
				}

				// ...

				ws
					= new WebSocket(deviceConnectionUrl + '&supports=' + supportsParam);

				// ...

				ws.onopen
					= function()
				{
					// ...
				};

				ws.onmessage
					= function(e)
				{
					var
						message
							= JSON.parse(e.data);

					// ...

					if (messageHandlers[message.type])
					{
						messageHandlers[message.type](message.data);
					}
				};

				ws.onclose
					= function()
				{
					messageHandlers['session.close']();

					ws = null;
				};
			},

			send
				= function(messageObject)
			{
				if (ws)
				{
					ws.send(JSON.stringify(messageObject));
				}
			};

		// ...

		messageHandlers['session.close']
			= function()
		{
			Video.stop();
		};

		messageHandlers['session.load']
			= function(data)
		{
			Video.load(data.mediaRef, data.startPosition);
		};

		messageHandlers['session.pause']
			= function()
		{
			Video.pause();
		};

		messageHandlers['session.resume']
			= function()
		{
			Video.resume();
		};

		messageHandlers['session.seek']
			= function(data)
		{
			Video.seek(data.position);
		};

		messageHandlers['session.stop']
			= function()
		{
			Video.stop();
		};

		// ...

		return {
			open: open,
			send: send
		};

	}()),

	Video
		= (function()
	{
		var
			videoElement,

			loaded,

			duration,

			_relativeStartPosition,

			// ...

			mediaStatus
				= (function()
			{
				var
					CHANGE_DELTA
						= 0.75,

					// ...

					changed
						= function(data)
					{
						var
							args
								= Array.prototype.slice.call(arguments),

							argsObject
								= {};

						for (var i = 0; i < args.length; i += 2)
						{
							argsObject[args[i]] = args[i + 1];
						}

						// ...

						Session.send(
							{
								type: 'session.mediaStatus',
								data: argsObject
							}
						)
					},

					// ...

					state,
					position,

					// ...

					transitionTo
						=
					{
						loading:
							function()
							{
								changed('state', 'loading');
							},

						playing:
							function()
							{
								changed('state', 'playing');
							},

						paused:
							function()
							{
								changed('state', 'paused');
							},

						idle:
							function(reason)
							{
								changed('state', 'idle', 'idleReason', reason);
							}
					};

				// ...

				return {
					state:
						function()
						{
							return state;
						},

					updateState:
						function(newState, data)
						{
							if (state !== newState)
							{
								transitionTo[newState](data);

								state = newState;
							}
						},

					updatePosition:
						function(pos)
						{
							if (pos)
							{
								position = pos;
							}
							else
							{
								(function()
								{
									var
										currentPosition
											= videoElement.currentTime;

									// ...

									if (currentPosition - position > CHANGE_DELTA)
									{
										position = currentPosition;

										changed('position', position);
									}
								}());
							}
						}
				};

			}()),

			// ...

			onloadedmetadata
				= function()
			{
				duration
					= videoElement.duration;
			},

			oncanplay
				= function()
			{
				videoElement.currentTime
					= _relativeStartPosition * duration;

				videoElement.play();
			},

			ontimeupdate
				= function()
			{
				mediaStatus.updatePosition();
			},

			onloadstart
				= function()
			{
				mediaStatus.updateState('loading');
			},

			onstalled
				= function()
			{
				if (mediaStatus.state() !== 'idle')
				{
					mediaStatus.updateState('loading');
				}
			},

			onwaiting
				= function()
			{
				mediaStatus.updateState('loading');
			},

			onplaying
				= function()
			{
				mediaStatus.updateState('playing');
			},

			onpause
				= function()
			{
				mediaStatus.updateState('paused');
			},

			onseeked
				= function()
			{
				mediaStatus.updatePosition(videoElement.currentTime);
			},

			onended
				= function()
			{
				mediaStatus.updateState('idle', 'ended');
			},

			onerror
				= function()
			{
				videoElement.src = '';

				mediaStatus.updateState('idle', 'cancelled');
			},

			// ...

			load
				= function(mediaRef, relativeStartPosition)
			{
				if (!loaded)
				{
					videoElement.addEventListener('loadedmetadata', onloadedmetadata);
					videoElement.addEventListener('canplay', oncanplay);

					// position.

					videoElement.addEventListener('timeupdate', ontimeupdate);
					videoElement.addEventListener('seeked', onseeked);

					// state.

					videoElement.addEventListener('loadstart', onloadstart);
					videoElement.addEventListener('stalled', onstalled);
					videoElement.addEventListener('waiting', onwaiting);
					videoElement.addEventListener('playing', onplaying);
					videoElement.addEventListener('pause', onpause);
					videoElement.addEventListener('ended', onended);

					// ...

					videoElement.addEventListener('error', onerror);

					loaded = true;
				}

				// ...

				_relativeStartPosition
					= relativeStartPosition;

				videoElement.src
					= mediaRef;
			},

			resume
				= function()
			{
				videoElement.play();
			},

			pause
				= function()
			{
				videoElement.pause();
			},

			seek
				= function(position)
			{
				videoElement.currentTime
					= position;
			},

			stop
				= function()
			{
				videoElement.removeEventListener('loadedmetadata', onloadedmetadata);
				videoElement.removeEventListener('canplay', oncanplay);

				// position.

				videoElement.removeEventListener('timeupdate', ontimeupdate);
				videoElement.removeEventListener('seeked', onseeked);

				// state.

				videoElement.removeEventListener('loadstart', onloadstart);
				videoElement.removeEventListener('stalled', onstalled);
				videoElement.removeEventListener('waiting', onwaiting);
				videoElement.removeEventListener('playing', onplaying);
				videoElement.removeEventListener('pause', onpause);
				videoElement.removeEventListener('ended', onended);

				// ...

				videoElement.removeEventListener('error', onerror);

				loaded = false;

				// ...

				videoElement.src = '';

				mediaStatus.updateState('idle', 'stopped');
			};

		// ...

		videoElement
			= $('video').get(0);

		// ...

		return {
			load:
				load,

			resume:
				resume,

			pause:
				pause,

			seek:
				seek,

			stop:
				stop
		};
	}());

// ...

$(
	function()
	{
		var
			argumentString
				= window.location.search.replace('?', ''),

			args,
			tokens,

			result
				= {};

		// ...

		// STV emulator bug: '/' added to end of argument list.
		argumentString
			= argumentString.substr(0, argumentString.length - 1);

		// ...

		args
			= argumentString.split('&');

		for (var arg in args)
		{
			tokens = args[arg].split('=');

			tokens[0] == 'deviceConnectionUrl'
				? result[tokens[0]] = decodeURIComponent(tokens[1])
				: result[tokens[0]] = tokens[1];

		}

		// ...

		Session.open(result['deviceConnectionUrl'], ['video']);
	}
);<|endoftext|>


<commit_before>import { Mongo } from 'meteor/mongo';
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { SimpleSchema } from 'meteor/aldeed:simple-schema';

export const Events = new Mongo.Collection('events');

Events.deny({
  insert() {
    return true;
  },
  update() {
    return true;
  },
  remove() {
    return true;
  }
});

export const createEvent = new ValidatedMethod({
  name: 'events.create',
  validate: new SimpleSchema({
    name: { type: String },
    place: { type: String },
    type: { type: String },
    description: { type: String },
    when: { type: Date },
    howMany: { type: Number }
  }).validator(),
  run({ name, place, type, description, when, howMany }) {
    if (!this.userId) {
      throw new Meteor.Error('not-authorized');
    }
    return Events.insert({
      owner: this.userId,
      name,
      place,
      type,
      description,
      when,
      howMany
    });
  }
});

if (Meteor.isServer) {
  // This code only runs on the server
  Meteor.publish('events', function eventsPublication() {
    return Events.find({});
  });
}
<commit_msg>Method that adds a person to an event<commit_after>import { Mongo } from 'meteor/mongo';
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { SimpleSchema } from 'meteor/aldeed:simple-schema';

export const Events = new Mongo.Collection('events');

Events.deny({
  insert() {
    return true;
  },
  update() {
    return true;
  },
  remove() {
    return true;
  }
});

export const createEvent = new ValidatedMethod({
  name: 'events.create',
  validate: new SimpleSchema({
    name: { type: String },
    place: { type: String },
    type: { type: String },
    description: { type: String },
    when: { type: Date },
    howMany: { type: Number }
  }).validator(),
  run({ name, place, type, description, when, howMany }) {
    if (!this.userId) {
      throw new Meteor.Error('not-authorized');
    }
    return Events.insert({
      owner: this.userId,
      name,
      place,
      type,
      description,
      when,
      howMany,
      people: []
    });
  }
});

export const addPerson = new ValidatedMethod({
  name: 'events.addPerson',
  validate: new SimpleSchema({
    id: { type: Number },
    person: { type: String }
  }).validator(),
  run({ id, person }) {
    if (!this.userId) {
      throw new Meteor.Error('not-authorized');
    }
    let event = Events.findOne({'_id': id});
    if (event.people.length >= event.howMany) {
      throw new Meteor.Error('event full');
    }
    Events.update({ '_id': id }, { $push: { people: person } });
  }
});

if (Meteor.isServer) {
  // This code only runs on the server
  Meteor.publish('events', function eventsPublication() {
    return Events.find({});
  });
}
<|endoftext|>


<commit_before>var data = [
/*  {
        "question_number": " ";
        "question_value": " ";
        "answer_value": " ";
        "story_value": " ";
    }, */
    {
        "question_number": "0",
        "question_value": "PHA+U28gaGVyZSdzIGhvdyB0aGlzIHdvcmtzLjwvcD4NCjxwPlR5cGUgJ2xvdmVsYWNlJyBpbiB0aGUgYm94IGJlbG93LCB3aXRob3V0IHF1b3RhdGlvbiBtYXJrcy48L3A+",
        "answer_value": "bG92ZWxhY2U=",
        "story_value": "PHA+RmlndXJlIG91dCB3aGF0IHlvdSBuZWVkIHRvIGVudGVyIHVwIHRoZXJlIGFuZCB5b3Ugd2lsbCBsZWFybiBzb21ldGhpbmcgZnJvbSBtZSAtIGEgcmVjaXBlLCBhIHJlYWRpbmcsIGEgcmVjb3VudGluZy48L3A+DQo8cD5SZXR1cm4gcmVndWxhcmx5IGFuZCB5b3UgbWF5IGZpbmQgc29tZXRoaW5nIGVsc2UgSSBoYXZlIGNvbWUgdG8gcmVhbGlzZSBhYm91dCB0aGlzIHdvcmxkLCBhYm91dCB0aGUgdW5zZWVuLCBhYm91dCBtZS48L3A+DQo8cD5Ob3cgdHJ5IGFub3RoZXIgcGFnZS48L3A+",
    },
    {
        "question_number": "1",
        "question_value": "PHA+d2UnbGwgdGFrZSBvdXIgaGF0cyBvdXRzaWRlPGJyIC8+DQpsZWF2ZSBvdXIgbGl2ZXMgYmVoaW5kPGJyIC8+DQphbmQgd2F0Y2ggdGhlIDxhIGhyZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9M050NHZmemVveFEiPiYjeDI3Mjg7ICYjeDI3Mjg7ICYjeDI3Mjg7PC9hPiBnbyBvdXQ8L3A+",
        "answer_value": "c3RhcnM=",
        "story_value": "PHA+SSB1bmRlcnN0YW5kIHRoYXQgcGVvcGxlIGhlcmUgbG9vayBhdCBzdGFycyBhcyBhIG1lYW5zIG9mIHdheWZpbmRpbmcuIFNlZWsgdGhlIE5vcnRoIFN0YXIsIEkgYW0gdG9sZCwgYW5kIG9uZSB3aWxsIGFsd2F5cyBrbm93IHdoZXJlIHRoZXkgYXJlLCBob3cgdG8gZ2V0IHRvIHdoZXJlIHRoZXkgd2lzaCB0byBiZS48L3A+DQo8cD5JIGdyZXcgdXAgdW5kZXJzdGFuZGluZyB0aGUgc3RhcnMgYXMgcGF0aHdheXMuIE9uZSBkb2VzIG5vdCBqdXN0IGxvb2sgdXAgYXQgdGhlIHN0YXJzIHRvIGZpZ3VyZSBvdXQgdGhlIG5leHQgc3RlcDogb25lIHVzZXMgdGhlIHN0YXJzIHRvIDxlbT5nZXQ8L2VtPiB0aGVyZS4gVGFrZSBhIGRlZXAgYnJlYXRoLCBjb25uZWN0IHlvdXIgaGVhcnQgdG8gdGhlIGhvdCwgcHVsc2luZyBjb3JlIG9mIHRoZSBzdGFyLCBmZWVsIHlvdXJzZWxmIGRpc3NvbHZlIGFuZCByZXNvbHZlIHRvIHdoZXJlIHlvdSBpbnRlbmQuPC9wPg0KPHA+TW9zdCBwZW9wbGUgaGFkIHZlcnkgY2xlYXIgaW50ZW50aW9ucyBvZiB3aGVyZSB0aGV5IHdhbnRlZCB0byB0cmF2ZWwgdG8sIGNvbnN1bHRpbmcgc3RhciBtYXBzIGFuZCBjaGFydGluZyBjb3Vyc2VzIGFyb3VuZCBwbGFuZXRzLiBMZW9uaXMgc3F1YXJlcyBDeWduaSByaWdodCBieSBTaXJpdXMgLSBJIGhlYXIgdGhlcmUgaXMgYSB3b3JsZCBmdWxsIG9mIGZyaWVuZGx5IGJlaW5ncyBmdWxsIG9mIGZsdWZmIGFuZCBsb3ZlLiBUaGUgcGFzc2FnZSBvZiBBc3Rlcm9pZCAxMTgxIGJyaW5ncyBhbiBpbnRpbWlkYXRpbmcgeWV0IGFsbHVyaW5nIHdvcmxkIHdoZXJlIEZlbW1lIGhvbGRzIHBvd2VyIGFuZCBjYWxscyBvbiB0aG9zZSB2aXNpdGluZyB0byBoYXJuZXNzIHRoZWlyIG93biAtIGJ5IGhvbGRpbmcgb24gdG8gdGhlaXIgZGVtb25zLCBiZWZyaWVuZGluZyB0aGVtLCBmaW5kaW5nIHN0cmVuZ3RoIGFuZCBwb3dlciB3aXRoaW4gdGhlbS4gVGhlIGVmZmVjdCBpcyBldmVuIG1vcmUgcG90ZW50IHdoZW4gdmlzaXRlZCBvbiBibG9vZCBtb29ucy48L3A+DQo8cD5JIHBlcnNvbmFsbHkgZW5qb3kgdHJhdmVsbGluZyBhdCByYW5kb20sIHBpY2tpbmcgdGhlIGZpcnN0IHN0YXIgSSBzZWUgLSBvciByZWFsbHksIHRoZSBmaXJzdCBzdGFyIHdob3NlIGNvcmUgY2FsbGVkIHRvIG15IGhlYXJ0IC0gYW5kIGxldHRpbmcgaXQgdGFrZSBtZSB3aGVyZSBpdCB3YW50cyBtZSB0byBiZS4gSSd2ZSBzZWVuIHBsYW5ldHMgdGhhdCByYWluZWQgZGlhbW9uZHMsIG1ldGVvcnMgaG9sZGluZyBjcnVjaWJsZXMgb2YgaW1wZW5kaW5nIGxpZmUsIGV2ZW4gcm9kZSBhIGNvbWV0IHJvdW5kIGEgZ2FsYXh5LjwvcD4NCjxwPk9uIHRoYXQgdmVyeSBjb21ldCByaWRlLCB0dXJuaW5nIGEgY29ybmVyIHBhc3QgS3VpcGVyLCBJIGZlbHQgYSB2ZXJ5IHN0cm9uZyBwdWxsIHRvd2FyZHMgYSBicmlnaHQsIHdhcm0gc3Rhcjsgbm90IHRoZSBiaWdnZXN0IEkgaGFkIGV2ZXIgc2VlbiwgYnV0IHRoZSBtb3N0IGludHJpZ3VpbmcsIHRoZSBtb3N0IGVsZWN0cmljLCBmdWxsIG9mIHB1bHNhdGluZyBsaWZlIGFuZCBtYWdpYyBhbmQgcG90ZW50aWFsLiBDYWxsaW5nIHRvIG1lIGFuZCBkcmF3aW5nIG1lIGluIHNvIGxvdWRseSBJIGZlbHQgbGlrZSB0aGUgY29tZXQgaXRzZWxmIHdhcyBiZWluZyBwdWxsZWQgb2ZmLWNvdXJzZS48L3A+DQo8cD5JIGRpZCBub3QgcmVjb2duaXNlIHRoaXMgc3RhciwgZGlkIG5vdCBrbm93IHdoZXJlIGl0IHdvdWxkIHRha2UgbWUuIEkgaGFkIG5vIHN0YXIgY2hhcnRzIG9uIG1lLCBubyB3YXkgdG8gY2hlY2sgd2hlcmUgSSB3b3VsZCBnbyBvciBob3cgSSB3b3VsZCBnZXQgaG9tZS4gSWYgSSB3YW50ZWQgdG8gZXZlbiBnZXQgaG9tZS48L3A+DQo8cD5UaGlzIGZlbHQgbW9yZSBsaWtlIGhvbWUsIHNvbWVob3cuPC9wPg0KPHA+TmVydm91cyB3aXRoIGVuZXJneSwgSSBsaW5rZWQgbXkgaGVhcnQgd2l0aCB0aGUgbXlzdGVyeSBzdGFyJ3MgY29yZTsgYSBnaWFudCB3YXZlIG9mIHNvbmljZXNxdWUgZW5lcmd5IG92ZXJ3aGVsbWVkIG1lLiBKdXN0IGFzIG15IGNvbWV0IHJpZGUgd2FzIGFib3V0IHRvIGNyYXNobGFuZCBpbnRvIGEgbGVzc2VyIGFzdGVyb2lkLCBJIGZlbHQgbXlzZWxmIGRpc3NvbHZlIHNvIHJhcGlkbHkgYW5kIHJlc29sdmUgZXZlbiBxdWlja2VyLCBvbiB0aGlzIHN0cmFuZ2Ugd29ybGQgSSBub3cgd3JpdGUgZnJvbS48L3A+DQo8cD5Tb2RkZW4gYW5kIHJvYnVzdCBhbmQgYmFsbXkgYW5kIGJyaXNrIGFuZCBidXp6aW5nIHdpdGggdml0YWxpdHkgYW5kIG11dGVkIHdpdGggc3VidGxldHkuIEEgbWVzcyBvZiBjb250cmFkaWN0aW9ucy4gQW5kIHRoZSBsb2NhbHMgZG9uJ3Qgc2VlbSB0byBwaWNrIHVwIG9uIGhvdyBtdWNoIHRoaXMgcGxhY2UgcmVhbGx5IGhvbGRzLjwvcD4NCjxwPldoZXJlIGFtIEk/IFdoYXQgaXMgdGhpcyBwbGFjZT8gPGVtPldoeTwvZW0+IHRoaXMgcGxhY2U/PC9wPg0KPHA+SSdtIGdvaW5nIHRvIGZpbmQgb3V0LjwvcD4=",
    }
];

var questionIndex = data.length - 1;
var wrongAnswer = "
Not quite there...
";

// this function decides which data item to show
function render(){
       // $('#questionNumber').text("✨" + (data[questionIndex]("question_number"]) + "✨");
        $('#question').html(atob(data[questionIndex]["question_value"]));
}

// this function checks if an answer is correct
function toggleFields(){
    var userAnswer = $('#answer-input').val();
    var comparisonAnswer = atob(data[questionIndex]["answer_value"]);
    if (userAnswer == comparisonAnswer) {
        $('#story').html(atob(data[questionIndex]["story_value"]));
        $('#story').fadeIn(100);
    }
    else {
        $('#story').html(wrongAnswer);
        $('#story').show();
    }

}

// this function sets up things so the page actually does things
$(document).ready(function () {

    render();

    toggleFields(); //call this first so we start out with the correct visibility depending on the selected form values
    //this will call our toggleFields function every time the answer changes
    $('#answer-form').submit(function (e) {
        e.preventDefault();
        toggleFields();
    });

    $('#story').hide();

});
<commit_msg>change fadein speed<commit_after>var data = [
/*  {
        "question_number": " ";
        "question_value": " ";
        "answer_value": " ";
        "story_value": " ";
    }, */
    {
        "question_number": "0",
        "question_value": "PHA+U28gaGVyZSdzIGhvdyB0aGlzIHdvcmtzLjwvcD4NCjxwPlR5cGUgJ2xvdmVsYWNlJyBpbiB0aGUgYm94IGJlbG93LCB3aXRob3V0IHF1b3RhdGlvbiBtYXJrcy48L3A+",
        "answer_value": "bG92ZWxhY2U=",
        "story_value": "PHA+RmlndXJlIG91dCB3aGF0IHlvdSBuZWVkIHRvIGVudGVyIHVwIHRoZXJlIGFuZCB5b3Ugd2lsbCBsZWFybiBzb21ldGhpbmcgZnJvbSBtZSAtIGEgcmVjaXBlLCBhIHJlYWRpbmcsIGEgcmVjb3VudGluZy48L3A+DQo8cD5SZXR1cm4gcmVndWxhcmx5IGFuZCB5b3UgbWF5IGZpbmQgc29tZXRoaW5nIGVsc2UgSSBoYXZlIGNvbWUgdG8gcmVhbGlzZSBhYm91dCB0aGlzIHdvcmxkLCBhYm91dCB0aGUgdW5zZWVuLCBhYm91dCBtZS48L3A+DQo8cD5Ob3cgdHJ5IGFub3RoZXIgcGFnZS48L3A+",
    },
    {
        "question_number": "1",
        "question_value": "PHA+d2UnbGwgdGFrZSBvdXIgaGF0cyBvdXRzaWRlPGJyIC8+DQpsZWF2ZSBvdXIgbGl2ZXMgYmVoaW5kPGJyIC8+DQphbmQgd2F0Y2ggdGhlIDxhIGhyZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9M050NHZmemVveFEiPiYjeDI3Mjg7ICYjeDI3Mjg7ICYjeDI3Mjg7PC9hPiBnbyBvdXQ8L3A+",
        "answer_value": "c3RhcnM=",
        "story_value": "PHA+SSB1bmRlcnN0YW5kIHRoYXQgcGVvcGxlIGhlcmUgbG9vayBhdCBzdGFycyBhcyBhIG1lYW5zIG9mIHdheWZpbmRpbmcuIFNlZWsgdGhlIE5vcnRoIFN0YXIsIEkgYW0gdG9sZCwgYW5kIG9uZSB3aWxsIGFsd2F5cyBrbm93IHdoZXJlIHRoZXkgYXJlLCBob3cgdG8gZ2V0IHRvIHdoZXJlIHRoZXkgd2lzaCB0byBiZS48L3A+DQo8cD5JIGdyZXcgdXAgdW5kZXJzdGFuZGluZyB0aGUgc3RhcnMgYXMgcGF0aHdheXMuIE9uZSBkb2VzIG5vdCBqdXN0IGxvb2sgdXAgYXQgdGhlIHN0YXJzIHRvIGZpZ3VyZSBvdXQgdGhlIG5leHQgc3RlcDogb25lIHVzZXMgdGhlIHN0YXJzIHRvIDxlbT5nZXQ8L2VtPiB0aGVyZS4gVGFrZSBhIGRlZXAgYnJlYXRoLCBjb25uZWN0IHlvdXIgaGVhcnQgdG8gdGhlIGhvdCwgcHVsc2luZyBjb3JlIG9mIHRoZSBzdGFyLCBmZWVsIHlvdXJzZWxmIGRpc3NvbHZlIGFuZCByZXNvbHZlIHRvIHdoZXJlIHlvdSBpbnRlbmQuPC9wPg0KPHA+TW9zdCBwZW9wbGUgaGFkIHZlcnkgY2xlYXIgaW50ZW50aW9ucyBvZiB3aGVyZSB0aGV5IHdhbnRlZCB0byB0cmF2ZWwgdG8sIGNvbnN1bHRpbmcgc3RhciBtYXBzIGFuZCBjaGFydGluZyBjb3Vyc2VzIGFyb3VuZCBwbGFuZXRzLiBMZW9uaXMgc3F1YXJlcyBDeWduaSByaWdodCBieSBTaXJpdXMgLSBJIGhlYXIgdGhlcmUgaXMgYSB3b3JsZCBmdWxsIG9mIGZyaWVuZGx5IGJlaW5ncyBmdWxsIG9mIGZsdWZmIGFuZCBsb3ZlLiBUaGUgcGFzc2FnZSBvZiBBc3Rlcm9pZCAxMTgxIGJyaW5ncyBhbiBpbnRpbWlkYXRpbmcgeWV0IGFsbHVyaW5nIHdvcmxkIHdoZXJlIEZlbW1lIGhvbGRzIHBvd2VyIGFuZCBjYWxscyBvbiB0aG9zZSB2aXNpdGluZyB0byBoYXJuZXNzIHRoZWlyIG93biAtIGJ5IGhvbGRpbmcgb24gdG8gdGhlaXIgZGVtb25zLCBiZWZyaWVuZGluZyB0aGVtLCBmaW5kaW5nIHN0cmVuZ3RoIGFuZCBwb3dlciB3aXRoaW4gdGhlbS4gVGhlIGVmZmVjdCBpcyBldmVuIG1vcmUgcG90ZW50IHdoZW4gdmlzaXRlZCBvbiBibG9vZCBtb29ucy48L3A+DQo8cD5JIHBlcnNvbmFsbHkgZW5qb3kgdHJhdmVsbGluZyBhdCByYW5kb20sIHBpY2tpbmcgdGhlIGZpcnN0IHN0YXIgSSBzZWUgLSBvciByZWFsbHksIHRoZSBmaXJzdCBzdGFyIHdob3NlIGNvcmUgY2FsbGVkIHRvIG15IGhlYXJ0IC0gYW5kIGxldHRpbmcgaXQgdGFrZSBtZSB3aGVyZSBpdCB3YW50cyBtZSB0byBiZS4gSSd2ZSBzZWVuIHBsYW5ldHMgdGhhdCByYWluZWQgZGlhbW9uZHMsIG1ldGVvcnMgaG9sZGluZyBjcnVjaWJsZXMgb2YgaW1wZW5kaW5nIGxpZmUsIGV2ZW4gcm9kZSBhIGNvbWV0IHJvdW5kIGEgZ2FsYXh5LjwvcD4NCjxwPk9uIHRoYXQgdmVyeSBjb21ldCByaWRlLCB0dXJuaW5nIGEgY29ybmVyIHBhc3QgS3VpcGVyLCBJIGZlbHQgYSB2ZXJ5IHN0cm9uZyBwdWxsIHRvd2FyZHMgYSBicmlnaHQsIHdhcm0gc3Rhcjsgbm90IHRoZSBiaWdnZXN0IEkgaGFkIGV2ZXIgc2VlbiwgYnV0IHRoZSBtb3N0IGludHJpZ3VpbmcsIHRoZSBtb3N0IGVsZWN0cmljLCBmdWxsIG9mIHB1bHNhdGluZyBsaWZlIGFuZCBtYWdpYyBhbmQgcG90ZW50aWFsLiBDYWxsaW5nIHRvIG1lIGFuZCBkcmF3aW5nIG1lIGluIHNvIGxvdWRseSBJIGZlbHQgbGlrZSB0aGUgY29tZXQgaXRzZWxmIHdhcyBiZWluZyBwdWxsZWQgb2ZmLWNvdXJzZS48L3A+DQo8cD5JIGRpZCBub3QgcmVjb2duaXNlIHRoaXMgc3RhciwgZGlkIG5vdCBrbm93IHdoZXJlIGl0IHdvdWxkIHRha2UgbWUuIEkgaGFkIG5vIHN0YXIgY2hhcnRzIG9uIG1lLCBubyB3YXkgdG8gY2hlY2sgd2hlcmUgSSB3b3VsZCBnbyBvciBob3cgSSB3b3VsZCBnZXQgaG9tZS4gSWYgSSB3YW50ZWQgdG8gZXZlbiBnZXQgaG9tZS48L3A+DQo8cD5UaGlzIGZlbHQgbW9yZSBsaWtlIGhvbWUsIHNvbWVob3cuPC9wPg0KPHA+TmVydm91cyB3aXRoIGVuZXJneSwgSSBsaW5rZWQgbXkgaGVhcnQgd2l0aCB0aGUgbXlzdGVyeSBzdGFyJ3MgY29yZTsgYSBnaWFudCB3YXZlIG9mIHNvbmljZXNxdWUgZW5lcmd5IG92ZXJ3aGVsbWVkIG1lLiBKdXN0IGFzIG15IGNvbWV0IHJpZGUgd2FzIGFib3V0IHRvIGNyYXNobGFuZCBpbnRvIGEgbGVzc2VyIGFzdGVyb2lkLCBJIGZlbHQgbXlzZWxmIGRpc3NvbHZlIHNvIHJhcGlkbHkgYW5kIHJlc29sdmUgZXZlbiBxdWlja2VyLCBvbiB0aGlzIHN0cmFuZ2Ugd29ybGQgSSBub3cgd3JpdGUgZnJvbS48L3A+DQo8cD5Tb2RkZW4gYW5kIHJvYnVzdCBhbmQgYmFsbXkgYW5kIGJyaXNrIGFuZCBidXp6aW5nIHdpdGggdml0YWxpdHkgYW5kIG11dGVkIHdpdGggc3VidGxldHkuIEEgbWVzcyBvZiBjb250cmFkaWN0aW9ucy4gQW5kIHRoZSBsb2NhbHMgZG9uJ3Qgc2VlbSB0byBwaWNrIHVwIG9uIGhvdyBtdWNoIHRoaXMgcGxhY2UgcmVhbGx5IGhvbGRzLjwvcD4NCjxwPldoZXJlIGFtIEk/IFdoYXQgaXMgdGhpcyBwbGFjZT8gPGVtPldoeTwvZW0+IHRoaXMgcGxhY2U/PC9wPg0KPHA+SSdtIGdvaW5nIHRvIGZpbmQgb3V0LjwvcD4=",
    }
];

var questionIndex = data.length - 1;
var wrongAnswer = "
Not quite there...
";

// this function decides which data item to show
function render(){
       // $('#questionNumber').text("✨" + (data[questionIndex]("question_number"]) + "✨");
        $('#question').html(atob(data[questionIndex]["question_value"]));
}

// this function checks if an answer is correct
function toggleFields(){
    var userAnswer = $('#answer-input').val();
    var comparisonAnswer = atob(data[questionIndex]["answer_value"]);
    if (userAnswer == comparisonAnswer) {
        $('#story').html(atob(data[questionIndex]["story_value"]));
        $('#story').fadeIn(600);
    }
    else {
        $('#story').html(wrongAnswer);
        $('#story').show();
    }

}

// this function sets up things so the page actually does things
$(document).ready(function () {

    render();

    toggleFields(); //call this first so we start out with the correct visibility depending on the selected form values
    //this will call our toggleFields function every time the answer changes
    $('#answer-form').submit(function (e) {
        e.preventDefault();
        toggleFields();
    });

    $('#story').hide();

});
<|endoftext|>


<commit_before>// replace snake case with camel case
// _([a-zA-Z])([a-zA-Z]*)
// \U$1\L$2

$(document).ready(function(){
    setupTests();
    // If we ever host this, we can enable sharing this way,
    // as long as the code is short enough to fit in a url.
    var urlParams = getURLParameters();
    ///////////////////////////////////////////////////
    // Mips Emulator Setup
    ///////////////////////////////////////////////////
    var me = mipsEmulator({
        debug: true,
        /*
         * Changes the registers visual representation when the mips emulator changes its value
         * @param  {String} regName the register name
         * @param  {String/Number} value    The new value of the register
         * @return {null}
         */
        onRegisterChange: function(regName, value){
            var reg = $("#" + regName.replace('$', '') + " .regSpacer");
            $(".lastRegChanged").removeClass('lastRegChanged');
            reg.html(value);
            reg.addClass('lastRegChanged');
            // change to correct tab
            var regLetter = regName.replace('$', '').replace(/\s/, '').charAt(0);
            $('#registers a[href="#'+regLetter+'-registers"]').tab('show')
        },
        /*
         * runs when the emulator has pushed past the last line
         * @return {null}
         */
        onFinish: function(){
            alert("Emulation complete, returning to line 1");
            me.setLine(1);
            setHighlights({lineRan: lastLineNoRun, nextLine: me.getLineNumber()});
            running = false;
        },
        /*
         * This is run when *the users* program encounters a mips error.
         * @param  {String} message     The error message
         * @param  {Number} lineNumber Which line the error occured on
         * @return {null}
         */
        onError: function(message, lineNumber){
            if(!_.isNumber(lineNumber)) return false;
            editor.markText(
                {line: lineNumber-1, ch: 0},
                {line: lineNumber, ch: 0},
                {title: message, className: 'errorLine', clearOnEnter: true}
            );
        },
        onStackChange: addStackAddress,
        // Set the starting code to be the defualt in the editor.
        startingCode: $("#editor").val()
    });
    var running = false;
    // the active line, is the one whose results are being examined.
    var lastLineNoRun;
    var nextLine;

    ///////////////////////////////////////////////////
    // Code Mirror Setup
    ///////////////////////////////////////////////////

    // Code Mirror lines do not match with displayed line number
    // they start at zero and so are off by  -1
    var editor = CodeMirror.fromTextArea(
        document.getElementById("editor"),{
          lineNumbers: true,
          mode: "text/css",
          matchBrackets: true,
    });

    // When the editor changes, we need to mark it as invalid
    // so it will be reanalyzed upon a step or run
    editor.on('change', markEditorAsInvalid);

    // Keeps track of the last line we ran. To start with we want it
    // to be null becuase we have not run anything yet.
    var lastRunMarker;
    // Keeps track of the next line we will run, we want to set it to the
    // first valid line.
    var nextMarker = editor.markText(
        {line: me.getLineNumber()-1, ch: 0},
        {line: me.getLineNumber(), ch: 0},
        {title: "Next line to be run", className: 'nextLine'}
    );

    ///////////////////////////////////////////////////
    // Event Handlers setup
    ///////////////////////////////////////////////////
    $(".registers-container li").each(setupRegisters);
    $('.regSpacer').on('input', manualRegistryValidate);
    $('.regSpacer').on('blur', manualRegistryEditSave);
    $('#codeLoaders button').on('click', loadCustomCode);
    $("#step").click(step);
    $("#goToLineButton").on('click', setLine);
    $("#run").click(run);

    // Functions to respond to events.
    function setLine(){
        var newLine = $("#currentLineInput").val();
        // if(debug) console.log("Setting new line: "+ newLine);
        if(!_.isNumber(me.setLine(Number(newLine)))) console.error("Error setting line: " + newLine);
        // if(debug) console.log("nextLine"+ me.getLineNumber());
        setHighlights({lineRan: null, nextLine: me.getLineNumber()})
        return false;
    };
    function markEditorAsInvalid(){
        me.valid = false;
    };
    function step(){
        // if this code is no longer valid, reanalyze.
        if(!me.valid){
            try{
                mipsAnalyze();
            } catch(e){
                console.error(JSON.stringify(e));
            }
        }
        //try{
            lineResult = me.step();
            if(lineResult){
               setHighlights(lineResult);
            }
        //} catch(e){
            //console.error("Error on line: " + nextLine + " - " + JSON.stringify(e));
        //}

    };
    function loadCustomCode(e){
        if(!confirm("This will erase what is in the code editor, are you sure?")) return;
        var target = $(e.target);
        var loadTarget = target.attr('load');
        var newContent = $(loadTarget).html();
        newContent = newContent.replace(/^\s+|\s+$/g, '');
        //newContent = newContent.replace(/\n\s+/g, '\n');
        editor.setValue(newContent);
        mipsAnalyze();
        me.setLine(1);
        lastLineNoRun = null;
        setHighlights();
    };
    function manualRegistryEditSave(e){
        var newVal = $(e.target).html();
        var target =  $(e.target);
        var regName = target.attr("reg");
        me.setRegisterVal(regName, Number(newVal), false);
    };
    function manualRegistryValidate(e){
        var newVal = $(e.target).html();
        var target =  $(e.target);
        var regName = target.attr("reg");
        if(newVal.search(/[^-\d]/) >= 0){
            target.html(newVal.replace(/[\D\s]/g, ''));
            alert("You cannot enter in characters into registers");
        }
        if(newVal.length > 11){
            if(newVal.length == 12 && newVal.charAt(0) == '-'){
                return true;
            } else {
                target.html(newVal.substring(0, 11));
                alert("The 32 bit integers can only be 11 digits long.");
            }

        }

        return true;
    };
    function setHighlights(lines){
        lines = lines || {};
        lastLineNoRun = lines.lineRan || lastLineNoRun || null;
        nextLine = lines.nextLine || me.getLineNumber();
        // if(debug) console.log("Active line: " + lastLineNoRun);
        // if(debug) console.log("Next line: " + nextLine);
        $("#currentLineInput").val(nextLine);
        if(lastRunMarker) lastRunMarker.clear();
        if(lastLineNoRun)
            lastRunMarker = editor.markText(
                {line: lastLineNoRun-1, ch: 0},
                {line: lastLineNoRun, ch: 0},
                {title: "last line ran", className: 'lastLineNoRun', clearOnEnter: true}
            );
        if(nextMarker) nextMarker.clear();
        nextMarker = editor.markText(
            {line: nextLine-1, ch: 0},
            {line: nextLine, ch: 0},
            {title: "Next line to be run", className: 'nextLine', clearOnEnter: true}
        );

    };
    function setupRegisters(index){
        var reg = $(this);
        var regName = reg.attr('id');
        reg.html(
            ""+regName +": "
            + ""
            + me.getRegisterVal('$' + regName)
            + ""
        );
    }
    function run(){
        // if this code is no longer valid, reanalyze.
        if(!me.valid){
            editor.save();
            me.setCode($("#editor").val());
            me.valid = true;
        }
        running = true;
        while(running) step();

    };
    function mipsAnalyze(){
        editor.save();
        me.setCode($("#editor").val());
        me.setLine(1);
        me.valid = true;
    };
    function getCodeAsString(){
        editor.save();
        return $("#editor").val();
    };
    function unsignInt(num){
        return (num << 31) >>> 0;
    };
    var stackLow = me.stack.pointerToBottomOfStack();
    var stackEnd = me.stack.pointerToBottomOfStack();
    function addStackAddress(address, val){
        $('#registers a[href="#stack-container-div"]').tab('show');
        console.log("address: " + address + "\nStackLow: " + stackLow + "\nVal: " + val );
        while(address <= stackLow){

            $("#stackRep").prepend(
                "
"
                    + ""
                        + stackLow + ": "
                    + ""
                    + ""
                + "
"
            );
            stackLow--;
        }
        console.log("stack Change: " + address + " - " + val);
        $("#stackVal-"+address).html(val);
    };
    function setupTests(){
        //

        // <button type="button" load="#additionDoubler" class="btn btn-default">Addition Doubler</button>
        $.each(examples, function(index, func){
            index = index.replace('Example', '');
            indexNice = index.replace(/([A-Z])/g, " \$1");

            $("#exampleHolder").append(
                "
"
                + func().join('\n')
                + "
"
            );
            $("#codeLoaders").append(
                '<button type="button" load="#' + index + '" class="btn btn-default">' + indexNice + '</button>'
            );
        });
    };

});<commit_msg>Added stack support<commit_after>// replace snake case with camel case
// _([a-zA-Z])([a-zA-Z]*)
// \U$1\L$2

$(document).ready(function(){
    setupTests();
    // If we ever host this, we can enable sharing this way,
    // as long as the code is short enough to fit in a url.
    var urlParams = getURLParameters();
    ///////////////////////////////////////////////////
    // Mips Emulator Setup
    ///////////////////////////////////////////////////
    var me = mipsEmulator({
        debug: true,
        /*
         * Changes the registers visual representation when the mips emulator changes its value
         * @param  {String} regName the register name
         * @param  {String/Number} value    The new value of the register
         * @return {null}
         */
        onRegisterChange: function(regName, value){
            if(regName == "$sp"){
                return setSP(value);
            }
            var reg = $("#" + regName.replace('$', '') + " .regSpacer");
            $(".lastRegChanged").removeClass('lastRegChanged');
            reg.html(value);
            reg.addClass('lastRegChanged');
            // change to correct tab
            var regLetter = regName.replace('$', '').replace(/\s/, '').charAt(0);
            $('#registers a[href="#'+regLetter+'-registers"]').tab('show')
        },
        /*
         * runs when the emulator has pushed past the last line
         * @return {null}
         */
        onFinish: function(){
            alert("Emulation complete, returning to line 1");
            me.setLine(1);
            setHighlights({lineRan: lastLineNoRun, nextLine: me.getLineNumber()});
            running = false;
        },
        /*
         * This is run when *the users* program encounters a mips error.
         * @param  {String} message     The error message
         * @param  {Number} lineNumber Which line the error occured on
         * @return {null}
         */
        onError: function(message, lineNumber){
            if(!_.isNumber(lineNumber)) return false;
            editor.markText(
                {line: lineNumber-1, ch: 0},
                {line: lineNumber, ch: 0},
                {title: message, className: 'errorLine', clearOnEnter: true}
            );
        },
        onStackChange: addStackAddress,
        // Set the starting code to be the defualt in the editor.
        startingCode: $("#editor").val()
    });
    var running = false;
    // the active line, is the one whose results are being examined.
    var lastLineNoRun;
    var nextLine;

    ///////////////////////////////////////////////////
    // Code Mirror Setup
    ///////////////////////////////////////////////////

    // Code Mirror lines do not match with displayed line number
    // they start at zero and so are off by  -1
    var editor = CodeMirror.fromTextArea(
        document.getElementById("editor"),{
          lineNumbers: true,
          mode: "text/css",
          matchBrackets: true,
    });

    // When the editor changes, we need to mark it as invalid
    // so it will be reanalyzed upon a step or run
    editor.on('change', markEditorAsInvalid);

    // Keeps track of the last line we ran. To start with we want it
    // to be null becuase we have not run anything yet.
    var lastRunMarker;
    // Keeps track of the next line we will run, we want to set it to the
    // first valid line.
    var nextMarker = editor.markText(
        {line: me.getLineNumber()-1, ch: 0},
        {line: me.getLineNumber(), ch: 0},
        {title: "Next line to be run", className: 'nextLine'}
    );

    ///////////////////////////////////////////////////
    // Event Handlers setup
    ///////////////////////////////////////////////////
    $(".registers-container li").each(setupRegisters);
    $('.regSpacer').on('input', manualRegistryEdit);
    //$('.regSpacer').on('blur', manualRegistryEditSave);
    $('#codeLoaders button').on('click', loadCustomCode);
    $("#step").click(step);
    $("#goToLineButton").on('click', setLine);
    $("#run").click(run);
    $("#optionShowRelative").change(switchAddressMode);

    // Functions to respond to events.
    function setLine(){
        var newLine = $("#currentLineInput").val();
        // if(debug) console.log("Setting new line: "+ newLine);
        if(!_.isNumber(me.setLine(Number(newLine)))) console.error("Error setting line: " + newLine);
        // if(debug) console.log("nextLine"+ me.getLineNumber());
        setHighlights({lineRan: null, nextLine: me.getLineNumber()})
        return false;
    };
    function markEditorAsInvalid(){
        me.valid = false;
    };
    function step(){
        // if this code is no longer valid, reanalyze.
        if(!me.valid){
            try{
                mipsAnalyze();
            } catch(e){
                console.error(JSON.stringify(e));
            }
        }
        //try{
            lineResult = me.step();
            if(lineResult){
               setHighlights(lineResult);
            }
        //} catch(e){
            //console.error("Error on line: " + nextLine + " - " + JSON.stringify(e));
        //}

    };
    function loadCustomCode(e){
        if(!confirm("This will erase what is in the code editor, are you sure?")) return;
        var target = $(e.target);
        var loadTarget = target.attr('load');
        var newContent = $(loadTarget).html();
        newContent = newContent.replace(/^\s+|\s+$/g, '');
        //newContent = newContent.replace(/\n\s+/g, '\n');
        editor.setValue(newContent);
        mipsAnalyze();
        me.setLine(1);
        lastLineNoRun = null;
        setHighlights();
    };
    function manualRegistryEditSave(e){
        var newVal = $(e.target).html();
        var target =  $(e.target);
        var regName = target.attr("reg");
        me.setRegisterVal(regName, Number(newVal), false);
    };
    function manualRegistryEdit(e){
        var newVal = $(e.target).html();
        var target =  $(e.target);
        var regName = target.attr("reg");
        newVal = parseInt(newVal);
        me.setRegisterVal(regName, newVal, false);
        target.html(me.getRegisterVal(regName));
    };
    function manualRegistryValidate(e){
        var newVal = $(e.target).html();
        var target =  $(e.target);
        var regName = target.attr("reg");
        if(newVal.search(/[^-\d]/) >= 0){
            target.html(newVal.replace(/[\D\s]/g, ''));
            alert("You cannot enter in characters into registers");
        }
        if(newVal.length > 11){
            if(newVal.length == 12 && newVal.charAt(0) == '-'){
                return true;
            } else {
                target.html(newVal.substring(0, 11));
                alert("The 32 bit integers can only be 11 digits long.");
            }

        }

        return true;
    };
    function setHighlights(lines){
        lines = lines || {};
        lastLineNoRun = lines.lineRan || lastLineNoRun || null;
        nextLine = lines.nextLine || me.getLineNumber();
        // if(debug) console.log("Active line: " + lastLineNoRun);
        // if(debug) console.log("Next line: " + nextLine);
        $("#currentLineInput").val(nextLine);
        if(lastRunMarker) lastRunMarker.clear();
        if(lastLineNoRun)
            lastRunMarker = editor.markText(
                {line: lastLineNoRun-1, ch: 0},
                {line: lastLineNoRun, ch: 0},
                {title: "last line ran", className: 'lastLineNoRun', clearOnEnter: true}
            );
        if(nextMarker) nextMarker.clear();
        nextMarker = editor.markText(
            {line: nextLine-1, ch: 0},
            {line: nextLine, ch: 0},
            {title: "Next line to be run", className: 'nextLine', clearOnEnter: true}
        );

    };
    function setupRegisters(index){
        var reg = $(this);
        var regName = reg.attr('id');
        reg.html(
            ""+regName +": "
            + ""
            + me.getRegisterVal('$' + regName)
            + ""
        );
    }
    function run(){
        // if this code is no longer valid, reanalyze.
        if(!me.valid){
            editor.save();
            me.setCode($("#editor").val());
            me.valid = true;
        }
        running = true;
        while(running) step();

    };
    function mipsAnalyze(){
        editor.save();
        me.setCode($("#editor").val());
        me.setLine(1);
        me.valid = true;
    };
    function getCodeAsString(){
        editor.save();
        return $("#editor").val();
    };
    function unsignInt(num){
        return (num << 31) >>> 0;
    };
    function setSP(address){
        addStackAddress(address, '', false);
        $(".glyphicon-arrow-right").removeClass("glyphicon-arrow-right");
        $("#stackEntry-" + address + " .glyphicon").addClass("glyphicon-arrow-right lastRegChanged");
        $('#registers a[href="#stack-container-div"]').tab('show');
            };
    var colorizeAddrBG = false;
    function addStackAddress(address, val, visualize){
        if(!val || val == '') val = me.stack.getByte(address);
        if(typeof visualize == 'undefined')
            visualize = true;
        console.log("address: " + address + "\nStackLow: " + stackLow + "\nVal: " + val );
        showAddReal = '';
            showAddRelative = 'style="display: none"';
        if(showRelative){
            showAddReal = 'style="display: none"';
            showAddRelative = '';
        }
        while(address <= stackLow){
            var bgColorClass = '';
            if(colorizeAddrBG) bgColorClass = 'lightGreyBG';
            colorizeAddrBG = !colorizeAddrBG;
            $("#stackRep").prepend(
                "
"
                + "&nbsp"
                    + ""
                        + ""
                            + stackLow + ": "
                        + ""
                        + ""
                            + (stackLow - stackEnd) + ": "
                        + ""
                        + ""+
                            + me.stack.getByte(stackLow)
                        +""
                    + ""
                + "
"
            );
            stackLow--;
        }
        console.log("stack Change: " + address + " - " + val);

        $("#stackVal-"+address).html(val);
        if(visualize){
            $('#registers a[href="#stack-container-div"]').tab('show');
            $(".lastRegChanged").removeClass('lastRegChanged');
            $("#stackVal-"+address).addClass('lastRegChanged');
        }
    };
    var stackLow = me.stack.pointerToBottomOfStack()-1;
    var stackEnd = me.stack.pointerToBottomOfStack();
    addStackAddress(stackLow, me.stack.getByte(stackLow), false);
    //setSP(stackEnd);
    function setupTests(){
        //

        // <button type="button" load="#additionDoubler" class="btn btn-default">Addition Doubler</button>
        $.each(examples, function(index, func){
            index = index.replace('Example', '');
            indexNice = index.replace(/([A-Z])/g, " \$1");
            indexNice = indexNice.charAt(0).toUpperCase() + indexNice.slice(1);;

            $("#exampleHolder").append(
                "
"
                + func().join('\n')
                + "
"
            );
            $("#codeLoaders").append(
                '<button type="button" load="#'
                + index + '" class="btn btn-default">'
                + indexNice + '</button>'
            );
        });
    };
    var showRelative;
    function switchAddressMode(e){
        showRelative = $(e.target).is(':checked');
        if(showRelative){
            $('.stackAddrRelative').show();
            $('.stackAddrReal').hide();
        } else {
            $('.stackAddrRelative').hide();
            $('.stackAddrReal').show();
        }
    }

});<|endoftext|>


<commit_before>$(w).resize(function(){ //Update dimensions on resize
  sw = document.documentElement.clientWidth;
  sh = document.documentElement.clientHeight;
  checkMobile();
});

//Check if Mobile
function checkMobile() {
  mobile = (sw > breakpoint) ? false : true;

  if (!mobile) { //If Not Mobile
    $('[role="tabpanel"],#nav,#search').show(); //Show full
	        navigation and search
	          } else { //Hide
	              if(!$('#nav-anchors a').hasClass('active')) {
	                    $('#nav,#search').hide(); //Hide full navigation
	                    and search
			}
		}
	}
<commit_msg>Added auxiliary content loader<commit_after>$(w).resize(function(){ //Update dimensions on resize
  sw = document.documentElement.clientWidth;
  sh = document.documentElement.clientHeight;
  checkMobile();
});

//Check if Mobile
function checkMobile() {
  mobile = (sw > breakpoint) ? false : true;

  if (!mobile) { //If Not Mobile
    $('[role="tabpanel"],#nav,#search').show(); //Show full navigation and search
    loadAux(); //Load auxiliary content
		 } else { //Hide
	              if(!$('#nav-anchors a').hasClass('active')) {
	                    $('#nav,#search').hide(); //Hide full navigation and search
			}
		}
	}

function buildGallery() {
  container.html('

');
    imgList = $('#img-list');
      nav.find('a:first').addClass('active');

	  //For Each Navigation Link
	    nav.find('a').each(function() {
	        var $this = $(this);
	            var href = $this.attr('href');

	                      //Prepare list item with image source in data
	                      attribute
	                          arr += '

';
	                            });

	                                //Append to #img-list
	                                  imgList.find('ul').append(arr);

	                                          //Nav Thumbnail Click
	                                            nav.on('click', 'a',
	                                            function(e) {
	                                                var pos =
	                                                $(this).parent().index();
	                                                   e.preventDefault();
	                                                        loadImg(pos);
	                                                            if(swipeEnabled)
	                                                            {
	                                                                  mySwipe.slide(index,
	                                                                  300);
	                                                                      }
	                                                                          updateNav(pos);
	                                                                            });

}

//Set up Auxiliary content
function loadAux() {
  var $aux = $('.aux');
    $aux.each(function(index) {
        var $this = $(this);
            var auxLink = $this.find('a');
                var auxFragment = auxLink.attr('href');
                    var auxContent = $this.find('[role=tabpanel]');
                        if (auxContent.size()===0 &&
                        $this.hasClass('loaded')===false) {
                              loadContent(auxFragment,$this);
                                  }
                                    });
                                    }

                                    function loadContent(src,container) { //
                                    Load Tab Content
                                      container.addClass('loaded');
                                        $('
').load(src
                                        +' #content > div',function() {
                                            $(this).appendTo(container);
                                              });
                                              }
<|endoftext|>


<commit_before>$(function () {

	const formsEnum = {
		LEFT: 0,
		RIGHT: 1,
		TOP: 2,
		BOTTOM: 3,
		FULLSCREEN: 4
	};

	var currentForm = formsEnum.FULLSCREEN;

	var calcMarkPosition = function (rectSize, rectOffset, posInsideRect) {
		rectSize = $.extend(true, {}, rectSize);
		rectOffset = $.extend(true, {}, rectOffset);
		posInsideRect = $.extend(true, {}, posInsideRect);

		const xThreshold = rectSize.width * 0.3;
		const yThreshold = rectSize.height * 0.4;

		if (posInsideRect.x < xThreshold) {
			currentForm = formsEnum.LEFT;
			rectSize.width /= 2;

		} else if (posInsideRect.y < yThreshold) {
			currentForm = formsEnum.TOP;
			rectSize.height /= 2;

		} else if (posInsideRect.x > rectSize.width - xThreshold) {
			currentForm = formsEnum.RIGHT;
			rectSize.width /= 2;
			rectOffset.left += rectSize.width;

		} else if (posInsideRect.y > rectSize.height - yThreshold) {
			currentForm = formsEnum.BOTTOM;
			rectSize.height /= 2;
			rectOffset.top += rectSize.height;

		} else {
			currentForm = formsEnum.FULLSCREEN;
		}

		return {
			top: rectOffset.top,
			left: rectOffset.left,
			width: rectSize.width,
			height: rectSize.height
		};
	}

	var setMarkPosition = (function () {
		var $mark = $('.mark');
		var positionCache = { top: 0, left: 0, width: 0, height: 0 };

		return function (position) {
			if (positionCache.top === position.top &&
				positionCache.left === position.left &&
				positionCache.width === position.width &&
				positionCache.height === position.height) {
				return;
			}
			positionCache = position;
			$mark.css(positionCache);
		}
	}());

	var onClickHandler = function (e) {
		var html = "";
		switch (currentForm) {

		case formsEnum.LEFT:
		case formsEnum.RIGHT:
			html = '

';
			break;

		case formsEnum.TOP:
		case formsEnum.BOTTOM:
			html = '

';
			break;

		case formsEnum.FULLSCREEN:
			html = "";
			break;
		}

		$(e.target).html(html);
	};

	var onMouseMoveHandler = (function () {
		var $rect = [];
		var rectOffset = { top: 0, left: 0 };
		var rectSize = { width: 0, height: 0 };

		var updateTargetRect = function (rect) {
			$rect = $(rect);
			rectOffset = $rect.offset();
			rectSize = {
				width: $rect.width(),
				height: $rect.height()
			}

			$('.rect').removeClass('painted');
			$rect.addClass('painted');
		}

		return function (e) {
			if ($rect[0] !== e.target) {
				updateTargetRect(e.target);
			}

			var posInsideRect = {
				x: e.pageX - rectOffset.left,
				y: e.pageY - rectOffset.top
			};

			if (posInsideRect.x < 0 || posInsideRect.y < 0) {
				return;
			}

			setMarkPosition(calcMarkPosition(
				rectSize,
				rectOffset,
				posInsideRect
			));
		}
	}());

	var onContextMenuHandler = function (e) {
		var $parentRect = $(e.target).parent();

		if (!$parentRect.hasClass('rect')) {
			$parentRect = $(e.target);
		}

		var $childrenClone = $parentRect.find('>').children().clone();
		$parentRect.empty().append($childrenClone);

		e.preventDefault();
	};

	$(document)
		.on('contextmenu', '.rect', onContextMenuHandler)
		.on('mousemove', '.rect', onMouseMoveHandler)
		.on('click', '.rect', onClickHandler);
});
<commit_msg>余分なcache機構削除<commit_after>$(function () {

	const formsEnum = {
		LEFT: 0,
		RIGHT: 1,
		TOP: 2,
		BOTTOM: 3,
		FULLSCREEN: 4
	};

	var currentForm = formsEnum.FULLSCREEN;

	var calcMarkPosition = function (rectSize, rectOffset, posInsideRect) {
		rectSize = $.extend(true, {}, rectSize);
		rectOffset = $.extend(true, {}, rectOffset);
		posInsideRect = $.extend(true, {}, posInsideRect);

		const xThreshold = rectSize.width * 0.3;
		const yThreshold = rectSize.height * 0.4;

		if (posInsideRect.x < xThreshold) {
			currentForm = formsEnum.LEFT;
			rectSize.width /= 2;

		} else if (posInsideRect.y < yThreshold) {
			currentForm = formsEnum.TOP;
			rectSize.height /= 2;

		} else if (posInsideRect.x > rectSize.width - xThreshold) {
			currentForm = formsEnum.RIGHT;
			rectSize.width /= 2;
			rectOffset.left += rectSize.width;

		} else if (posInsideRect.y > rectSize.height - yThreshold) {
			currentForm = formsEnum.BOTTOM;
			rectSize.height /= 2;
			rectOffset.top += rectSize.height;

		} else {
			currentForm = formsEnum.FULLSCREEN;
		}

		return {
			top: rectOffset.top,
			left: rectOffset.left,
			width: rectSize.width,
			height: rectSize.height
		};
	}

	var setMarkPosition = (function () {
		var $mark = $('.mark');
		var positionCache = { top: 0, left: 0, width: 0, height: 0 };

		return function (position) {
			if (positionCache.top === position.top &&
				positionCache.left === position.left &&
				positionCache.width === position.width &&
				positionCache.height === position.height) {
				return;
			}
			positionCache = position;
			$mark.css(positionCache);
		}
	}());

	var onClickHandler = function (e) {
		var html = "";
		switch (currentForm) {

		case formsEnum.LEFT:
		case formsEnum.RIGHT:
			html = '

';
			break;

		case formsEnum.TOP:
		case formsEnum.BOTTOM:
			html = '

';
			break;

		case formsEnum.FULLSCREEN:
			html = "";
			break;
		}

		$(e.target).html(html);
	};

	var onMouseMoveHandler = (function () {
		var $rect = [];

		return function (e) {
			if ($rect[0] !== e.target) {
				$rect = $(e.target);

				$('.rect').removeClass('painted');
				$rect.addClass('painted');
			}

			var rectOffset = $rect.offset();
			var posInsideRect = {
				x: e.pageX - rectOffset.left,
				y: e.pageY - rectOffset.top
			};
			var rectSize = {
				width: $rect.width(),
				height: $rect.height()
			};

			setMarkPosition(calcMarkPosition(
				rectSize,
				rectOffset,
				posInsideRect
			));
		}
	}());

	var onContextMenuHandler = function (e) {
		var $parentRect = $(e.target).parent();

		if (!$parentRect.hasClass('rect')) {
			$parentRect = $(e.target);
		}

		var $childrenClone = $parentRect.find('>').children().clone();
		$parentRect.empty().append($childrenClone);

		e.preventDefault();
	};

	$(document)
		.on('contextmenu', '.rect', onContextMenuHandler)
		.on('mousemove', '.rect', onMouseMoveHandler)
		.on('click', '.rect', onClickHandler);
});
<|endoftext|>


<commit_before>/*-----------------------------------------------------------------------------------
/*
/* Main JS
/*
-----------------------------------------------------------------------------------*/

(function($) {

   /*---------------------------------------------------- */
	/* Final Countdown Settings
	------------------------------------------------------ */

  var template = '%D days' +
                 '%H hours' +
                 '%M minutes';

  $('.counter.group').each(function(i, el) {
    var startDate = $(el).find('[property=startDate]').attr('content');
    $(el)
      .countdown(startDate)
      .on('update.countdown', function(event) {
        $(this).html(event.strftime(template));
      });
  });

   /*----------------------------------------------------*/
	/*  Placeholder Plugin Settings
	------------------------------------------------------ */
	$('input').placeholder()

   /*----------------------------------------------------- */
   /* Modals
   ------------------------------------------------------- */
   $('.modal-toggles ul').on('click', 'a', function(e) {

   	var html = $('html'),
   		 main = $('main, footer'),
   		 footer = $('footer'),
          curMod = $(this).attr('href'),
          modal = $(curMod),
          modClose = modal.find('#modal-close');

		main.fadeOut(500, function(){
			$('html,body').scrollTop(0);
        	modal.addClass('is-visible');
      });

      e.preventDefault();

      // for old ie
      if (html.hasClass('oldie')) {

      	$(document).on('click', "#modal-close", function(evt) {
	      	$('html,body').scrollTop(0);
	      	modal.removeClass('is-visible');
	      	setTimeout(function() {
	        		main.fadeIn(500);
	        	}, 500);

	        	evt.preventDefault();
      	});

      }
      // other browsers
      else {

      	modClose.on('click', function(evt) {
	      	$('html,body').scrollTop(0);
	      	modal.removeClass('is-visible');
	      	setTimeout(function() {
	        		main.fadeIn(500);
	        	}, 500);

	        	evt.preventDefault();
	      });

      }

   });

   /*---------------------------------------------------- */
	/* Owl Carousel
	------------------------------------------------------ */
	$("#owl-slider").owlCarousel({
        navigation: false,
        pagination: true,
        items: 4,
        navigationText: false
    });

   /*----------------------------------------------------*/
  	/* FitText Settings
  	------------------------------------------------------ */
  	setTimeout(function() {

   	  $('main h1, #mod-about h1').fitText(1.1, { minFontSize: '28px', maxFontSize: '38px' });

  	}, 100);

   /*---------------------------------------------------- */
   /* ajaxchimp
	------------------------------------------------------ */

	// Example MailChimp url: http://xxx.xxx.list-manage.com/subscribe/post?u=xxx&id=xxx
	$('#mc-form').ajaxChimp({
	   url: 'http://restfest.us7.list-manage1.com/subscribe/post?u=dc5d847a1bf683803f067bcc4&id=e8112b5bc0'
	});

	/*---------------------------------------------------- */
	/* Map
	------------------------------------------------------ */
	var latitude = 14.549072,
		 longitude = 121.046958,
		 map_zoom = 15,
		 main_color = '#d8ac00',
		 saturation_value= -30,
		 brightness_value= 5,
		 winWidth = $(window).width();

   // marker url
	if ( winWidth > 480 ) {
		marker_url = 'images/icon-location-b.png';
   } else {
      marker_url = 'images/icon-location.png';
   }

	// map style
	var style = [
		{
			// set saturation for the labels on the map
			elementType: "labels",
			stylers: [
				{ saturation: saturation_value }
			]
		},
	   {	// poi stands for point of interest - don't show these lables on the map
			featureType: "poi",
			elementType: "labels",
			stylers: [
				{visibility: "off"}
			]
		},
		{
			// don't show highways lables on the map
	      featureType: 'road.highway',
	      elementType: 'labels',
	      stylers: [
	         { visibility: "off" }
	      ]
	   },
		{
			// don't show local road lables on the map
			featureType: "road.local",
			elementType: "labels.icon",
			stylers: [
				{ visibility: "off" }
			]
		},
		{
			// don't show arterial road lables on the map
			featureType: "road.arterial",
			elementType: "labels.icon",
			stylers: [
				{ visibility: "off" }
			]
		},
		{
			// don't show road lables on the map
			featureType: "road",
			elementType: "geometry.stroke",
			stylers: [
				{ visibility: "off" }
			]
		},
		// style different elements on the map
		{
			featureType: "transit",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "poi",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "poi.government",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "poi.sport_complex",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "poi.attraction",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "poi.business",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "transit",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "transit.station",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "landscape",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]

		},
		{
			featureType: "road",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "road.highway",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "water",
			elementType: "geometry",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		}
	];

	// map options
	var map_options = {

      	center: new google.maps.LatLng(latitude, longitude),
      	zoom: 15,
      	panControl: false,
      	zoomControl: false,
        	mapTypeControl: false,
      	streetViewControl: false,
      	mapTypeId: google.maps.MapTypeId.ROADMAP,
      	scrollwheel: false,
      	styles: style

    	};

   // inizialize the map
	var map = new google.maps.Map(document.getElementById('map-container'), map_options);

	// add a custom marker to the map
	var marker = new google.maps.Marker({

		 	position: new google.maps.LatLng(latitude, longitude),
		 	map: map,
		 	visible: true,
		 	icon: marker_url

		});

	// add custom buttons for the zoom-in/zoom-out on the map
	function CustomZoomControl(controlDiv, map) {

		// grap the zoom elements from the DOM and insert them in the map
	 	var controlUIzoomIn= document.getElementById('map-zoom-in'),
		  	 controlUIzoomOut= document.getElementById('map-zoom-out');

		controlDiv.appendChild(controlUIzoomIn);
		controlDiv.appendChild(controlUIzoomOut);

		// Setup the click event listeners and zoom-in or out according to the clicked element
		google.maps.event.addDomListener(controlUIzoomIn, 'click', function() {
			map.setZoom(map.getZoom()+1)
		});
		google.maps.event.addDomListener(controlUIzoomOut, 'click', function() {
			map.setZoom(map.getZoom()-1)
		});

	}

	var zoomControlDiv = document.createElement('div');
	var zoomControl = new CustomZoomControl(zoomControlDiv, map);

	// insert the zoom div on the top right of the map
	map.controls[google.maps.ControlPosition.TOP_RIGHT].push(zoomControlDiv);

})(jQuery);
<commit_msg>Fix mailchimp form URL<commit_after>/*-----------------------------------------------------------------------------------
/*
/* Main JS
/*
-----------------------------------------------------------------------------------*/

(function($) {

   /*---------------------------------------------------- */
	/* Final Countdown Settings
	------------------------------------------------------ */

  var template = '%D days' +
                 '%H hours' +
                 '%M minutes';

  $('.counter.group').each(function(i, el) {
    var startDate = $(el).find('[property=startDate]').attr('content');
    $(el)
      .countdown(startDate)
      .on('update.countdown', function(event) {
        $(this).html(event.strftime(template));
      });
  });

   /*----------------------------------------------------*/
	/*  Placeholder Plugin Settings
	------------------------------------------------------ */
	$('input').placeholder()

   /*----------------------------------------------------- */
   /* Modals
   ------------------------------------------------------- */
   $('.modal-toggles ul').on('click', 'a', function(e) {

   	var html = $('html'),
   		 main = $('main, footer'),
   		 footer = $('footer'),
          curMod = $(this).attr('href'),
          modal = $(curMod),
          modClose = modal.find('#modal-close');

		main.fadeOut(500, function(){
			$('html,body').scrollTop(0);
        	modal.addClass('is-visible');
      });

      e.preventDefault();

      // for old ie
      if (html.hasClass('oldie')) {

      	$(document).on('click', "#modal-close", function(evt) {
	      	$('html,body').scrollTop(0);
	      	modal.removeClass('is-visible');
	      	setTimeout(function() {
	        		main.fadeIn(500);
	        	}, 500);

	        	evt.preventDefault();
      	});

      }
      // other browsers
      else {

      	modClose.on('click', function(evt) {
	      	$('html,body').scrollTop(0);
	      	modal.removeClass('is-visible');
	      	setTimeout(function() {
	        		main.fadeIn(500);
	        	}, 500);

	        	evt.preventDefault();
	      });

      }

   });

   /*---------------------------------------------------- */
	/* Owl Carousel
	------------------------------------------------------ */
	$("#owl-slider").owlCarousel({
        navigation: false,
        pagination: true,
        items: 4,
        navigationText: false
    });

   /*----------------------------------------------------*/
  	/* FitText Settings
  	------------------------------------------------------ */
  	setTimeout(function() {

   	  $('main h1, #mod-about h1').fitText(1.1, { minFontSize: '28px', maxFontSize: '38px' });

  	}, 100);

   /*---------------------------------------------------- */
   /* ajaxchimp
	------------------------------------------------------ */

	// Example MailChimp url: http://xxx.xxx.list-manage.com/subscribe/post?u=xxx&id=xxx
	$('#mc-form').ajaxChimp({
	   url: 'https://restfest.us7.list-manage1.com/subscribe/post?u=dc5d847a1bf683803f067bcc4&id=e8112b5bc0'
	});

	/*---------------------------------------------------- */
	/* Map
	------------------------------------------------------ */
	var latitude = 14.549072,
		 longitude = 121.046958,
		 map_zoom = 15,
		 main_color = '#d8ac00',
		 saturation_value= -30,
		 brightness_value= 5,
		 winWidth = $(window).width();

   // marker url
	if ( winWidth > 480 ) {
		marker_url = 'images/icon-location-b.png';
   } else {
      marker_url = 'images/icon-location.png';
   }

	// map style
	var style = [
		{
			// set saturation for the labels on the map
			elementType: "labels",
			stylers: [
				{ saturation: saturation_value }
			]
		},
	   {	// poi stands for point of interest - don't show these lables on the map
			featureType: "poi",
			elementType: "labels",
			stylers: [
				{visibility: "off"}
			]
		},
		{
			// don't show highways lables on the map
	      featureType: 'road.highway',
	      elementType: 'labels',
	      stylers: [
	         { visibility: "off" }
	      ]
	   },
		{
			// don't show local road lables on the map
			featureType: "road.local",
			elementType: "labels.icon",
			stylers: [
				{ visibility: "off" }
			]
		},
		{
			// don't show arterial road lables on the map
			featureType: "road.arterial",
			elementType: "labels.icon",
			stylers: [
				{ visibility: "off" }
			]
		},
		{
			// don't show road lables on the map
			featureType: "road",
			elementType: "geometry.stroke",
			stylers: [
				{ visibility: "off" }
			]
		},
		// style different elements on the map
		{
			featureType: "transit",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "poi",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "poi.government",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "poi.sport_complex",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "poi.attraction",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "poi.business",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "transit",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "transit.station",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "landscape",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]

		},
		{
			featureType: "road",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "road.highway",
			elementType: "geometry.fill",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		},
		{
			featureType: "water",
			elementType: "geometry",
			stylers: [
				{ hue: main_color },
				{ visibility: "on" },
				{ lightness: brightness_value },
				{ saturation: saturation_value }
			]
		}
	];

	// map options
	var map_options = {

      	center: new google.maps.LatLng(latitude, longitude),
      	zoom: 15,
      	panControl: false,
      	zoomControl: false,
        	mapTypeControl: false,
      	streetViewControl: false,
      	mapTypeId: google.maps.MapTypeId.ROADMAP,
      	scrollwheel: false,
      	styles: style

    	};

   // inizialize the map
	var map = new google.maps.Map(document.getElementById('map-container'), map_options);

	// add a custom marker to the map
	var marker = new google.maps.Marker({

		 	position: new google.maps.LatLng(latitude, longitude),
		 	map: map,
		 	visible: true,
		 	icon: marker_url

		});

	// add custom buttons for the zoom-in/zoom-out on the map
	function CustomZoomControl(controlDiv, map) {

		// grap the zoom elements from the DOM and insert them in the map
	 	var controlUIzoomIn= document.getElementById('map-zoom-in'),
		  	 controlUIzoomOut= document.getElementById('map-zoom-out');

		controlDiv.appendChild(controlUIzoomIn);
		controlDiv.appendChild(controlUIzoomOut);

		// Setup the click event listeners and zoom-in or out according to the clicked element
		google.maps.event.addDomListener(controlUIzoomIn, 'click', function() {
			map.setZoom(map.getZoom()+1)
		});
		google.maps.event.addDomListener(controlUIzoomOut, 'click', function() {
			map.setZoom(map.getZoom()-1)
		});

	}

	var zoomControlDiv = document.createElement('div');
	var zoomControl = new CustomZoomControl(zoomControlDiv, map);

	// insert the zoom div on the top right of the map
	map.controls[google.maps.ControlPosition.TOP_RIGHT].push(zoomControlDiv);

})(jQuery);
<|endoftext|>