<commit_before>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

const ipcRenderer = require('electron').ipcRenderer;

var initData = {};

function styleBody(body) {
	if (!body) {
		return
	}
	body.classList.remove('vscode-light', 'vscode-dark', 'vscode-high-contrast');
	body.classList.add(initData.activeTheme);
}

function getTarget() {
	return document.getElementById('_target');
}

function handleInnerClick(event) {
	if (!event || !event.view || !event.view.document) {
		return;
	}
	var node = event.target;
	while (node) {
		if (node.tagName === "A" && node.href) {
			var baseElement = event.view.document.getElementsByTagName("base")[0];
			if (node.getAttribute("href") === "#") {
				event.view.scrollTo(0, 0);
			} else if (node.hash && (node.getAttribute("href") === node.hash || (baseElement && node.href.indexOf(baseElement.href) >= 0))) {
				var scrollTarget = event.view.document.getElementById(node.hash.substr(1, node.hash.length - 1));
				if (scrollTarget) {
					scrollTarget.scrollIntoView();
				}
			} else {
				ipcRenderer.sendToHost("did-click-link", node.href);
			}
			event.preventDefault();
			break;
		}
		node = node.parentNode;
	}
}

document.addEventListener("DOMContentLoaded", function (event) {
	ipcRenderer.on('baseUrl', function (event, value) {
		initData.baseUrl = value;
	});

	ipcRenderer.on('styles', function (event, value, activeTheme) {
		initData.styles = value;
		initData.activeTheme = activeTheme;

		// webview
		var target = getTarget()
		if (!target) {
			return;
		}
		var body = target.contentDocument.getElementsByTagName('body');
		styleBody(body[0]);

		// iframe
		defaultStyles = target.contentDocument.getElementById('_defaultStyles');
		if (defaultStyles) {
			defaultStyles.innerHTML = initData.styles;
		}
	});

	// propagate focus
	ipcRenderer.on('focus', function () {
		const target = getTarget();
		if (target) {
			target.contentWindow.focus();
		}
	});

	// update iframe-contents
	ipcRenderer.on('content', function(_event, value) {
		const text = value.join('\n');
		const newDocument = new DOMParser().parseFromString(text, 'text/html');

		// know what happens here
		const stats = {
			scriptTags: newDocument.documentElement.querySelectorAll('script').length,
			inputTags: newDocument.documentElement.querySelectorAll('input').length,
			styleTags: newDocument.documentElement.querySelectorAll('style').length,
			linkStyleSheetTags: newDocument.documentElement.querySelectorAll('link[rel=stylesheet]').length,
			stringLen: text.length
		};

		// set base-url if applicable
		if (initData.baseUrl && newDocument.head.getElementsByTagName('base').length === 0) {
			const baseElement = newDocument.createElement('base');
			baseElement.href = initData.baseUrl;
			newDocument.head.appendChild(baseElement);
		}

		// apply default styles
		const defaultStyles = newDocument.createElement('style');
		defaultStyles.id = '_defaultStyles';
		defaultStyles.innerHTML = initData.styles;
		if (newDocument.head.hasChildNodes()) {
			newDocument.head.insertBefore(defaultStyles, newDocument.head.firstChild);
		} else {
			newDocument.head.appendChild(defaultStyles);
		}

		styleBody(newDocument.body);

		const frame = getTarget();
		if (frame) {
			frame.setAttribute('id', '_oldTarget');
		}

		// keep current scrollTop around and use later
		const scrollTop = frame && frame.contentDocument && frame.contentDocument.body ? frame.contentDocument.body.scrollTop : 0;

		const newFrame = document.createElement('iframe');
		newFrame.setAttribute('id', '_target');
		newFrame.setAttribute('frameborder', '0');
		newFrame.setAttribute('sandbox', 'allow-scripts allow-forms allow-same-origin');
		newFrame.style.cssText = "margin: 0; overflow: hidden; position: absolute; width: 100%; height: 100%; display: none";
		document.body.appendChild(newFrame);

		// write new content onto iframe
		newFrame.contentDocument.open('text/html', 'replace');
		newFrame.contentWindow.onbeforeunload = function (e) {
			console.log('prevented webview navigation');
			return false;
		};

		// workaround for https://github.com/Microsoft/vscode/issues/12865
		// check new scrollTop and reset if neccessary
		newFrame.contentWindow.addEventListener('DOMContentLoaded', function (e) {
			const contentDocument = e.target;
			if (contentDocument.body) {
				if (scrollTop !== contentDocument.body.scrollTop) {
					contentDocument.body.scrollTop = scrollTop;
				}

				// bubble out link-clicks
				contentDocument.body.addEventListener('click', handleInnerClick);
			}

			// Clean up old frames
			[].forEach.call(document.body.getElementsByTagName('iframe'), frame => {
				if (frame.id !== '_target') {
					document.body.removeChild(frame);
				}
			});

			const newFrame = document.getElementById('_target');
			if (newFrame.contentDocument === contentDocument) {
				newFrame.style.display = 'block';
			}
		});

		// set DOCTYPE for newDocument explicitly as DOMParser.parseFromString strips it off
		// and DOCTYPE is needed in the iframe to ensure that the user agent stylesheet is correctly overridden
		newFrame.contentDocument.write('<!DOCTYPE html>');
		newFrame.contentDocument.write(newDocument.documentElement.innerHTML);
		newFrame.contentDocument.close();

		ipcRenderer.sendToHost('did-set-content', stats);
	});

	// Forward message to the embedded iframe
	ipcRenderer.on('message', function (event, data) {
		const target = getTarget();
		if (target) {
			target.contentWindow.postMessage(data, document.location.origin);
		}
	});

	// forward messages from the embedded iframe
	window.onmessage = function (message) {
		ipcRenderer.sendToHost(message.data.command, message.data.data);
	};

	// signal ready
	ipcRenderer.sendToHost('webview-ready', process.pid);
});<commit_msg>Small doc clearnup<commit_after>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

const ipcRenderer = require('electron').ipcRenderer;

var initData = {};

function styleBody(body) {
	if (!body) {
		return
	}
	body.classList.remove('vscode-light', 'vscode-dark', 'vscode-high-contrast');
	body.classList.add(initData.activeTheme);
}

function getTarget() {
	return document.getElementById('_target');
}

function handleInnerClick(event) {
	if (!event || !event.view || !event.view.document) {
		return;
	}
	var node = event.target;
	while (node) {
		if (node.tagName === "A" && node.href) {
			var baseElement = event.view.document.getElementsByTagName("base")[0];
			if (node.getAttribute("href") === "#") {
				event.view.scrollTo(0, 0);
			} else if (node.hash && (node.getAttribute("href") === node.hash || (baseElement && node.href.indexOf(baseElement.href) >= 0))) {
				var scrollTarget = event.view.document.getElementById(node.hash.substr(1, node.hash.length - 1));
				if (scrollTarget) {
					scrollTarget.scrollIntoView();
				}
			} else {
				ipcRenderer.sendToHost("did-click-link", node.href);
			}
			event.preventDefault();
			break;
		}
		node = node.parentNode;
	}
}

document.addEventListener("DOMContentLoaded", function (event) {
	ipcRenderer.on('baseUrl', function (event, value) {
		initData.baseUrl = value;
	});

	ipcRenderer.on('styles', function (event, value, activeTheme) {
		initData.styles = value;
		initData.activeTheme = activeTheme;

		// webview
		var target = getTarget()
		if (!target) {
			return;
		}
		var body = target.contentDocument.getElementsByTagName('body');
		styleBody(body[0]);

		// iframe
		defaultStyles = target.contentDocument.getElementById('_defaultStyles');
		if (defaultStyles) {
			defaultStyles.innerHTML = initData.styles;
		}
	});

	// propagate focus
	ipcRenderer.on('focus', function () {
		const target = getTarget();
		if (target) {
			target.contentWindow.focus();
		}
	});

	// update iframe-contents
	ipcRenderer.on('content', function (_event, value) {
		const text = value.join('\n');
		const newDocument = new DOMParser().parseFromString(text, 'text/html');

		// know what happens here
		const stats = {
			scriptTags: newDocument.documentElement.querySelectorAll('script').length,
			inputTags: newDocument.documentElement.querySelectorAll('input').length,
			styleTags: newDocument.documentElement.querySelectorAll('style').length,
			linkStyleSheetTags: newDocument.documentElement.querySelectorAll('link[rel=stylesheet]').length,
			stringLen: text.length
		};

		// set base-url if applicable
		if (initData.baseUrl && newDocument.head.getElementsByTagName('base').length === 0) {
			const baseElement = newDocument.createElement('base');
			baseElement.href = initData.baseUrl;
			newDocument.head.appendChild(baseElement);
		}

		// apply default styles
		const defaultStyles = newDocument.createElement('style');
		defaultStyles.id = '_defaultStyles';
		defaultStyles.innerHTML = initData.styles;
		if (newDocument.head.hasChildNodes()) {
			newDocument.head.insertBefore(defaultStyles, newDocument.head.firstChild);
		} else {
			newDocument.head.appendChild(defaultStyles);
		}

		styleBody(newDocument.body);

		const frame = getTarget();
		if (frame) {
			frame.setAttribute('id', '_oldTarget');
		}

		// keep current scrollTop around and use later
		const scrollTop = frame && frame.contentDocument && frame.contentDocument.body ? frame.contentDocument.body.scrollTop : 0;

		const newFrame = document.createElement('iframe');
		newFrame.setAttribute('id', '_target');
		newFrame.setAttribute('frameborder', '0');
		newFrame.setAttribute('sandbox', 'allow-scripts allow-forms allow-same-origin');
		newFrame.style.cssText = "margin: 0; overflow: hidden; position: absolute; width: 100%; height: 100%; display: none";
		document.body.appendChild(newFrame);

		// write new content onto iframe
		newFrame.contentDocument.open('text/html', 'replace');
		newFrame.contentWindow.onbeforeunload = function (e) {
			console.log('prevented webview navigation');
			return false;
		};

		newFrame.contentWindow.addEventListener('DOMContentLoaded', function (e) {
			const contentDocument = e.target;
			if (contentDocument.body) {

				// Workaround for https://github.com/Microsoft/vscode/issues/12865
				// check new scrollTop and reset if neccessary
				if (scrollTop !== contentDocument.body.scrollTop) {
					contentDocument.body.scrollTop = scrollTop;
				}

				// Bubble out link clicks
				contentDocument.body.addEventListener('click', handleInnerClick);
			}

			// Clean up old frames
			[].forEach.call(document.body.getElementsByTagName('iframe'), frame => {
				if (frame.id !== '_target') {
					document.body.removeChild(frame);
				}
			});

			const newFrame = document.getElementById('_target');
			if (newFrame.contentDocument === contentDocument) {
				newFrame.style.display = 'block';
			}
		});

		// set DOCTYPE for newDocument explicitly as DOMParser.parseFromString strips it off
		// and DOCTYPE is needed in the iframe to ensure that the user agent stylesheet is correctly overridden
		newFrame.contentDocument.write('<!DOCTYPE html>');
		newFrame.contentDocument.write(newDocument.documentElement.innerHTML);
		newFrame.contentDocument.close();

		ipcRenderer.sendToHost('did-set-content', stats);
	});

	// Forward message to the embedded iframe
	ipcRenderer.on('message', function (event, data) {
		const target = getTarget();
		if (target) {
			target.contentWindow.postMessage(data, document.location.origin);
		}
	});

	// forward messages from the embedded iframe
	window.onmessage = function (message) {
		ipcRenderer.sendToHost(message.data.command, message.data.data);
	};

	// signal ready
	ipcRenderer.sendToHost('webview-ready', process.pid);
});<|endoftext|>


<commit_before>/**
 * PageSpeed Insights Settings stories.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import { storiesOf } from '@storybook/react';

/**
 * WordPress dependencies
 */
import { removeAllFilters, addFilter } from '@wordpress/hooks';

/**
 * Internal dependencies
 */
import SettingsModule from '../assets/js/components/settings/settings-module';
import { SettingsMain as PageSpeedInsightsSettings } from '../assets/js/modules/pagespeed-insights/settings';
import { fillFilterWithComponent } from '../assets/js/util';

import { STORE_NAME } from '../assets/js/modules/pagespeed-insights/datastore';
import { WithTestRegistry } from '../tests/js/utils';

function filterPageSpeedInsightsSettings() {
	removeAllFilters( 'googlesitekit.ModuleSettingsDetails-pagespeed-insights' );
	addFilter(
		'googlesitekit.ModuleSettingsDetails-pagespeed-insights',
		'googlesitekit.PageSpeedInsightsModuleSettingsDetails',
		fillFilterWithComponent( PageSpeedInsightsSettings ), 10 );
}

const completeModuleData = {
	...global.googlesitekit.modules[ 'pagespeed-insights' ],
	active: true,
	setupComplete: true,
};

function Settings( props ) {
	const {
		callback,
		module = global.googlesitekit.modules[ 'pagespeed-insights' ],
		isEditing = false,
		isOpen = true,
		isSaving = false,
		error = false,
		// eslint-disable-next-line no-console
		handleAccordion = ( ...args ) => console.log( 'handleAccordion', ...args ),
		// eslint-disable-next-line no-console
		handleDialog = ( ...args ) => console.log( 'handleDialog', ...args ),
		// eslint-disable-next-line no-console
		updateModulesList = ( ...args ) => console.log( 'updateModulesList', ...args ),
		// eslint-disable-next-line no-console
		handleButtonAction = ( ...args ) => console.log( 'handleButtonAction', ...args ),
	} = props;

	return (
		<WithTestRegistry callback={ callback }>

				<SettingsModule
					key={ module.slug + '-module' }
					slug={ module.slug }
					name={ module.name }
					description={ module.description }
					homepage={ module.homepage }
					learnmore={ module.learnMore }
					active={ module.active }
					setupComplete={ module.setupComplete }
					hasSettings={ false }
					autoActivate={ module.autoActivate }
					updateModulesList={ updateModulesList }
					handleEdit={ handleButtonAction }
					handleConfirm
					isEditing={ isEditing ? { 'pagespeed-insights-module': true } : {} }
					isOpen={ isOpen }
					handleAccordion={ handleAccordion }
					handleDialog={ handleDialog }
					provides={ module.provides }
					isSaving={ isSaving }
					screenID={ module.screenID }
					error={ error }
				/>

		</WithTestRegistry>
	);
}

storiesOf( 'PageSpeed Insights Module/Settings', module )
	.add( 'View, closed', () => {
		filterPageSpeedInsightsSettings();

		const setupRegistry = ( { dispatch } ) => {
			dispatch( STORE_NAME ).receiveSettings( {} );
		};

		return <Settings isOpen={ false } module={ completeModuleData } callback={ setupRegistry } />;
	} )
	.add( 'View, open with all settings', () => {
		filterPageSpeedInsightsSettings();

		const setupRegistry = ( { dispatch } ) => {
			dispatch( STORE_NAME ).receiveSettings( {
				propertyID: 'http://example.com/',
			} );
		};

		return <Settings module={ completeModuleData } callback={ setupRegistry } />;
	} )
;
<commit_msg>Removed store name from storybook.<commit_after>/**
 * PageSpeed Insights Settings stories.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import { storiesOf } from '@storybook/react';

/**
 * WordPress dependencies
 */
import { removeAllFilters, addFilter } from '@wordpress/hooks';

/**
 * Internal dependencies
 */
import SettingsModule from '../assets/js/components/settings/settings-module';
import { SettingsMain as PageSpeedInsightsSettings } from '../assets/js/modules/pagespeed-insights/settings';
import { fillFilterWithComponent } from '../assets/js/util';
import { WithTestRegistry } from '../tests/js/utils';

function filterPageSpeedInsightsSettings() {
	removeAllFilters( 'googlesitekit.ModuleSettingsDetails-pagespeed-insights' );
	addFilter(
		'googlesitekit.ModuleSettingsDetails-pagespeed-insights',
		'googlesitekit.PageSpeedInsightsModuleSettingsDetails',
		fillFilterWithComponent( PageSpeedInsightsSettings ), 10 );
}

const completeModuleData = {
	...global.googlesitekit.modules[ 'pagespeed-insights' ],
	active: true,
	setupComplete: true,
};

function Settings( props ) {
	const {
		callback,
		module = global.googlesitekit.modules[ 'pagespeed-insights' ],
		isEditing = false,
		isOpen = true,
		isSaving = false,
		error = false,
		// eslint-disable-next-line no-console
		handleAccordion = ( ...args ) => console.log( 'handleAccordion', ...args ),
		// eslint-disable-next-line no-console
		handleDialog = ( ...args ) => console.log( 'handleDialog', ...args ),
		// eslint-disable-next-line no-console
		updateModulesList = ( ...args ) => console.log( 'updateModulesList', ...args ),
		// eslint-disable-next-line no-console
		handleButtonAction = ( ...args ) => console.log( 'handleButtonAction', ...args ),
	} = props;

	return (
		<WithTestRegistry callback={ callback }>

				<SettingsModule
					key={ module.slug + '-module' }
					slug={ module.slug }
					name={ module.name }
					description={ module.description }
					homepage={ module.homepage }
					learnmore={ module.learnMore }
					active={ module.active }
					setupComplete={ module.setupComplete }
					hasSettings={ false }
					autoActivate={ module.autoActivate }
					updateModulesList={ updateModulesList }
					handleEdit={ handleButtonAction }
					handleConfirm
					isEditing={ isEditing ? { 'pagespeed-insights-module': true } : {} }
					isOpen={ isOpen }
					handleAccordion={ handleAccordion }
					handleDialog={ handleDialog }
					provides={ module.provides }
					isSaving={ isSaving }
					screenID={ module.screenID }
					error={ error }
				/>

		</WithTestRegistry>
	);
}

storiesOf( 'PageSpeed Insights Module/Settings', module )
	.add( 'View, closed', () => {
		filterPageSpeedInsightsSettings();

		return <Settings isOpen={ false } module={ completeModuleData } />;
	} )
	.add( 'View, open with all settings', () => {
		filterPageSpeedInsightsSettings();

		return <Settings module={ completeModuleData } />;
	} )
;
<|endoftext|>


<commit_before>/**
 * Copyright 2015-2021 OpenCB
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {LitElement, html} from "lit";
import UtilsNew from "../../../core/utilsNew.js";
import LitUtils from "../utils/lit-utils.js";
import "../../job/job-monitor.js";

export default class CustomNavBar extends LitElement {

    constructor() {
        super();
    }

    createRenderRoot() {
        return this;
    }

    static get properties() {
        return {
            loggedIn: {
                type: Boolean
            },
            app: {
                type: Object
            },
            opencgaSession: {
                type: Object
            },
            config: {
                type: Object
            }
        };
    }

    onSideBarToggle(e) {
        LitUtils.dispatchEventCustom(this, "sideBarToggle", "", null, {event: e});
    }

    onChangeTool(e) {
        LitUtils.dispatchEventCustom(this, "changeTool", e);
    }

    onChangeApp(e, toggle) {
        LitUtils.dispatchEventCustom(this, "changeApp", "", null, {event: e, toggle: toggle});
    }

    onStudySelect(e, study) {
        e.preventDefault(); // prevents the hash change to "#" and allows to manipulate the hash fragment as needed
        LitUtils.dispatchEventCustom(this, "studySelect", "", null, {event: e, study: study});
    }

    createAboutLink(link, button) {
        const url = link.url ? `${link.url}` : `#${link.id}`;
        const iconHtml = link.icon ? html`<i class="${link.icon} icon-padding" aria-hidden="true"></i>` : null;
        if (link.url) {
            return html`
                ${iconHtml} ${link.name}`;
        } else {
            return html`
                ${iconHtml} ${link.name}`;
        }
    }

    logout() {
        LitUtils.dispatchEventCustom(this, "logout");
    }

    render() {
        return html `

                    ${this.config.apps?.filter(app => UtilsNew.isAppVisible(app, this.opencgaSession)).length > 1 ? html`

                    ` : null}

                        ${this.config?.companyLogo ? html`

                        ` : null}
                        ${this.app?.logo ? html`

                                ${this.config.version}

                        ` : null}

                            ${this.app?.menu?.filter?.(item => UtilsNew.isAppVisible(item, this.opencgaSession)).map(item => html`

                                ${item.submenu && item.submenu.some(sm => UtilsNew.isAppVisible(sm, this.opencgaSession)) ? html`

                                            ${item.name}

                                            ${item.submenu.map(subitem => subitem.category ? html`

                                                    ${subitem.name}

                                            ` : subitem.separator ? html`

                                            ` : html`

                                                    ${subitem.name}

                                            `)}

                                ` : html`

                                        ${item.name}

`
                                }`
                            )}

                            ${this.opencgaSession && this.opencgaSession.projects && this.opencgaSession.projects.length ? html`

${this.opencgaSession.project?.name}

${this.opencgaSession.study.name}

                                        ${this.opencgaSession.projects.filter(project => project?.studies.length > 0).map(project => html`

${project.name} [${project.fqn.split("@")[0]}]

                                            ${project.studies && project.studies.length && project.studies.map(study => html`

                                                    <a href="javascript: void 0"
                                                       data-cy-fqn="${study.fqn}"
                                                       data-study="${study.id}"
                                                       data-project="${project.id}"
                                                       data-project-name="${project.name}"
                                                       data-study-name="${study.name}"
                                                       title="${study.fqn}"
                                                       @click="${e => this.onStudySelect(e, study)}">${study.name}

                                            `)}
                                        `)}

                            ` : null}

                            ${UtilsNew.isAppVisible(this.app?.jobMonitor, this.opencgaSession) ? html`
                                <job-monitor .opencgaSession="${this.opencgaSession}"></job-monitor>
                            ` : null}

                            ${UtilsNew.isAppVisible(this.app?.fileExplorer, this.opencgaSession) ? html`

                            ` : null}

                            ${this.app?.about.dropdown ? html`

                                        About

                                        ${this.app.about.links && this.app.about.links.map(link => html`

${this.createAboutLink(link, false)}

                                        `)}

                            ` : this.app?.about.links && this.app.about.links.map(link => html`

${this.createAboutLink(link, true)}

                            `) }

                            ${this.config.login.visible && !this.loggedIn ? html`

                                        Login

                            ` : null}

                            ${this.loggedIn ? html`

                                        ${this.opencgaSession.user?.name ?? this.opencgaSession.user?.email}

                                        ${this.app?.userMenu?.length ? this.app.userMenu.filter(item => UtilsNew.isAppVisible(item, this.opencgaSession)).map(item => html`

                                                 ${item.name}

                                        `) : null}

                                                 Logout

                            ` : null}

            `;
    }

}

customElements.define("custom-navbar", CustomNavBar);
<commit_msg>custom-navbar.js visiblity bug fixed<commit_after>/**
 * Copyright 2015-2021 OpenCB
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {LitElement, html} from "lit";
import UtilsNew from "../../../core/utilsNew.js";
import LitUtils from "../utils/lit-utils.js";
import "../../job/job-monitor.js";

export default class CustomNavBar extends LitElement {

    constructor() {
        super();
    }

    createRenderRoot() {
        return this;
    }

    static get properties() {
        return {
            loggedIn: {
                type: Boolean
            },
            app: {
                type: Object
            },
            opencgaSession: {
                type: Object
            },
            config: {
                type: Object
            }
        };
    }

    onSideBarToggle(e) {
        LitUtils.dispatchEventCustom(this, "sideBarToggle", "", null, {event: e});
    }

    onChangeTool(e) {
        LitUtils.dispatchEventCustom(this, "changeTool", e);
    }

    onChangeApp(e, toggle) {
        LitUtils.dispatchEventCustom(this, "changeApp", "", null, {event: e, toggle: toggle});
    }

    onStudySelect(e, study) {
        e.preventDefault(); // prevents the hash change to "#" and allows to manipulate the hash fragment as needed
        LitUtils.dispatchEventCustom(this, "studySelect", "", null, {event: e, study: study});
    }

    createAboutLink(link, button) {
        const url = link.url ? `${link.url}` : `#${link.id}`;
        const iconHtml = link.icon ? html`<i class="${link.icon} icon-padding" aria-hidden="true"></i>` : null;
        if (link.url) {
            return html`
                ${iconHtml} ${link.name}`;
        } else {
            return html`
                ${iconHtml} ${link.name}`;
        }
    }

    logout() {
        LitUtils.dispatchEventCustom(this, "logout");
    }

    render() {
        return html `

                    ${this.config.apps?.filter(app => UtilsNew.isAppVisible(app, this.opencgaSession)).length > 1 ? html`

                    ` : null}

                        ${this.config?.companyLogo ? html`

                        ` : null}
                        ${this.app?.logo ? html`

                                ${this.config.version}

                        ` : null}

                            ${this.app?.menu?.filter?.(item => UtilsNew.isAppVisible(item, this.opencgaSession)).map(item => html`

                                ${item.submenu && item.submenu.some(sm => UtilsNew.isAppVisible(sm, this.opencgaSession)) ? html`

                                            ${item.name}

                                            ${item.submenu.filter(subitem => UtilsNew.isAppVisible(subitem, this.opencgaSession)).map(subitem => subitem.category ? html`

                                                    ${subitem.name}

                                            ` : subitem.separator ? html`

                                            ` : html`

                                                    ${subitem.name}

                                            `)}

                                ` : html`

                                        ${item.name}

`
                                }`
                            )}

                            ${this.opencgaSession && this.opencgaSession.projects && this.opencgaSession.projects.length ? html`

${this.opencgaSession.project?.name}

${this.opencgaSession.study.name}

                                        ${this.opencgaSession.projects.filter(project => project?.studies.length > 0).map(project => html`

${project.name} [${project.fqn.split("@")[0]}]

                                            ${project.studies && project.studies.length && project.studies.map(study => html`

                                                    <a href="javascript: void 0"
                                                       data-cy-fqn="${study.fqn}"
                                                       data-study="${study.id}"
                                                       data-project="${project.id}"
                                                       data-project-name="${project.name}"
                                                       data-study-name="${study.name}"
                                                       title="${study.fqn}"
                                                       @click="${e => this.onStudySelect(e, study)}">${study.name}

                                            `)}
                                        `)}

                            ` : null}

                            ${UtilsNew.isAppVisible(this.app?.jobMonitor, this.opencgaSession) ? html`
                                <job-monitor .opencgaSession="${this.opencgaSession}"></job-monitor>
                            ` : null}

                            ${UtilsNew.isAppVisible(this.app?.fileExplorer, this.opencgaSession) ? html`

                            ` : null}

                            ${this.app?.about.dropdown ? html`

                                        About

                                        ${this.app.about.links && this.app.about.links.map(link => html`

${this.createAboutLink(link, false)}

                                        `)}

                            ` : this.app?.about.links && this.app.about.links.map(link => html`

${this.createAboutLink(link, true)}

                            `) }

                            ${this.config.login.visible && !this.loggedIn ? html`

                                        Login

                            ` : null}

                            ${this.loggedIn ? html`

                                        ${this.opencgaSession.user?.name ?? this.opencgaSession.user?.email}

                                        ${this.app?.userMenu?.length ? this.app.userMenu.filter(item => UtilsNew.isAppVisible(item, this.opencgaSession)).map(item => html`

                                                 ${item.name}

                                        `) : null}

                                                 Logout

                            ` : null}

            `;
    }

}

customElements.define("custom-navbar", CustomNavBar);
<|endoftext|>


<commit_before>cop.create("UnconstrainAndDisableAllLayer")
    .refineClass(Babelsberg, {
        unconstrain: function(obj, accessor) {
            var cvar = ConstrainedVariable.findConstraintVariableFor(obj, accessor);
            cvar._constraints.each(function(constraint) {
                constraint.disable();
            });
            cop.proceed(obj, accessor);
        }
    })
    //.beGlobal();

Object.subclass("Game", {
    initialize: function(canvasId) {
        this.buildCanvas(canvasId);
        this.buildInput(canvasId);
        this.renderer = new Renderer(this.canvas);
        this.buildViewport();
        this.constrainDebugLayer();
        this.levels = new LevelPointer();
    },
    buildCanvas: function(canvasId) {
        this.canvas = document.getElementById(canvasId);
        this.canvas.style.position = "absolute";
        this.canvas.style.top = "0px";
        this.canvas.style.left = "0px";
        this.canvas.style["z-index"] = -1;
    },
    buildInput: function(canvasId) {
        this.input = new Input(canvasId);

        this.input.bind(Input.KEY.W, "up");
        this.input.bind(Input.KEY.A, "left");
        this.input.bind(Input.KEY.S, "down");
        this.input.bind(Input.KEY.D, "right");

        this.input.bind(Input.KEY.UP_ARROW, "up");
        this.input.bind(Input.KEY.LEFT_ARROW, "left");
        this.input.bind(Input.KEY.DOWN_ARROW, "down");
        this.input.bind(Input.KEY.RIGHT_ARROW, "right");

        this.input.bind(Input.KEY.MOUSE1, "leftclick");
        this.input.bind(Input.KEY.MOUSE2, "rightclick");
        this.input.bind(Input.KEY.MWHEEL_UP, "zoomIn");
        this.input.bind(Input.KEY.MWHEEL_DOWN, "zoomOut");

        this.input.bind(Input.KEY.P, "debug");
    },
    buildViewport: function() {
        var input = this.input,
            viewport = this.viewport = new Viewport(
                new Vector2(30, 30* this.canvas.height/this.canvas.width),
                new Vector2(60, 60 * this.canvas.height/this.canvas.width)
            );

        // constraint:
        // - keep input position in world and mouse on screen in sync
        bbb.always({
            solver: new DBPlanner(),
            ctx: {
                input: input,
                viewport: viewport
            },
            methods: function() {
                input.position.formula([input.mouse, input.mouse.x, input.mouse.y], function(mouse, mouseX, mouseY) {
                    return viewport.screenToWorldCoordinates(mouse);
                });
            }
        }, function() {
            return input.position.equals(viewport.screenToWorldCoordinates(input.mouse));
        });
    },
    constrainDebugLayer: function() {
        var input = this.input;

        // do not debugdraw velocities if debug button is pressed
        DebugLayer.activeOn({
            ctx: {
                input: input
            }
        }, function() {
            return input.switchedOn("debug") == true;
        });
    },
    prepare: function() {
        this.resetLevel();
    },
    resetLevel: function() {
        // TODO: eliminate duplications
        this.cleanUp();
        var builder = new WorldBuilder(this);
        this.world = builder.buildWorld(this.levels.get());

        this.gui = new Gui(this.world, this.input, player, this.viewport);
    },
    nextLevel: function() {
        this.cleanUp();
        var builder = new WorldBuilder(this);
        this.world = builder.buildWorld(this.levels.next());

        this.gui = new Gui(this.world, this.input, player, this.viewport);
    },
    cleanUp: function() {
        // TODO
    },
    update: function(dt) {
        this.updatePhysics(dt);
        this.gui.update(dt);
        this.draw();

        this.input.clearPressed();
    },
    updatePhysics: function(dt) {
        this.world.update(dt);
    },
    draw: function() {
        this.renderer.clear();
        this.renderer.withViewport(this.viewport, (function() {
            this.world.draw(this.renderer);
        }).bind(this));
        this.gui.draw(this.renderer);
    }
});

cop.create("DebugLayer")
    .refineClass(GameObject, {
        draw: function(renderer) {
            cop.proceed(renderer);
            renderer.drawLine(this.position, this.position.add(this.velocity), "red", 1, 3);
        }
    })
    .refineClass(CPUControls, {
        getTargetTiles: function() {
            var tiles = cop.proceed();

            tiles.each(function(tile) {
                tile.marked = tile.canFlyThrough() ? this.color : "red";
            }, this);

            return tiles;
        }
    })
    .refineClass(Tile, {
        draw: function(renderer, x, y, size) {
            cop.proceed(renderer, x, y, size);
            if(this.marked) {
                var min = new Vector2(x, y).mulVector(size);
                renderer.drawRectangle(
                    min.add(size.mulFloat(0.5)),
                    25,
                    this.marked,
                    1
                );
            }
            this.marked = false;
        }
    });

cop.create("AdjustViewportManuallyLayer")
    .refineClass(Game, {
        initialize: function(canvasId) {
            cop.proceed(canvasId);

            this.downPoint = Vector2.Zero.copy();
            this.lastPoint = Vector2.Zero.copy();
        },
        update: function(dt) {
            if(this.input.pressed("leftclick")) {
                this.downPoint.set(this.input.mouse);
            }
            if(this.input.pressed("rightclick")) {
                this.lastPoint.set(this.input.mouse);
            }
            // viewport manipulation
            if(this.input.state("rightclick")) {
                this.viewport.translateBy(this.canvas, this.lastPoint.sub(this.input.mouse));
                this.lastPoint.set(this.input.mouse);
            }
            if(this.input.state("zoomIn")) {
                this.viewport.zoomIn();
            }
            if(this.input.state("zoomOut")) {
                this.viewport.zoomOut();
            }

            cop.proceed(dt);
        }
    })
    .beGlobal();

Object.subclass("Timer", {
    initialize: function() {
        this.lastFrame = window.performance.now();

        // TODO: minimal framerate constraint
    },
    // returns time since last call
    update: function() {
        var time = window.performance.now(),
            dt = (time - this.lastFrame) / 1000;
        this.lastFrame = time;
        return dt;
    }
});

Object.subclass("Loop", {
    initialize: function(func) {
        this.func = func;
    },
    start: function() {
        this.update();
    },
    update: function() {
        this.func();
        requestAnimationFrame(this.update.bind(this));
    }
});

function loadJSON(path, callback) {
    var xobj = new XMLHttpRequest();
    xobj.overrideMimeType("application/json");
	xobj.open('GET', path, true); // Replace 'my_data' with the path to your file
	xobj.onreadystatechange = function () {
        if (xobj.readyState == 4) {
            // Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
            // Parse JSON string into object
            var actual_JSON = JSON.parse(xobj.responseText);
            callback(actual_JSON);
        }
    };
    xobj.send(null);
};

loadLevel = function(index, path, callback) {
    loadJSON("assets/levels/" + path, function(json) {
        Levels[index] = json;
        callback(null, json);
     });
};

window.onload = function() {
    var canvasId = "game",
        game = new Game(canvasId);

    // prepare stats
    var stats = new Stats();
    stats.domElement.style.position = 'absolute';
    stats.domElement.style.left = '0px';
    stats.domElement.style.top = '0px';
    document.body.appendChild( stats.domElement );

    // main loop
    var timer = new Timer();
    function animate() {
        stats.update();
        var dt = timer.update();
        game.update(dt);
    }
    var loop = new Loop(animate);

    // asset loading
    queue()
        .defer(loadLevel, 0, '0_tutorial.json')
        .defer(loadLevel, 1, '1_movingtank.json')
        .defer(loadLevel, 2, '2_multipletanks.json')
        .defer(loadLevel, 3, '3_grid.json')
        .defer(loadLevel, 4, '4_hunter.json')
        .defer(loadLevel, 5, '5_borderline.json')
        .defer(loadLevel, 6, '6_hunter2.json')
        .defer(loadLevel, 7, '7_demo.json')
        .defer(loadImage, "tileset.png")
        .defer(loadImage, "tank.png")
        .defer(loadImage, "turret.png")
        .defer(loadImage, "bullet.png")
        .defer(loadImage, "target.png")
        .await(function(error) {
            if(error) {
                console.error("error while loading", error);
            } else {
                console.log(arguments[1]);
                game.prepare();
                loop.start();
            }
        });
};
<commit_msg>added OneBulletPerFrameLayer<commit_after>cop.create("UnconstrainAndDisableAllLayer")
    .refineClass(Babelsberg, {
        unconstrain: function(obj, accessor) {
            var cvar = ConstrainedVariable.findConstraintVariableFor(obj, accessor);
            cvar._constraints.each(function(constraint) {
                constraint.disable();
            });
            cop.proceed(obj, accessor);
        }
    })
    //.beGlobal();

Object.subclass("Game", {
    initialize: function(canvasId) {
        this.buildCanvas(canvasId);
        this.buildInput(canvasId);
        this.renderer = new Renderer(this.canvas);
        this.buildViewport();
        this.constrainDebugLayer();
        this.levels = new LevelPointer();
    },
    buildCanvas: function(canvasId) {
        this.canvas = document.getElementById(canvasId);
        this.canvas.style.position = "absolute";
        this.canvas.style.top = "0px";
        this.canvas.style.left = "0px";
        this.canvas.style["z-index"] = -1;
    },
    buildInput: function(canvasId) {
        this.input = new Input(canvasId);

        this.input.bind(Input.KEY.W, "up");
        this.input.bind(Input.KEY.A, "left");
        this.input.bind(Input.KEY.S, "down");
        this.input.bind(Input.KEY.D, "right");

        this.input.bind(Input.KEY.UP_ARROW, "up");
        this.input.bind(Input.KEY.LEFT_ARROW, "left");
        this.input.bind(Input.KEY.DOWN_ARROW, "down");
        this.input.bind(Input.KEY.RIGHT_ARROW, "right");

        this.input.bind(Input.KEY.MOUSE1, "leftclick");
        this.input.bind(Input.KEY.MOUSE2, "rightclick");
        this.input.bind(Input.KEY.MWHEEL_UP, "zoomIn");
        this.input.bind(Input.KEY.MWHEEL_DOWN, "zoomOut");

        this.input.bind(Input.KEY.P, "debug");
    },
    buildViewport: function() {
        var input = this.input,
            viewport = this.viewport = new Viewport(
                new Vector2(30, 30* this.canvas.height/this.canvas.width),
                new Vector2(60, 60 * this.canvas.height/this.canvas.width)
            );

        // constraint:
        // - keep input position in world and mouse on screen in sync
        bbb.always({
            solver: new DBPlanner(),
            ctx: {
                input: input,
                viewport: viewport
            },
            methods: function() {
                input.position.formula([input.mouse, input.mouse.x, input.mouse.y], function(mouse, mouseX, mouseY) {
                    return viewport.screenToWorldCoordinates(mouse);
                });
            }
        }, function() {
            return input.position.equals(viewport.screenToWorldCoordinates(input.mouse));
        });
    },
    constrainDebugLayer: function() {
        var input = this.input;

        // do not debugdraw velocities if debug button is pressed
        DebugLayer.activeOn({
            ctx: {
                input: input
            }
        }, function() {
            return input.switchedOn("debug") == true;
        });
    },
    prepare: function() {
        this.resetLevel();
    },
    resetLevel: function() {
        // TODO: eliminate duplications
        this.cleanUp();
        var builder = new WorldBuilder(this);
        this.world = builder.buildWorld(this.levels.get());

        this.gui = new Gui(this.world, this.input, player, this.viewport);
    },
    nextLevel: function() {
        this.cleanUp();
        var builder = new WorldBuilder(this);
        this.world = builder.buildWorld(this.levels.next());

        this.gui = new Gui(this.world, this.input, player, this.viewport);
    },
    cleanUp: function() {
        // TODO
    },
    update: function(dt) {
        this.updatePhysics(dt);
        this.gui.update(dt);
        this.draw();

        this.input.clearPressed();
    },
    updatePhysics: function(dt) {
        this.world.update(dt);
    },
    draw: function() {
        this.renderer.clear();
        this.renderer.withViewport(this.viewport, (function() {
            this.world.draw(this.renderer);
        }).bind(this));
        this.gui.draw(this.renderer);
    }
});

cop.create("DebugLayer")
    .refineClass(GameObject, {
        draw: function(renderer) {
            cop.proceed(renderer);
            renderer.drawLine(this.position, this.position.add(this.velocity), "red", 1, 3);
        }
    })
    .refineClass(CPUControls, {
        getTargetTiles: function() {
            var tiles = cop.proceed();

            tiles.each(function(tile) {
                tile.marked = tile.canFlyThrough() ? this.color : "red";
            }, this);

            return tiles;
        }
    })
    .refineClass(Tile, {
        draw: function(renderer, x, y, size) {
            cop.proceed(renderer, x, y, size);
            if(this.marked) {
                var min = new Vector2(x, y).mulVector(size);
                renderer.drawRectangle(
                    min.add(size.mulFloat(0.5)),
                    25,
                    this.marked,
                    1
                );
            }
            this.marked = false;
        }
    });

cop.create("AdjustViewportManuallyLayer")
    .refineClass(Game, {
        initialize: function(canvasId) {
            cop.proceed(canvasId);

            this.downPoint = Vector2.Zero.copy();
            this.lastPoint = Vector2.Zero.copy();
        },
        update: function(dt) {
            if(this.input.pressed("leftclick")) {
                this.downPoint.set(this.input.mouse);
            }
            if(this.input.pressed("rightclick")) {
                this.lastPoint.set(this.input.mouse);
            }
            // viewport manipulation
            if(this.input.state("rightclick")) {
                this.viewport.translateBy(this.canvas, this.lastPoint.sub(this.input.mouse));
                this.lastPoint.set(this.input.mouse);
            }
            if(this.input.state("zoomIn")) {
                this.viewport.zoomIn();
            }
            if(this.input.state("zoomOut")) {
                this.viewport.zoomOut();
            }

            cop.proceed(dt);
        }
    })
    .beGlobal();

cop.create("OneBulletPerFrameLayer")
    .refineClass(Tank, {
        fireBullet: function(world, dt) {
            if(OneBulletPerFrameLayer.bulletShot) {
                return;
            }
            OneBulletPerFrameLayer.bulletShot = true;
            return cop.proceed(world, dt);
        }
    })
    .refineClass(World, {
        update: function(dt) {
            OneBulletPerFrameLayer.bulletShot = false;

            return cop.proceed(dt);
        }
    })
    .beGlobal();

Object.subclass("Timer", {
    initialize: function() {
        this.lastFrame = window.performance.now();

        // TODO: minimal framerate constraint
    },
    // returns time since last call
    update: function() {
        var time = window.performance.now(),
            dt = (time - this.lastFrame) / 1000;
        this.lastFrame = time;
        return dt;
    }
});

Object.subclass("Loop", {
    initialize: function(func) {
        this.func = func;
    },
    start: function() {
        this.update();
    },
    update: function() {
        this.func();
        requestAnimationFrame(this.update.bind(this));
    }
});

function loadJSON(path, callback) {
    var xobj = new XMLHttpRequest();
    xobj.overrideMimeType("application/json");
	xobj.open('GET', path, true); // Replace 'my_data' with the path to your file
	xobj.onreadystatechange = function () {
        if (xobj.readyState == 4) {
            // Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
            // Parse JSON string into object
            var actual_JSON = JSON.parse(xobj.responseText);
            callback(actual_JSON);
        }
    };
    xobj.send(null);
};

loadLevel = function(index, path, callback) {
    loadJSON("assets/levels/" + path, function(json) {
        Levels[index] = json;
        callback(null, json);
     });
};

window.onload = function() {
    var canvasId = "game",
        game = new Game(canvasId);

    // prepare stats
    var stats = new Stats();
    stats.domElement.style.position = 'absolute';
    stats.domElement.style.left = '0px';
    stats.domElement.style.top = '0px';
    document.body.appendChild( stats.domElement );

    // main loop
    var timer = new Timer();
    function animate() {
        stats.update();
        var dt = timer.update();
        game.update(dt);
    }
    var loop = new Loop(animate);

    // asset loading
    queue()
        .defer(loadLevel, 0, '0_tutorial.json')
        .defer(loadLevel, 1, '1_movingtank.json')
        .defer(loadLevel, 2, '2_multipletanks.json')
        .defer(loadLevel, 3, '3_grid.json')
        .defer(loadLevel, 4, '4_hunter.json')
        .defer(loadLevel, 5, '5_borderline.json')
        .defer(loadLevel, 6, '6_hunter2.json')
        .defer(loadLevel, 7, '7_demo.json')
        .defer(loadImage, "tileset.png")
        .defer(loadImage, "tank.png")
        .defer(loadImage, "turret.png")
        .defer(loadImage, "bullet.png")
        .defer(loadImage, "target.png")
        .await(function(error) {
            if(error) {
                console.error("error while loading", error);
            } else {
                console.log(arguments[1]);
                game.prepare();
                loop.start();
            }
        });
};
<|endoftext|>


<commit_before>const express = require('express')
const router = express.Router()

router.get('/', (request, response) => {
  response.set('content-type', 'text/plain')
  response.status(200).send('Welcome to Sandbox!')
})

router.get('/search', (request, response) => {
  if ('q' in request.query) {
    response.set('content-type', 'text/plain')
    response.status(200).send(`You searched for: "${request.query.q}"`)
  } else {
    response.set('content-type', 'text/plain')
    response.status(400).send("You didn't provide a search query term :(")
  }
})

router.post('/things', (request, response) => {
  response.status(201)
    .set('content-type', 'text/plain')
      .send('New thing created: flying car!')
})

router.get('/somefile', (request, response) => {
  response.set('content-type', 'text/plain')
    response.status(200).send('This is a plain text file')
})

router.get('/somefiles', (request, response) => {
  response.set('content-type', 'text/html')
    response.status(200).send('<!DOCTYPE html>This is an HTML file')
})

router.post('/admin-only', (request, response) => {
  response.status(403).end();
})

router.get('/not-a-page', (request, response) => {
  response.status(404).end();
})

router.get('/server-error', (request, response) => {
  response.status(500).end();
})

// Add other routes here

module.exports = router
<commit_msg>add json route and data back<commit_after>const express = require('express')
const router = express.Router()

router.get('/', (request, response) => {
  response.set('content-type', 'text/plain')
  response.status(200).send('Welcome to Sandbox!')
})

router.get('/search', (request, response) => {
  if ('q' in request.query) {
    response.set('content-type', 'text/plain')
    response.status(200).send(`You searched for: "${request.query.q}"`)
  } else {
    response.set('content-type', 'text/plain')
    response.status(400).send("You didn't provide a search query term :(")
  }
})

router.post('/things', (request, response) => {
  response.status(201)
    .set('content-type', 'text/plain')
      .send('New thing created: flying car!')
})

router.get('/somefile', (request, response) => {
  response.set('content-type', 'text/plain')
    response.status(200).send('This is a plain text file')
})

router.get('/somefiles', (request, response) => {
  response.set('content-type', 'text/html')
    response.status(200).send('<!DOCTYPE html>This is an HTML file')
})

router.get('/myjsondata', function(request, response) {
  response.set('content-type', 'application/json')
    response.status(200).send({"title":"some JSON data"})
})

router.post('/admin-only', (request, response) => {
  response.status(403).end();
})

router.get('/not-a-page', (request, response) => {
  response.status(404).end();
})

router.get('/server-error', (request, response) => {
  response.status(500).end();
})

// Add other routes here

module.exports = router
<|endoftext|>


<commit_before>if (typeof module !== 'undefined') {
    // In Node load required modules
    var assert = require('chai').assert;
    var evalScheem = require('./scheem.js').evalScheem;
    var parse = require('./parser.js').scheem.parse;
} else {
    // In browser assume loaded by <script>
    var parse = scheem.parse;
    var assert = chai.assert;
}

suite('quote', function() {
    test('a number', function() {
        assert.deepEqual(
            evalScheem(['quote', 3], {}),
            3
        );
    });
    test('an atom', function() {
        assert.deepEqual(
            evalScheem(['quote', 'dog'], {}),
            'dog'
        );
    });
    test('a list', function() {
        assert.deepEqual(
            evalScheem(['quote', [1, 2, 3]], {}),
            [1, 2, 3]
        );
    });
});
<commit_msg>removed redundant evalScheemTest.js<commit_after><|endoftext|>


<commit_before>var SlackClient = require('@slack/client').RtmClient;
var CLIENT_EVENTS = require('@slack/client').CLIENT_EVENTS;
var RTM_CLIENT_EVENTS = require('@slack/client').CLIENT_EVENTS.RTM;
var RTM_EVENTS = require('@slack/client').RTM_EVENTS;
var pg = require('pg');
var config = require('./config');
var orm = require("orm");

var token = process.env.SLACK_API || config.slack;
var dbURL = process.env.DATABASE_URL || config.db.url;
var client = new SlackClient(token);
var botId;
var GameDB;

////////////////////////////////////////////////////
// Startup
////////////////////////////////////////////////////

orm.connect(dbURL, function (err, db) {
  if (err) throw err;

  GameDB = db.define("game", {
      id        : { type: 'serial', key: true },
      channelId  : String,
      numPlayers: Number, // max 8
      player1   : String,
      player2   : String,
      player3   : String,
      player4   : String,
      player5   : String,
      player6   : String,
      player7   : String,
      player8   : String,
      currentTurn   : Number, // 1-14 14 is game over
      currentPlayer : Number,
      currentRoll   : Number,
      currentRoll1  : Number,
      currentRoll2  : Number,
      currentRoll3  : Number,
      currentRoll4  : Number,
      currentRoll5  : Number

    }, {
        methods: {
            fullName: function () {
                return this.id;
            }
        },
        validations: {
        }
    });

    // add the table to the database
  db.sync(function(err) {
      if (err) throw err;
  });
});

client.start();

////////////////////////////////////////////////////
// Client Events
////////////////////////////////////////////////////

client.on(CLIENT_EVENTS.RTM.AUTHENTICATED, function (rtmStartData) {
  if(rtmStartData["ok"] === true){
    botId = rtmStartData.self.id;
  }
});

client.on(RTM_CLIENT_EVENTS.RTM_CONNECTION_OPENED, function () {

});

////////////////////////////////////////////////////
// RTM Events
////////////////////////////////////////////////////

client.on(RTM_EVENTS.MESSAGE, function (message) {
  // Listens to all `message` events from the team

  // start game with list of users in turn order in channel
  if(message.type === 'message' && message.text.indexOf(botId) > -1)
  {
    var prefix = '<@' + botId + '>: ';
    // Start game
    if(message.text.indexOf(prefix + 'start') > -1){
      var commandLength = (prefix + 'start').length;
      var params = message.text.substr(commandLength, message.text.length-commandLength).trim();

      //find if there's already a game
      GameDB.find({ channelId: message.channel }, function (err, games) {
        if (err) throw err;

        if(games.length === 0 || games[0].currentTurn === 14){ // or end game turn is 14
          if(games.length > 0){
            // Delete old games..
            GameDB.find({ channelId: message.channel }).remove();
          }

          var players = params.split(" ");

          if(players.length > 1 && players.length < 9){
            GameDB.create(
              {
                channelId: message.channel,
                numPlayers: players.length,
                player1: players[0],
                player2: players.length >= 2 ? players[1] : '',
                player3: players.length >= 3 ? players[2] : '',
                player4: players.length >= 4 ? players[3] : '',
                player5: players.length >= 5 ? players[4] : '',
                player6: players.length >= 6 ? players[5] : '',
                player7: players.length >= 7 ? players[6] : '',
                player8: players.length >= 8 ? players[7] : '',
                currentTurn: 0,
                currentPlayer: 0,
                currentRoll: 0
              },
              function(err) {
                if (err) throw err;
                client.sendMessage('Starting game...', message.channel);

                GameDB.find({ channelId: message.channel, currentTurn: 0 }, function (err, games) {
                  if (err) throw err;

                  if (games.length > 0){
                    notifyNextPlayer(games[0], client);
                  }
                });
              }
            );
          }else{
            client.sendMessage('Too many or too few players... must be 1 or less than 8', message.channel);
          }
        }else{
          client.sendMessage('Game in progress!', message.channel);
        }
      });
    }
    // Turn Roll logic
    else if(message.text.indexOf(prefix + 'roll') > -1){
      var commandLength = (prefix + 'roll').length;
      var params = message.text.substr(commandLength, message.text.length-commandLength).trim();
      GameDB.find({ channelId: message.channel, currentTurn: 0 }, function (err, games) {
        if (err) throw err;

        if(games.length < 1)
          return;

        var userId = '<@' + message.user + '>';
        var playerId = '';

        if(games[0].currentPlayer == 1){
          playerId = games[0].player1;
        }else if (games[0].currentPlayer == 2){
          playerId = games[0].player2;
        }else if (games[0].currentPlayer == 3){
          playerId = games[0].player3;
        }else if (games[0].currentPlayer == 4){
          playerId = games[0].player4;
        }else if (games[0].currentPlayer == 5){
          playerId = games[0].player5;
        }else if (games[0].currentPlayer == 6){
          playerId = games[0].player6;
        }else if (games[0].currentPlayer == 7){
          playerId = games[0].player7;
        }else if (games[0].currentPlayer == 8){
          playerId = games[0].player8;
        }

        if(playerId === userId){
          // count unused dice spots
          var count = games[0].currentRoll1 === 0 ? 1 : 0;
          count = games[0].currentRoll2 === 0? count + 1 : count;
          count = games[0].currentRoll3 === 0? count + 1 : count;
          count = games[0].currentRoll4 === 0? count + 1 : count;
          count = games[0].currentRoll5 === 0? count + 1 : count;

          games[0].currentRoll = games[0].currentRoll + 1;

          var dice = rollDice(count);
          console.log(dice);

          for (var i =0; i<count; i++){
            if(5-count+i === 4){
              games[0].currentRoll5 = dice[i];
            }else if(5-count+i === 3){
              games[0].currentRoll4 = dice[i];
            }else if(5-count+i === 2){
              games[0].currentRoll3 = dice[i];
            }else if(5-count+i === 1){
              games[0].currentRoll2 = dice[i];
            }else if(5-count+i === 0){
              games[0].currentRoll1 = dice[i];
            }
          }
          client.sendMessage('Current hand: *' + games[0].currentRoll1 + ' '
            + games[0].currentRoll2 + ' '
            + games[0].currentRoll3 + ' '
            + games[0].currentRoll4 + ' '
            + games[0].currentRoll5
            + '*', message.channel);
          games[0].save();

          if(games[0].currentRoll === 4){
            notifyNextPlayer(games[0], client)
          }

        }
      });
    }
    // Keep Roll logic
    else if(message.text.indexOf(prefix + 'keep') > -1){
      var commandLength = (prefix + 'roll').length;
      var params = message.text.substr(commandLength, message.text.length-commandLength).trim();
      GameDB.find({ channelId: message.channel, currentTurn: 0 }, function (err, games) {
        if (err) throw err;

        if(games.length < 1)
          return;

        var userId = '<@' + message.user + '>';
        var playerId = '';

        if(games[0].currentPlayer == 1){
          playerId = games[0].player1;
        }else if (games[0].currentPlayer == 2){
          playerId = games[0].player2;
        }else if (games[0].currentPlayer == 3){
          playerId = games[0].player3;
        }else if (games[0].currentPlayer == 4){
          playerId = games[0].player4;
        }else if (games[0].currentPlayer == 5){
          playerId = games[0].player5;
        }else if (games[0].currentPlayer == 6){
          playerId = games[0].player6;
        }else if (games[0].currentPlayer == 7){
          playerId = games[0].player7;
        }else if (games[0].currentPlayer == 8){
          playerId = games[0].player8;
        }

        if(playerId === userId){
          // count unused dice spots
          var nums = params.split(' ').join('').split('').map(function(item) {
            return parseInt(item, 10);
          });

          // array of current rolls
          var rolls = [games[0].currentRoll1,games[0].currentRoll2,
            games[0].currentRoll3,games[0].currentRoll4,games[0].currentRoll5];
          var keep = [];

          console.log(nums);
          console.log(rolls);
          var count = 0;
          while(count < nums.length){
            if(rolls.indexOf(nums[count]) < 0){
              client.sendMessage('Bad Keep. Try again.', message.channel);
              return;
            }
            else {
              keep.push(nums[count]);
              rolls[rolls.indexOf(nums[count])] = 0;
            }
            count++;
          }
          keep.sort();
          console.log(keep);

          games[0].currentRoll1 = 0;
          games[0].currentRoll2 = 0;
          games[0].currentRoll3 = 0;
          games[0].currentRoll4 = 0;
          games[0].currentRoll5 = 0;
          for (var i =0; i<keep.length; i++){
            if(i === 4){
              games[0].currentRoll5 = keep[i];
            }else if(i === 3){
              games[0].currentRoll4 = keep[i];
            }else if(i === 2){
              games[0].currentRoll3 = keep[i];
            }else if(i === 1){
              games[0].currentRoll2 = keep[i];
            }else if(i === 0){
              games[0].currentRoll1 = keep[i];
            }
          }
          games[0].save();
          client.sendMessage('Keeping: *' + keep.join(' ') + '*... Roll again.', message.channel);
        }
      });
    }
    // Display help
    else if(message.text.indexOf(prefix + 'help') > -1){
      // send command info
      client.sendMessage('this is a test message', message.channel, function () {
        // optionally, you can supply a callback to execute once the message has been sent
      });
    }
  }
});

////////////////////////////////////////////////////
// Helper Functions
////////////////////////////////////////////////////

function rollDice(count) {
  var dice = [];
  for (var i = 0; i < Math.min(5, Math.max(1, count)); i++) {
      dice.push(getRandomIntInclusive(1, 6));
  }
  return dice.sort();
}

function getRandomIntInclusive(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function notifyNextPlayer(game, client){
  var playerId = '';
  game.currentTurn = game.currentPlayer < game.numPlayers ? game.currentTurn : game.currentTurn + 1;
  game.currentRoll = 1;
  game.currentPlayer = game.currentPlayer < game.numPlayers ? game.currentPlayer + 1 : 1;
  game.currentRoll1 = 0;
  game.currentRoll2 = 0;
  game.currentRoll3 = 0;
  game.currentRoll4 = 0;
  game.currentRoll5 = 0;
  game.save();

  if(game.currentTurn === 14){
    client.sendMessage('GAME OVER', game.channelId);
    game.remove()
  }

  if(game.currentPlayer == 1){
    playerId = game.player1;
  }else if (game.currentPlayer == 2){
    playerId = game.player2;
  }else if (game.currentPlayer == 3){
    playerId = game.player3;
  }else if (game.currentPlayer == 4){
    playerId = game.player4;
  }else if (game.currentPlayer == 5){
    playerId = game.player5;
  }else if (game.currentPlayer == 6){
    playerId = game.player6;
  }else if (game.currentPlayer == 7){
    playerId = game.player7;
  }else if (game.currentPlayer == 8){
    playerId = game.player8;
  }
  client.sendMessage(playerId + ' it\'s your turn!', game.channelId);
}

<commit_msg>fixing end game<commit_after>var SlackClient = require('@slack/client').RtmClient;
var CLIENT_EVENTS = require('@slack/client').CLIENT_EVENTS;
var RTM_CLIENT_EVENTS = require('@slack/client').CLIENT_EVENTS.RTM;
var RTM_EVENTS = require('@slack/client').RTM_EVENTS;
var pg = require('pg');
var config = require('./config');
var orm = require("orm");

var token = process.env.SLACK_API || config.slack;
var dbURL = process.env.DATABASE_URL || config.db.url;
var client = new SlackClient(token);
var botId;
var GameDB;

////////////////////////////////////////////////////
// Startup
////////////////////////////////////////////////////

orm.connect(dbURL, function (err, db) {
  if (err) throw err;

  GameDB = db.define("game", {
      id        : { type: 'serial', key: true },
      channelId  : String,
      numPlayers: Number, // max 8
      player1   : String,
      player2   : String,
      player3   : String,
      player4   : String,
      player5   : String,
      player6   : String,
      player7   : String,
      player8   : String,
      currentTurn   : Number, // 1-14 14 is game over
      currentPlayer : Number,
      currentRoll   : Number,
      currentRoll1  : Number,
      currentRoll2  : Number,
      currentRoll3  : Number,
      currentRoll4  : Number,
      currentRoll5  : Number

    }, {
        methods: {
            fullName: function () {
                return this.id;
            }
        },
        validations: {
        }
    });

    // add the table to the database
  db.sync(function(err) {
      if (err) throw err;
  });
});

client.start();

////////////////////////////////////////////////////
// Client Events
////////////////////////////////////////////////////

client.on(CLIENT_EVENTS.RTM.AUTHENTICATED, function (rtmStartData) {
  if(rtmStartData["ok"] === true){
    botId = rtmStartData.self.id;
  }
});

client.on(RTM_CLIENT_EVENTS.RTM_CONNECTION_OPENED, function () {

});

////////////////////////////////////////////////////
// RTM Events
////////////////////////////////////////////////////

client.on(RTM_EVENTS.MESSAGE, function (message) {
  // Listens to all `message` events from the team

  // start game with list of users in turn order in channel
  if(message.type === 'message' && message.text.indexOf(botId) > -1)
  {
    var prefix = '<@' + botId + '>: ';
    // Start game
    if(message.text.indexOf(prefix + 'start') > -1){
      var commandLength = (prefix + 'start').length;
      var params = message.text.substr(commandLength, message.text.length-commandLength).trim();

      //find if there's already a game
      GameDB.find({ channelId: message.channel }, function (err, games) {
        if (err) throw err;

        if(games.length === 0 || games[0].currentTurn === 14){ // or end game turn is 14
          if(games.length > 0){
            // Delete old games..
            GameDB.find({ channelId: message.channel }).remove();
          }

          var players = params.split(" ");

          if(players.length > 1 && players.length < 9){
            GameDB.create(
              {
                channelId: message.channel,
                numPlayers: players.length,
                player1: players[0],
                player2: players.length >= 2 ? players[1] : '',
                player3: players.length >= 3 ? players[2] : '',
                player4: players.length >= 4 ? players[3] : '',
                player5: players.length >= 5 ? players[4] : '',
                player6: players.length >= 6 ? players[5] : '',
                player7: players.length >= 7 ? players[6] : '',
                player8: players.length >= 8 ? players[7] : '',
                currentTurn: 0,
                currentPlayer: 0,
                currentRoll: 0
              },
              function(err) {
                if (err) throw err;
                client.sendMessage('Starting game...', message.channel);

                GameDB.find({ channelId: message.channel, currentTurn: 0 }, function (err, games) {
                  if (err) throw err;

                  if (games.length > 0){
                    notifyNextPlayer(games[0], client);
                  }
                });
              }
            );
          }else{
            client.sendMessage('Too many or too few players... must be 1 or less than 8', message.channel);
          }
        }else{
          client.sendMessage('Game in progress!', message.channel);
        }
      });
    }
    // Turn Roll logic
    else if(message.text.indexOf(prefix + 'roll') > -1){
      var commandLength = (prefix + 'roll').length;
      var params = message.text.substr(commandLength, message.text.length-commandLength).trim();
      GameDB.find({ channelId: message.channel, currentTurn: 0 }, function (err, games) {
        if (err) throw err;

        if(games.length < 1)
          return;

        var userId = '<@' + message.user + '>';
        var playerId = '';

        if(games[0].currentPlayer == 1){
          playerId = games[0].player1;
        }else if (games[0].currentPlayer == 2){
          playerId = games[0].player2;
        }else if (games[0].currentPlayer == 3){
          playerId = games[0].player3;
        }else if (games[0].currentPlayer == 4){
          playerId = games[0].player4;
        }else if (games[0].currentPlayer == 5){
          playerId = games[0].player5;
        }else if (games[0].currentPlayer == 6){
          playerId = games[0].player6;
        }else if (games[0].currentPlayer == 7){
          playerId = games[0].player7;
        }else if (games[0].currentPlayer == 8){
          playerId = games[0].player8;
        }

        if(playerId === userId){
          // count unused dice spots
          var count = games[0].currentRoll1 === 0 ? 1 : 0;
          count = games[0].currentRoll2 === 0? count + 1 : count;
          count = games[0].currentRoll3 === 0? count + 1 : count;
          count = games[0].currentRoll4 === 0? count + 1 : count;
          count = games[0].currentRoll5 === 0? count + 1 : count;

          games[0].currentRoll = games[0].currentRoll + 1;

          var dice = rollDice(count);
          console.log(dice);

          for (var i =0; i<count; i++){
            if(5-count+i === 4){
              games[0].currentRoll5 = dice[i];
            }else if(5-count+i === 3){
              games[0].currentRoll4 = dice[i];
            }else if(5-count+i === 2){
              games[0].currentRoll3 = dice[i];
            }else if(5-count+i === 1){
              games[0].currentRoll2 = dice[i];
            }else if(5-count+i === 0){
              games[0].currentRoll1 = dice[i];
            }
          }
          client.sendMessage('Current hand: *' + games[0].currentRoll1 + ' '
            + games[0].currentRoll2 + ' '
            + games[0].currentRoll3 + ' '
            + games[0].currentRoll4 + ' '
            + games[0].currentRoll5
            + '*', message.channel);
          games[0].save();

          if(games[0].currentRoll === 4){
            notifyNextPlayer(games[0], client)
          }

        }
      });
    }
    // Keep Roll logic
    else if(message.text.indexOf(prefix + 'keep') > -1){
      var commandLength = (prefix + 'roll').length;
      var params = message.text.substr(commandLength, message.text.length-commandLength).trim();
      GameDB.find({ channelId: message.channel, currentTurn: 0 }, function (err, games) {
        if (err) throw err;

        if(games.length < 1)
          return;

        var userId = '<@' + message.user + '>';
        var playerId = '';

        if(games[0].currentPlayer == 1){
          playerId = games[0].player1;
        }else if (games[0].currentPlayer == 2){
          playerId = games[0].player2;
        }else if (games[0].currentPlayer == 3){
          playerId = games[0].player3;
        }else if (games[0].currentPlayer == 4){
          playerId = games[0].player4;
        }else if (games[0].currentPlayer == 5){
          playerId = games[0].player5;
        }else if (games[0].currentPlayer == 6){
          playerId = games[0].player6;
        }else if (games[0].currentPlayer == 7){
          playerId = games[0].player7;
        }else if (games[0].currentPlayer == 8){
          playerId = games[0].player8;
        }

        if(playerId === userId){
          // count unused dice spots
          var nums = params.split(' ').join('').split('').map(function(item) {
            return parseInt(item, 10);
          });

          // array of current rolls
          var rolls = [games[0].currentRoll1,games[0].currentRoll2,
            games[0].currentRoll3,games[0].currentRoll4,games[0].currentRoll5];
          var keep = [];

          console.log(nums);
          console.log(rolls);
          var count = 0;
          while(count < nums.length){
            if(rolls.indexOf(nums[count]) < 0){
              client.sendMessage('Bad Keep. Try again.', message.channel);
              return;
            }
            else {
              keep.push(nums[count]);
              rolls[rolls.indexOf(nums[count])] = 0;
            }
            count++;
          }
          keep.sort();
          console.log(keep);

          games[0].currentRoll1 = 0;
          games[0].currentRoll2 = 0;
          games[0].currentRoll3 = 0;
          games[0].currentRoll4 = 0;
          games[0].currentRoll5 = 0;
          for (var i =0; i<keep.length; i++){
            if(i === 4){
              games[0].currentRoll5 = keep[i];
            }else if(i === 3){
              games[0].currentRoll4 = keep[i];
            }else if(i === 2){
              games[0].currentRoll3 = keep[i];
            }else if(i === 1){
              games[0].currentRoll2 = keep[i];
            }else if(i === 0){
              games[0].currentRoll1 = keep[i];
            }
          }
          games[0].save();
          client.sendMessage('Keeping: *' + keep.join(' ') + '*... Roll again.', message.channel);
        }
      });
    }
    // Display help
    else if(message.text.indexOf(prefix + 'help') > -1){
      // send command info
      client.sendMessage('this is a test message', message.channel, function () {
        // optionally, you can supply a callback to execute once the message has been sent
      });
    }
  }
});

////////////////////////////////////////////////////
// Helper Functions
////////////////////////////////////////////////////

function rollDice(count) {
  var dice = [];
  for (var i = 0; i < Math.min(5, Math.max(1, count)); i++) {
      dice.push(getRandomIntInclusive(1, 6));
  }
  return dice.sort();
}

function getRandomIntInclusive(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function notifyNextPlayer(game, client){
  var playerId = '';
  game.currentTurn = game.currentPlayer < game.numPlayers ? game.currentTurn : game.currentTurn + 1;
  game.currentRoll = 1;
  game.currentPlayer = game.currentPlayer < game.numPlayers ? game.currentPlayer + 1 : 1;
  game.currentRoll1 = 0;
  game.currentRoll2 = 0;
  game.currentRoll3 = 0;
  game.currentRoll4 = 0;
  game.currentRoll5 = 0;
  game.save();

  if(game.currentTurn === 13){
    client.sendMessage('GAME OVER', game.channelId);
    game.remove()
  }else {
    if(game.currentPlayer == 1){
      playerId = game.player1;
    }else if (game.currentPlayer == 2){
      playerId = game.player2;
    }else if (game.currentPlayer == 3){
      playerId = game.player3;
    }else if (game.currentPlayer == 4){
      playerId = game.player4;
    }else if (game.currentPlayer == 5){
      playerId = game.player5;
    }else if (game.currentPlayer == 6){
      playerId = game.player6;
    }else if (game.currentPlayer == 7){
      playerId = game.player7;
    }else if (game.currentPlayer == 8){
      playerId = game.player8;
    }
    client.sendMessage(playerId + ' it\'s your turn!', game.channelId);
  }
}

<|endoftext|>


<commit_before>#!/bin/env node
if (process.env.NODE_ENV === 'development') {
  require('dotenv').config();
}
var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');
var router = express.Router();
var fs      = require('fs');
var nodemailer = require('nodemailer');

/**
 *  Define the application.
 */
var SampleApp = function() {

    //  Scope.
    var self = this;

    /*  ================================================================  */
    /*  Helper functions.                                                 */
    /*  ================================================================  */

    /**
     *  Set up server IP address and port # using env variables/defaults.
     */
    self.setupVariables = function() {
        //  Set the environment variables we need.
        self.ipaddress = process.env.OPENSHIFT_NODEJS_IP ||
                         process.env.OPENSHIFT_INTERNAL_IP;
        self.port      = process.env.OPENSHIFT_NODEJS_PORT   ||
                         process.env.OPENSHIFT_INTERNAL_PORT || 8080;

        if (typeof self.ipaddress === "undefined") {
            //  Log errors on OpenShift but continue w/ 127.0.0.1 - this
            //  allows us to run/test the app locally.
            console.warn('No OPENSHIFT_*_IP var, using 127.0.0.1');
            self.ipaddress = "127.0.0.1";
        };
    };

    /**
     *  Populate the cache.
     */
    self.populateCache = function() {
        if (typeof self.zcache === "undefined") {
            self.zcache = { 'index.html': '' };
        }

        //  Local cache for static content.
        self.zcache['index.html'] = fs.readFileSync('./index.html');
    };

    /**
     *  Retrieve entry (content) from cache.
     *  @param {string} key  Key identifying content to retrieve from cache.
     */
    self.cache_get = function(key) { return self.zcache[key]; };

    /**
     *  terminator === the termination handler
     *  Terminate server on receipt of the specified signal.
     *  @param {string} sig  Signal to terminate on.
     */
    self.terminator = function(sig){
        if (typeof sig === "string") {
           console.log('%s: Received %s - terminating sample app ...',
                       Date(Date.now()), sig);
           process.exit(1);
        }
        console.log('%s: Node server stopped.', Date(Date.now()) );
    };

    /**
     *  Setup termination handlers (for exit and a list of signals).
     */
    self.setupTerminationHandlers = function(){
        //  Process on exit and signals.
        process.on('exit', function() { self.terminator(); });

        // Removed 'SIGPIPE' from the list - bugz 852598.
        ['SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT',
         'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGTERM'
        ].forEach(function(element, index, array) {
            process.on(element, function() { self.terminator(element); });
        });
    };

    /*  ================================================================  */
    /*  App server functions (main app logic here).                       */
    /*  ================================================================  */

    /**
     *  Create the routing table entries + handlers for the application.
     */
    self.createRoutes = function() {
        self.routes = { };

        // Routes for /health, /asciimo, /env and /
        self.routes['/health'] = function(req, res) {
            res.send('1');
        };

        self.routes['/asciimo'] = function(req, res) {
            var link = "http://i.imgur.com/kmbjB.png";
            res.send("");
        };

        self.routes['/env'] = function(req, res) {
            var content = 'Version: ' + process.version + '\n
\n' +
                          'Env: {
\n
';
            //  Add env entries.
            for (var k in process.env) {
               content += '   ' + k + ': ' + process.env[k] + '\n';
            }
            content += '}\n

\n'
            res.send('\n' +
                     '  <title>Node.js Process Env</title>\n' +
                     '  \n
\n' + content + '\n');
        };

        self.routes['/'] = function(req, res) {
            res.set('Content-Type', 'text/html');
            res.send(self.cache_get('index.html') );
        };
    };

    /**
     *  Initialize the server (express) and create the routes and register
     *  the handlers.
     */
    self.initializeServer = function() {
        self.createRoutes();
        self.app = express();
        self.app.use(bodyParser.json());

        //CORS middleware
        var allowCrossDomain = function(req, res, next) {
            res.header('Access-Control-Allow-Origin', '*');
            res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
            res.header('Access-Control-Allow-Headers', 'Content-Type');

            next();
        }

        self.app.use(allowCrossDomain);

        //  Add handlers for the app (from the routes).
        for (var r in self.routes) {
            self.app.get(r, self.routes[r]);
        }
        self.app.post('/', cors(), handleContactForm);
    };

    /**
     *  Initializes the sample application.
     */
    self.initialize = function() {
        self.setupVariables();
        self.populateCache();
        self.setupTerminationHandlers();

        // Create the express server and routes.
        self.initializeServer();
    };

    /**
     *  Start the server (starts up the sample application).
     */
    self.start = function() {
        //  Start the app on the specific interface (and port).
        self.app.listen(self.port, self.ipaddress, function() {
            console.log('%s: Node server started on %s:%d ...',
                        Date(Date.now() ), self.ipaddress, self.port);
        });
    };

};   /*  Sample Application.  */

function handleContactForm(req, res) {
  var transporter = nodemailer.createTransport({
    service: 'Gmail',
    auth: {
      user: process.env.EMAIL_USER,
      pass: process.env.EMAIL_PASSWORD
    }
  });

  var receivers = process.env.MAIN_RECIPIENT_EMAIL;

  var source = req.body.contactsource;
  if (source === 'badlandstaxsolutions.com') {
    console.log('SHOULD add Debbi\'s email');
    // receivers += ', ' + process.env.BADLANDS_EMAIL;
  }

  var contentHoneypot = req.body.content;

  if (contentHoneypot) {
    console.error('They filled out the honeypot, must be robots!');
  }

  var plainText = 'A visitor filled out your contact form:\n';
  plainText += 'Name: ' + req.body.name;
  plainText += 'Email: ' + req.body.email;
  plainText += 'Message: ' + req.body.message;

  var html = '
A visitor filled out your contact form:
';
  html += '
';
  html += '
Name: ' + req.body.name + '
';
  html += '
Email: ' + req.body.email + '
';
  html += '
Message: ' + req.body.message + '
';
  html += '
';

  // setup e-mail data with unicode symbols
  var mailOptions = {
    from: 'tsemcontact<tsemcontact@gmail.com>', // sender address
    to: receivers, // list of receivers
    subject: 'New contact message from ' + source,
    text: plainText,
    html: html
  };

  // send mail with defined transport object
  transporter.sendMail(mailOptions, function(error, info){
    if(error){
      return console.log(error);
    }
    console.log('Message sent: ' + info.response);
    return res.send('Message sent');
    // return res.end('hello,world\nkeesun,hi', 'UTF-8');
  });
}

/**
 *  main():  Main code.
 */
var zapp = new SampleApp();
zapp.initialize();
zapp.start();
<commit_msg>also use bodyParser.urlencode() now<commit_after>#!/bin/env node
if (process.env.NODE_ENV === 'development') {
  require('dotenv').config();
}
var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');
var router = express.Router();
var fs      = require('fs');
var nodemailer = require('nodemailer');

/**
 *  Define the application.
 */
var SampleApp = function() {

    //  Scope.
    var self = this;

    /*  ================================================================  */
    /*  Helper functions.                                                 */
    /*  ================================================================  */

    /**
     *  Set up server IP address and port # using env variables/defaults.
     */
    self.setupVariables = function() {
        //  Set the environment variables we need.
        self.ipaddress = process.env.OPENSHIFT_NODEJS_IP ||
                         process.env.OPENSHIFT_INTERNAL_IP;
        self.port      = process.env.OPENSHIFT_NODEJS_PORT   ||
                         process.env.OPENSHIFT_INTERNAL_PORT || 8080;

        if (typeof self.ipaddress === "undefined") {
            //  Log errors on OpenShift but continue w/ 127.0.0.1 - this
            //  allows us to run/test the app locally.
            console.warn('No OPENSHIFT_*_IP var, using 127.0.0.1');
            self.ipaddress = "127.0.0.1";
        };
    };

    /**
     *  Populate the cache.
     */
    self.populateCache = function() {
        if (typeof self.zcache === "undefined") {
            self.zcache = { 'index.html': '' };
        }

        //  Local cache for static content.
        self.zcache['index.html'] = fs.readFileSync('./index.html');
    };

    /**
     *  Retrieve entry (content) from cache.
     *  @param {string} key  Key identifying content to retrieve from cache.
     */
    self.cache_get = function(key) { return self.zcache[key]; };

    /**
     *  terminator === the termination handler
     *  Terminate server on receipt of the specified signal.
     *  @param {string} sig  Signal to terminate on.
     */
    self.terminator = function(sig){
        if (typeof sig === "string") {
           console.log('%s: Received %s - terminating sample app ...',
                       Date(Date.now()), sig);
           process.exit(1);
        }
        console.log('%s: Node server stopped.', Date(Date.now()) );
    };

    /**
     *  Setup termination handlers (for exit and a list of signals).
     */
    self.setupTerminationHandlers = function(){
        //  Process on exit and signals.
        process.on('exit', function() { self.terminator(); });

        // Removed 'SIGPIPE' from the list - bugz 852598.
        ['SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT',
         'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGTERM'
        ].forEach(function(element, index, array) {
            process.on(element, function() { self.terminator(element); });
        });
    };

    /*  ================================================================  */
    /*  App server functions (main app logic here).                       */
    /*  ================================================================  */

    /**
     *  Create the routing table entries + handlers for the application.
     */
    self.createRoutes = function() {
        self.routes = { };

        // Routes for /health, /asciimo, /env and /
        self.routes['/health'] = function(req, res) {
            res.send('1');
        };

        self.routes['/asciimo'] = function(req, res) {
            var link = "http://i.imgur.com/kmbjB.png";
            res.send("");
        };

        self.routes['/env'] = function(req, res) {
            var content = 'Version: ' + process.version + '\n
\n' +
                          'Env: {
\n
';
            //  Add env entries.
            for (var k in process.env) {
               content += '   ' + k + ': ' + process.env[k] + '\n';
            }
            content += '}\n

\n'
            res.send('\n' +
                     '  <title>Node.js Process Env</title>\n' +
                     '  \n
\n' + content + '\n');
        };

        self.routes['/'] = function(req, res) {
            res.set('Content-Type', 'text/html');
            res.send(self.cache_get('index.html') );
        };
    };

    /**
     *  Initialize the server (express) and create the routes and register
     *  the handlers.
     */
    self.initializeServer = function() {
        self.createRoutes();
        self.app = express();
        self.app.use(bodyParser.json());
        self.app.use(bodyParser.urlencoded({ extended: false }));

        //CORS middleware
        var allowCrossDomain = function(req, res, next) {
            res.header('Access-Control-Allow-Origin', '*');
            res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
            res.header('Access-Control-Allow-Headers', 'Content-Type');

            next();
        }

        self.app.use(allowCrossDomain);

        //  Add handlers for the app (from the routes).
        for (var r in self.routes) {
            self.app.get(r, self.routes[r]);
        }
        self.app.post('/', cors(), handleContactForm);
    };

    /**
     *  Initializes the sample application.
     */
    self.initialize = function() {
        self.setupVariables();
        self.populateCache();
        self.setupTerminationHandlers();

        // Create the express server and routes.
        self.initializeServer();
    };

    /**
     *  Start the server (starts up the sample application).
     */
    self.start = function() {
        //  Start the app on the specific interface (and port).
        self.app.listen(self.port, self.ipaddress, function() {
            console.log('%s: Node server started on %s:%d ...',
                        Date(Date.now() ), self.ipaddress, self.port);
        });
    };

};   /*  Sample Application.  */

function handleContactForm(req, res) {
  var transporter = nodemailer.createTransport({
    service: 'Gmail',
    auth: {
      user: process.env.EMAIL_USER,
      pass: process.env.EMAIL_PASSWORD
    }
  });

  var receivers = process.env.MAIN_RECIPIENT_EMAIL;

  var source = req.body.contactsource;
  if (source === 'badlandstaxsolutions.com') {
    console.log('SHOULD add Debbi\'s email');
    // receivers += ', ' + process.env.BADLANDS_EMAIL;
  }

  var contentHoneypot = req.body.content;

  if (contentHoneypot) {
    console.error('They filled out the honeypot, must be robots!');
  }

  var plainText = 'A visitor filled out your contact form:\n';
  plainText += 'Name: ' + req.body.name;
  plainText += 'Email: ' + req.body.email;
  plainText += 'Message: ' + req.body.message;

  var html = '
A visitor filled out your contact form:
';
  html += '
';
  html += '
Name: ' + req.body.name + '
';
  html += '
Email: ' + req.body.email + '
';
  html += '
Message: ' + req.body.message + '
';
  html += '
';

  // setup e-mail data with unicode symbols
  var mailOptions = {
    from: 'tsemcontact<tsemcontact@gmail.com>', // sender address
    to: receivers, // list of receivers
    subject: 'New contact message from ' + source,
    text: plainText,
    html: html
  };

  // send mail with defined transport object
  transporter.sendMail(mailOptions, function(error, info){
    if(error){
      return console.log(error);
    }
    console.log('Message sent: ' + info.response);
    return res.send('Message sent');
    // return res.end('hello,world\nkeesun,hi', 'UTF-8');
  });
}

/**
 *  main():  Main code.
 */
var zapp = new SampleApp();
zapp.initialize();
zapp.start();
<|endoftext|>


<commit_before>var fs = require('fs')
  , express = require('express')
  , bodyParser = require('body-parser')
  , serveStatic = require('serve-static');
var app = express();
var port = 80;

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true}));
app.use(serveStatic('.'));
app.use(express.static('src'));

app.post('/question', function(req, res) {
  var a = fs.readFileSync(req.body.quest + '.json', 'utf8');
  // console.log(a);
  res.json(a);
});

app.listen(port, function() {
    console.log("listening http on port " + port)
});<commit_msg>ポート変更<commit_after>var fs = require('fs')
  , express = require('express')
  , bodyParser = require('body-parser')
  , serveStatic = require('serve-static');
var app = express();
var port = 8080;

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true}));
app.use(serveStatic('.'));
app.use(express.static('src'));

app.post('/question', function(req, res) {
  var a = fs.readFileSync(req.body.quest + '.json', 'utf8');
  // console.log(a);
  res.json(a);
});

app.listen(port, function() {
    console.log("listening http on port " + port)
});<|endoftext|>