<commit_before>import React, { useState, useEffect } from 'react';
import { c } from 'ttag';
import {
    Alert,
    Href,
    InlineLinkButton,
    Loader,
    Block,
    FormModal,
    PasswordTotpInputs,
    Button,
    useNotifications,
    useLoading,
    useAddresses,
    useUser,
    useApi,
    useEventManager
} from 'react-components';
import QRCode from 'qrcode.react';
import { generateSharedSecret, getUri } from 'proton-shared/lib/helpers/twofa';
import { setupTotp, TOTP_WRONG_ERROR } from 'proton-shared/lib/api/settings';
import { srpAuth } from 'proton-shared/lib/srp';
import { PASSWORD_WRONG_ERROR } from 'proton-shared/lib/api/auth';
import downloadFile from 'proton-shared/lib/helpers/downloadFile';
import { TWO_FA_CONFIG } from 'proton-shared/lib/constants';

const { PERIOD, DIGITS, ALGORITHM } = TWO_FA_CONFIG;

const STEPS = {
    INFO: 1,
    SCAN_CODE: 2,
    CONFIRM_CODE: 3,
    RECOVERY_CODES: 4
};

const EnableTwoFactorModal = (props) => {
    const [addresses] = useAddresses();
    const [user] = useUser();
    const api = useApi();
    const { call } = useEventManager();
    const { createNotification } = useNotifications();
    const [{ sharedSecret, uri = '' }, setTotpData] = useState({});
    const [step, setStep] = useState(STEPS.INFO);
    const [manualCode, setManualCode] = useState(false);
    const [recoveryCodes, setRecoveryCodes] = useState([]);
    const [password, setPassword] = useState('');
    const [totp, setTotp] = useState('');
    const [passwordError, setPasswordError] = useState('');
    const [totpError, setTotpError] = useState('');
    const [loading, withLoading] = useLoading();

    useEffect(() => {
        if (!Array.isArray(addresses) || sharedSecret) {
            return;
        }

        const generatedSharedSecret = generateSharedSecret();
        const primaryAddress = addresses.find(({ Keys = [] }) => Keys.length > 0);
        const identifier = (primaryAddress && primaryAddress.Email) || `${user.Name}@protonmail`;

        setTotpData({
            uri: getUri({
                identifier,
                sharedSecret: generatedSharedSecret,
                period: PERIOD,
                digits: DIGITS,
                algorithm: ALGORITHM
            }),
            sharedSecret: generatedSharedSecret
        });
    }, [addresses]);

    const { section, ...modalProps } = (() => {
        if (!sharedSecret) {
            return {
                section: <Loader />
            };
        }

        if (step === STEPS.INFO) {
            const guideButton = (
                <Href key="0" url="https://protonmail.com/support/knowledge-base/two-factor-authentication/">{c('Info')
                    .t`reading our 2FA Guide first`}</Href>
            );

            return {
                section: (
                    <>
                        <Block>
                            {c('Info')
                                .t`This wizard will enable Two Factor Authentication (2FA) on your ProtonMail account. 2FA will make your ProtonMail account more secure so we recommend enabling it.`}
                        </Block>
                        <Alert>
                            {c('Info').jt`If you have never used 2FA before, we strongly recommend you ${guideButton}.`}
                        </Alert>
                    </>
                ),
                onSubmit() {
                    setStep(STEPS.SCAN_CODE);
                }
            };
        }

        const handleSubmitScan = () => {
            setStep(STEPS.CONFIRM_CODE);
        };

        if (step === STEPS.SCAN_CODE && !manualCode) {
            const switchButton = (
                <InlineLinkButton key="0" onClick={() => setManualCode(true)}>
                    {c('Info').t`Enter key manually instead`}
                </InlineLinkButton>
            );

            return {
                section: (
                    <>
                        <Alert>
                            {c('Info')
                                .jt`Scan this code with your two-factor authentication device to set up your account. ${switchButton}.`}
                        </Alert>

                            <QRCode value={uri} size={200} includeMargin={false} renderAs={'svg'} />

                    </>
                ),
                onSubmit: handleSubmitScan
            };
        }

        if (step === STEPS.SCAN_CODE && manualCode) {
            const switchButton = (
                <InlineLinkButton key="0" onClick={() => setManualCode(false)}>
                    {c('Info').t`Scan QR code instead`}
                </InlineLinkButton>
            );

            return {
                section: (
                    <>
                        <Alert>
                            {c('Info')
                                .jt`Manually enter this information into your two-factor authentication device to set up your account. ${switchButton}.`}
                        </Alert>

{c('Label').t`Key`}

                                    {sharedSecret}

{c('Label').t`Interval`}

                                    {PERIOD}

{c('Label').t`Digits`}

                                    {DIGITS}

                    </>
                ),
                onSubmit: handleSubmitScan
            };
        }

        if (step === STEPS.CONFIRM_CODE) {
            const handleSubmit = async () => {
                try {
                    const { TwoFactorRecoveryCodes } = await srpAuth({
                        api,
                        credentials: { password },
                        config: setupTotp(sharedSecret, totp)
                    });
                    await call();
                    createNotification({ text: c('Info').t`Two-factor authentication enabled` });
                    setRecoveryCodes(TwoFactorRecoveryCodes);
                    setStep(STEPS.RECOVERY_CODES);
                } catch (error) {
                    const { data: { Code, Error } = {} } = error;

                    setPasswordError();
                    setTotpError();

                    if (Code === PASSWORD_WRONG_ERROR) {
                        setPasswordError(Error);
                    }

                    if (Code === TOTP_WRONG_ERROR) {
                        setTotpError(Error);
                    }
                }
            };

            return {
                section: (
                    <PasswordTotpInputs
                        password={password}
                        setPassword={setPassword}
                        passwordError={passwordError}
                        totp={totp}
                        setTotp={setTotp}
                        totpError={totpError}
                        showTotp={true}
                    />
                ),
                close: <Button type="button" onClick={() => setStep(STEPS.SCAN_CODE)}>{c('Action').t`Back`}</Button>,
                onSubmit() {
                    withLoading(handleSubmit());
                },
                submit: c('Action').t`Submit`
            };
        }

        if (step === STEPS.RECOVERY_CODES) {
            return {
                section: (
                    <>
                        <Alert>
                            {c('Info')
                                .t`Important: Please make sure you save the recovery codes. Otherwise you can permanently lose access to your account if you lose your 2FA device.`}

                            {c('Info')
                                .t`If you lose your two-factor-enabled device, these codes can be used instead of the 6-digit 2FA code to log into your account. Each code can only be used once.`}
                        </Alert>

                            {recoveryCodes.map((code) => {
                                return (

                                        {code}

                                );
                            })}

                            <Button
                                onClick={() => {
                                    const blob = new Blob([recoveryCodes.join('\r\n')], {
                                        type: 'text/plain;charset=utf-8;'
                                    });
                                    const filename = 'protonmail_recovery_codes.txt';
                                    downloadFile(blob, filename);
                                }}
                            >
                                {c('Action').t`Download`}
                            </Button>

                    </>
                ),
                onSubmit() {
                    props.onClose();
                },
                submit: c('Action').t`Ok`
            };
        }
    })();

    return (
        <FormModal
            title={c('Title').t`Set up two-factor authentication`}
            submit={c('Action').t`Next`}
            loading={loading}
            {...props}
            {...modalProps}
        >
            {section}
        </FormModal>
    );
};

export default EnableTwoFactorModal;
<commit_msg>Fix https://github.com/ProtonMail/protonvpn-settings/issues/17<commit_after>import React, { useState, useEffect } from 'react';
import { c } from 'ttag';
import {
    Alert,
    Href,
    InlineLinkButton,
    Loader,
    Block,
    FormModal,
    PasswordTotpInputs,
    Button,
    useNotifications,
    useLoading,
    useAddresses,
    useUser,
    useApi,
    useEventManager
} from 'react-components';
import QRCode from 'qrcode.react';
import { generateSharedSecret, getUri } from 'proton-shared/lib/helpers/twofa';
import { setupTotp, TOTP_WRONG_ERROR } from 'proton-shared/lib/api/settings';
import { srpAuth } from 'proton-shared/lib/srp';
import { PASSWORD_WRONG_ERROR } from 'proton-shared/lib/api/auth';
import downloadFile from 'proton-shared/lib/helpers/downloadFile';
import { TWO_FA_CONFIG } from 'proton-shared/lib/constants';

const { PERIOD, DIGITS, ALGORITHM } = TWO_FA_CONFIG;

const STEPS = {
    INFO: 1,
    SCAN_CODE: 2,
    CONFIRM_CODE: 3,
    RECOVERY_CODES: 4
};

const EnableTwoFactorModal = (props) => {
    const [addresses] = useAddresses();
    const [user] = useUser();
    const api = useApi();
    const { call } = useEventManager();
    const { createNotification } = useNotifications();
    const [{ sharedSecret, uri = '' }, setTotpData] = useState({});
    const [step, setStep] = useState(STEPS.INFO);
    const [manualCode, setManualCode] = useState(false);
    const [recoveryCodes, setRecoveryCodes] = useState([]);
    const [password, setPassword] = useState('');
    const [totp, setTotp] = useState('');
    const [passwordError, setPasswordError] = useState('');
    const [totpError, setTotpError] = useState('');
    const [loading, withLoading] = useLoading();

    useEffect(() => {
        if (!Array.isArray(addresses) || sharedSecret) {
            return;
        }

        const generatedSharedSecret = generateSharedSecret();
        const primaryAddress = addresses.find(({ Keys = [] }) => Keys.length > 0);
        const identifier = (primaryAddress && primaryAddress.Email) || `${user.Name}@protonmail`;

        setTotpData({
            uri: getUri({
                identifier,
                sharedSecret: generatedSharedSecret,
                period: PERIOD,
                digits: DIGITS,
                algorithm: ALGORITHM
            }),
            sharedSecret: generatedSharedSecret
        });
    }, [addresses]);

    const { section, ...modalProps } = (() => {
        if (!sharedSecret) {
            return {
                section: <Loader />
            };
        }

        if (step === STEPS.INFO) {
            const guideButton = (
                <Href key="0" url="https://protonmail.com/support/knowledge-base/two-factor-authentication/">{c('Info')
                    .t`reading our 2FA Guide first`}</Href>
            );

            return {
                section: (
                    <>
                        <Block>
                            {c('Info')
                                .t`This wizard will enable Two Factor Authentication (2FA) on your Proton account. 2FA will make your Proton account more secure so we recommend enabling it.`}
                        </Block>
                        <Alert>
                            {c('Info').jt`If you have never used 2FA before, we strongly recommend you ${guideButton}.`}
                        </Alert>
                    </>
                ),
                onSubmit() {
                    setStep(STEPS.SCAN_CODE);
                }
            };
        }

        const handleSubmitScan = () => {
            setStep(STEPS.CONFIRM_CODE);
        };

        if (step === STEPS.SCAN_CODE && !manualCode) {
            const switchButton = (
                <InlineLinkButton key="0" onClick={() => setManualCode(true)}>
                    {c('Info').t`Enter key manually instead`}
                </InlineLinkButton>
            );

            return {
                section: (
                    <>
                        <Alert>
                            {c('Info')
                                .jt`Scan this code with your two-factor authentication device to set up your account. ${switchButton}.`}
                        </Alert>

                            <QRCode value={uri} size={200} includeMargin={false} renderAs={'svg'} />

                    </>
                ),
                onSubmit: handleSubmitScan
            };
        }

        if (step === STEPS.SCAN_CODE && manualCode) {
            const switchButton = (
                <InlineLinkButton key="0" onClick={() => setManualCode(false)}>
                    {c('Info').t`Scan QR code instead`}
                </InlineLinkButton>
            );

            return {
                section: (
                    <>
                        <Alert>
                            {c('Info')
                                .jt`Manually enter this information into your two-factor authentication device to set up your account. ${switchButton}.`}
                        </Alert>

{c('Label').t`Key`}

                                    {sharedSecret}

{c('Label').t`Interval`}

                                    {PERIOD}

{c('Label').t`Digits`}

                                    {DIGITS}

                    </>
                ),
                onSubmit: handleSubmitScan
            };
        }

        if (step === STEPS.CONFIRM_CODE) {
            const handleSubmit = async () => {
                try {
                    const { TwoFactorRecoveryCodes } = await srpAuth({
                        api,
                        credentials: { password },
                        config: setupTotp(sharedSecret, totp)
                    });
                    await call();
                    createNotification({ text: c('Info').t`Two-factor authentication enabled` });
                    setRecoveryCodes(TwoFactorRecoveryCodes);
                    setStep(STEPS.RECOVERY_CODES);
                } catch (error) {
                    const { data: { Code, Error } = {} } = error;

                    setPasswordError();
                    setTotpError();

                    if (Code === PASSWORD_WRONG_ERROR) {
                        setPasswordError(Error);
                    }

                    if (Code === TOTP_WRONG_ERROR) {
                        setTotpError(Error);
                    }
                }
            };

            return {
                section: (
                    <PasswordTotpInputs
                        password={password}
                        setPassword={setPassword}
                        passwordError={passwordError}
                        totp={totp}
                        setTotp={setTotp}
                        totpError={totpError}
                        showTotp={true}
                    />
                ),
                close: <Button type="button" onClick={() => setStep(STEPS.SCAN_CODE)}>{c('Action').t`Back`}</Button>,
                onSubmit() {
                    withLoading(handleSubmit());
                },
                submit: c('Action').t`Submit`
            };
        }

        if (step === STEPS.RECOVERY_CODES) {
            return {
                section: (
                    <>
                        <Alert>
                            {c('Info')
                                .t`Important: Please make sure you save the recovery codes. Otherwise you can permanently lose access to your account if you lose your 2FA device.`}

                            {c('Info')
                                .t`If you lose your two-factor-enabled device, these codes can be used instead of the 6-digit 2FA code to log into your account. Each code can only be used once.`}
                        </Alert>

                            {recoveryCodes.map((code) => {
                                return (

                                        {code}

                                );
                            })}

                            <Button
                                onClick={() => {
                                    const blob = new Blob([recoveryCodes.join('\r\n')], {
                                        type: 'text/plain;charset=utf-8;'
                                    });
                                    const filename = 'protonmail_recovery_codes.txt';
                                    downloadFile(blob, filename);
                                }}
                            >
                                {c('Action').t`Download`}
                            </Button>

                    </>
                ),
                onSubmit() {
                    props.onClose();
                },
                submit: c('Action').t`Ok`
            };
        }
    })();

    return (
        <FormModal
            title={c('Title').t`Set up two-factor authentication`}
            submit={c('Action').t`Next`}
            loading={loading}
            {...props}
            {...modalProps}
        >
            {section}
        </FormModal>
    );
};

export default EnableTwoFactorModal;
<|endoftext|>


<commit_before>var GOL = (function (GOL) {

    GOL.Area = function(width, height)
    {
        this.width = width;
        this.height = height;
        this.cellsByCoordinates = new Map();
        this.coordinatesByCells = new Map();
        this.relativeNeighborLocation = [
            [-1, -1], [0, -1], [1, -1],
            [-1, 0], [1, 0],
            [-1, 1], [0, 1], [1, 1]
        ];
    };

    GOL.Area.prototype.addCell = function(cell, coordinates)
    {
        this.cellsByCoordinates.set(coordinates.getHash(), cell);
        this.coordinatesByCells.set(cell, coordinates);
    };

    GOL.Area.prototype.getCellWithCoordinates = function(coordinates)
    {
        return this.cellsByCoordinates.get(coordinates.getHash());
    };

    GOL.Area.prototype.getAllCells = function()
    {
        var cells = [];
        this.cellsByCoordinates.forEach(function (cell) { cells.push(cell); });
        return cells;
    };

    GOL.Area.prototype.getCoordinatesOf = function (cell)
    {
        return this.coordinatesByCells.get(cell);
    };

    GOL.Area.prototype.getNeighborsOf = function(cell)
    {
        var neighbors = [];
        var cellCoordinates = this.getCoordinatesOf(cell);
        var cellX = cellCoordinates.x;
        var cellY = cellCoordinates.y;
        var self = this;
        this.relativeNeighborLocation.forEach(function (neighborLocation) {
            var singleNeighbor = self.getCellWithCoordinates(new GOL.Coordinates(
                cellX + neighborLocation[0],
                cellY + neighborLocation[1]
            ));
            if (undefined !== singleNeighbor) {
                neighbors.push(singleNeighbor);
            }
        });

        return neighbors;
    };

    return GOL;
} (GOL || {}));
<commit_msg>Area refactor<commit_after>var GOL = (function (GOL) {

    GOL.Area = function(width, height)
    {
        this.width = width;
        this.height = height;
        this.cellsByCoordinates = new Map();
        this.coordinatesByCells = new Map();
        this.relativeNeighborLocation = [
            [-1, -1], [0, -1], [1, -1],
            [-1, 0], [1, 0],
            [-1, 1], [0, 1], [1, 1]
        ];
    };

    GOL.Area.prototype.addCell = function(cell, coordinates)
    {
        this.cellsByCoordinates.set(coordinates.getHash(), cell);
        this.coordinatesByCells.set(cell, coordinates);
    };

    GOL.Area.prototype.getCellWithCoordinates = function(coordinates)
    {
        return this.cellsByCoordinates.get(coordinates.getHash());
    };

    GOL.Area.prototype.getAllCells = function()
    {
        var cells = [];
        this.cellsByCoordinates.forEach(function (cell) { cells.push(cell); });
        return cells;
    };

    GOL.Area.prototype.getCoordinatesOf = function (cell)
    {
        return this.coordinatesByCells.get(cell);
    };

    GOL.Area.prototype.getNeighborsOf = function(cell)
    {
        var neighbors = [];
        var cellCoordinates = this.getCoordinatesOf(cell);
        var cellX = cellCoordinates.x;
        var cellY = cellCoordinates.y;
        this.relativeNeighborLocation.forEach((function (neighborLocation) {
            var singleNeighbor = this.getCellWithCoordinates(new GOL.Coordinates(
                cellX + neighborLocation[0],
                cellY + neighborLocation[1]
            ));
            if (undefined !== singleNeighbor) {
                neighbors.push(singleNeighbor);
            }
        }).bind(this));

        return neighbors;
    };

    return GOL;
} (GOL || {}));
<|endoftext|>


<commit_before><commit_msg>Linked js file<commit_after><|endoftext|>


<commit_before>/*
 * Provides ajax tools for ACWPD Projects
 * Feel free to use this in your projects! Just provide Attribution by keeping this block in place!
 *
 * This is version 1.0
 *
 * For the latest version, please visit: https://github.com/farfromunique/ACWPD_Tools
 *
 * This code is copyright (C) 2015 Aaron Coquet / ACWPD
 */

/*
 * Instructions for preperation:
 * Replace ::SiteName:: with the string to be placed in the browser's history
 *
 */

// Put site's address here, in format "http://sub.domain.tld/path/to/root"
var sRoot = document.location.origin; // Default: document.location.origin
var siteName = "Futhark Power Generator 1.5.4";

function adjustMyURL(displayURL) {
	window.history.pushState({site:sRoot}, siteName, "/" + displayURL + "/");
}

function loadMyPage(pageName, targetDiv) {
	var ajax;
	var loaderDiv;
	loaderDiv = document.getElementById("loader")
	loaderDiv.classList.remove("hidden");
	loaderDiv.classList.add("loading");
	ajax = new XMLHttpRequest();
	ajax.open("GET", sRoot + pageName, true);
	ajax.onreadystatechange = function() {
		if (ajax.readyState === 4) {
			document.getElementById(targetDiv).innerHTML = ajax.responseText;
			loaderDiv.classList.remove("loading");
			loaderDiv.classList.add("hidden");
		}
	};
	ajax.send(null);

}

function postToPage(pageName, displayURL, postData) {
	var ajax;
	document.getElementById("content").innerHTML = "Loading ...";
	ajax = new XMLHttpRequest();
	ajax.open("POST", sRoot + pageName, true);
	ajax.onreadystatechange=function() {
		if (ajax.readyState === 4) {
			document.getElementById("content").innerHTML = ajax.responseText;
		}
	};
	ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	ajax.send(postData);
	adjustMyURL(displayURL);
}

function postAndRedirect(pageName, displayURL, postData, redirectTo) {
	var ajax;
    document.getElementById("content").innerHTML = "Loading ...";
	ajax = new XMLHttpRequest();
	ajax.open("POST",sRoot + pageName, true);
	ajax.onreadystatechange=function() {
		if (ajax.readyState === 4) {
			loadMyPage(redirectTo, displayURL, 'content');
		}
	};
	ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	ajax.send(postData);
	adjustMyURL(displayURL);
}

function DismissImportant() {
	if (document.getElementById('Important')) {
	document.getElementById('Important').style.display='none';
	}
}

function hideMessage() {
	if(document.getElementById('Message')) {
		document.getElementById('Message').style.display='none';
	}
}

function insertHistory() {
	var hist = document.querySelector("#hist");
	var marker = document.querySelector("#endOfhist");
	var newDiv = document.createElement("div");

	newDiv.id = "added_"+ hist.childNodes.length;
	newDiv.classList.add("added");
	if (document.querySelectorAll(".added").length > 0) {
		marker = document.getElementById("added_" + (hist.childNodes.length-1));
	}
	hist.insertBefore(newDiv,marker);
	return newDiv.id;
}

function insertSmallImages() {
	var target = insertHistory();
	var req = "/small/" + document.querySelector("#ref").innerText;
	loadMyPage(req,target);
}

function reroll() {
	insertSmallImages();
	loadMyPage("/raw","content");
}

<commit_msg>last change?<commit_after>/*
 * Provides ajax tools for ACWPD Projects
 * Feel free to use this in your projects! Just provide Attribution by keeping this block in place!
 *
 * This is version 1.0
 *
 * For the latest version, please visit: https://github.com/farfromunique/ACWPD_Tools
 *
 * This code is copyright (C) 2015 Aaron Coquet / ACWPD
 */

/*
 * Instructions for preperation:
 * Replace ::SiteName:: with the string to be placed in the browser's history
 *
 */

// Put site's address here, in format "http://sub.domain.tld/path/to/root"
var sRoot = document.location.origin; // Default: document.location.origin
var siteName = "Futhark Power Generator 1.5.4";

function adjustMyURL(displayURL) {
	window.history.pushState({site:sRoot}, siteName, "/" + displayURL + "/");
}

function loadMyPage(pageName, targetDiv) {
	var ajax;
	var loaderDiv;
	loaderDiv = document.getElementById("loader")
	loaderDiv.classList.remove("hidden");
	loaderDiv.classList.add("loading");
	ajax = new XMLHttpRequest();
	ajax.open("GET", sRoot + pageName, true);
	ajax.onreadystatechange = function() {
		if (ajax.readyState === 4) {
			document.getElementById(targetDiv).innerHTML = ajax.responseText;
			loaderDiv.classList.remove("loading");
			loaderDiv.classList.add("hidden");
		}
	};
	ajax.send(null);

}

function postToPage(pageName, displayURL, postData) {
	var ajax;
	document.getElementById("content").innerHTML = "Loading ...";
	ajax = new XMLHttpRequest();
	ajax.open("POST", sRoot + pageName, true);
	ajax.onreadystatechange=function() {
		if (ajax.readyState === 4) {
			document.getElementById("content").innerHTML = ajax.responseText;
		}
	};
	ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	ajax.send(postData);
	adjustMyURL(displayURL);
}

function postAndRedirect(pageName, displayURL, postData, redirectTo) {
	var ajax;
    document.getElementById("content").innerHTML = "Loading ...";
	ajax = new XMLHttpRequest();
	ajax.open("POST",sRoot + pageName, true);
	ajax.onreadystatechange=function() {
		if (ajax.readyState === 4) {
			loadMyPage(redirectTo, displayURL, 'content');
		}
	};
	ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	ajax.send(postData);
	adjustMyURL(displayURL);
}

function DismissImportant() {
	if (document.getElementById('Important')) {
	document.getElementById('Important').style.display='none';
	}
}

function hideMessage() {
	if(document.getElementById('Message')) {
		document.getElementById('Message').style.display='none';
	}
}

function insertHistory() {
	var hist = document.querySelector("#hist");
	var marker = document.querySelector("#endOfhist");
	var newDiv = document.createElement("div");

	newDiv.id = "added_"+ hist.childNodes.length;
	newDiv.classList.add("added");
	if (document.querySelectorAll(".added").length > 0) {
		marker = document.getElementById("added_" + (hist.childNodes.length-1));
	}
	hist.insertBefore(newDiv,marker);
	return newDiv.id;
}

function insertSmallImages() {
	var target = insertHistory();
	var req = "/small/" + document.querySelector("#ref").innerText;
	loadMyPage(req,target);
}

function reroll() {
	insertSmallImages();
	loadMyPage("/raw","content");
	var hist = document.querySelector("#hist");
	while (hist.childElementCount > 4) {
		document.querySelector(".added:last-of-type").remove();
	}
}

<|endoftext|>


<commit_before>

var tutorID = -1; //Local tracking of tutor numbers

function encodeRFC5987ValueChars (str) {
    return encodeURIComponent(str).
        // Note that although RFC3986 reserves "!", RFC5987 does not,
        // so we do not need to escape it
        replace(/['()]/g, escape). // i.e., %27 %28 %29
        replace(/\*/g, '%2A').
            // The following are not required for percent-encoding per RFC5987,
            // so we can allow for a little better readability over the wire: |`^
            replace(/%(?:7C|60|5E)/g, unescape);
}

function isNumeric(num){
    return !isNaN(num)
}

function sendLoginAttempt(query){
    $.ajax({
        url: "http://d.rhocode.com:5000/login.html" + query,
        data: {},
        type: "GET",
        crossDomain: true,
        dataType: "jsonp",
        success: function (data) {
            if(data.status == 'success') {
              tutorID = data.tutorcode;
              $("#serverresponselogin").html("Sign-in successful! Welcome " + $("#name").val() + '! Your tutor code is ' + data.tutorcode + '.');
              populateTable();
            } else {
              $("#serverresponselogin").text("Sign-in failed.");
            }

        },
        error: function (xhr, status) {
            $("#serverresponselogin").text("Server might be offline. Please contact aafu@ucdavis.edu!");
        },
        complete: function (xhr, status) {
            console.log("complete");
        }
    });
}

function sendKeepAlive(tutorid){
    if (tutorid == -1)
      return;
    $.ajax({
        url: "http://d.rhocode.com:5000/keepalive.html?tutorid=" + String(tutorid),
        data: {},
        type: "GET",
        crossDomain: true,
        dataType: "jsonp",
        success: function (data) {

        },
        error: function (xhr, status) {

        },
        complete: function (xhr, status) {
            console.log("Keepalive Sent.");
        }
    });
}

function populateTable(){
    $.ajax({
        url: "http://d.rhocode.com:5000/table.html",
        data: {},
        type: "GET",
        crossDomain: true,
        dataType: "jsonp",
        success: function (data) {
            var $data = $('
');
            var numitems = 0;
            $.each(data.data, function(i, item) {
                numitems++;
                var $tr = $('
').append(
                    $('').text(item.name),
                    $('').text(item.location),
                    $('').text(item.subjects)
                );
                $data.append($tr);
            });
            if (numitems == 0)
              $data.append($.parseHTML('
There are no tutors at this time.
'));
            $('#tutorbody').html($data.html());
        },
        error: function (xhr, status) {
        },
        complete: function (xhr, status) {
            console.log("complete");
        }
    });
}

$(document).ready(function() {
  // set defaults
  $('[data-toggle="tooltip"]').tooltip()
  $("#locationform").hide();
  $("#locationdropdown").val("computer");
  var dropdown = true;

  // dropdown changer

  populateTable();

  setInterval(function(){
    populateTable();
  }, 60000);

  setInterval(function(){
    sendKeepAlive(tutorID);
  }, 300000);

  $("#locationdropdown").change(function() {
    if ($("#locationdropdown").val() == "location") {
      dropdown = false;
      $("#locationform").show();
      $("#computerform").hide();
    } else {
      dropdown = true;
      $("#locationform").hide();
      $("#computerform").show();
    }
  });

  // $("#tsubmit").click(function(e) {

  // var valid = 0 // counts # of form arguments
  // var query = "?name="

  // if (!$("#name").val()) {
  //   $("#name").parent('div').addClass("has-error");
  // }
  // else {
  //     $("#name").parent('div').removeClass("has-error");
  //     valid++;
  //     query += encodeRFC5987ValueChars($("#name").val());
  //   }

  //   if (dropdown) {
  //     if (!$("#num").val() || !isNumeric($("#num").val())) {
  //       $("#num").parent('div').addClass("has-error");
  //     } else {
  //       $("#num").parent('div').removeClass("has-error");
  //       valid++;
  //       query += "&num=" + encodeRFC5987ValueChars($("#num").val());
  //     }
  //   } else {
  //     if (!$("#location").val()) {
  //       $("#location").parent('div').addClass("has-error");
  //     } else {
  //       $("#location").parent('div').removeClass("has-error");
  //       valid++;
  //       query += "&loc=" + encodeRFC5987ValueChars($("#location").val());
  //     }
  //   }

  //   query += "&sub="
  //   var subs = 0 //counts # of subjects needs tutoring for.
  //   $('#tutoringsubjectbody tr').each(function() {
  //     //check the buttons to see if they are checked
  //     //count the # of buttons
  //     query += encodeRFC5987ValueChars($("#button").closest("div").attr("id"));
  //     // ^^^ Adds the id of the closest value to the button, theoretically the
  //     // class
  //   }

  //   if (!subs) {
  //     $("#tutoringsubjectbody").parent('div').addClass("has-error");
  //   } else {
  //     $("#tutoringsubjectbody").parent('div').removeClass("has-error");
  //     valid++;
  //   }

  //   if (valid == 4) {
  //     //do submit
  //     console.log("we good");
  //     console.log(query);
  //     // sendTutoreeAttempt(query); Tutoree send attempt needed?
  //   } else {
  //     console.log("nice try kid");
  //   }

  // });

  // form submission
  $("#submit").click(function(e) {
    //input validation
    var valid = 0;
    var query = "?name="
    // REALLY BAD INPUT VALIDATION
    if (!$("#name").val()) {
      $("#name").parent('div').addClass("has-error");
    } else {
      $("#name").parent('div').removeClass("has-error");
      valid++;
      query += encodeRFC5987ValueChars($("#name").val());
    }

    if (dropdown) {
      if (!$("#num").val() || !isNumeric($("#num").val())) {
        $("#num").parent('div').addClass("has-error");
      } else {
        $("#num").parent('div').removeClass("has-error");
        valid++;
        query += "&num=" + encodeRFC5987ValueChars($("#num").val());
      }
    } else {
      if (!$("#location").val()) {
        $("#location").parent('div').addClass("has-error");
      } else {
        $("#location").parent('div').removeClass("has-error");
        valid++;
        query += "&loc=" + encodeRFC5987ValueChars($("#location").val());
      }
    }

    var format = /^[0-9]+[a-zA-Z]*[\s]*([\s,]+[0-9]+[a-zA-Z]*)*$/i;
    if (!$("#subject").val() ||  !format.test( $("#subject").val() ) ) {
      $("#subject").parent('div').addClass("has-error");
    } else {
      $("#subject").parent('div').removeClass("has-error");
      valid++;
      query += "&sub=" + encodeRFC5987ValueChars($("#subject").val());
    }
    if (!$("#password").val()) {
      $("#password").parent('div').addClass("has-error");
    } else {
      $("#password").parent('div').removeClass("has-error");
      valid++;
      query += "&pass=" + encodeRFC5987ValueChars($("#password").val());
    }

    if (valid == 4) {
      //do submit
      console.log("we good");
      console.log(query);
      sendLoginAttempt(query);
    } else {
      console.log("nice try kid");
    }

  });

  // row toggle
  $(".rowtoggle").click(function(e) {
    if ($(this).hasClass("success")) {
      $(this).addClass("danger").removeClass("success");
      //send to server BUSY
    } else {
      $(this).addClass("success").removeClass("danger");
      //send to server AVAILABLE
    }
  });

});

<commit_msg>Fixed deleted code<commit_after>

var tutorID = -1; //Local tracking of tutor numbers

function encodeRFC5987ValueChars (str) {
    return encodeURIComponent(str).
        // Note that although RFC3986 reserves "!", RFC5987 does not,
        // so we do not need to escape it
        replace(/['()]/g, escape). // i.e., %27 %28 %29
        replace(/\*/g, '%2A').
            // The following are not required for percent-encoding per RFC5987,
            // so we can allow for a little better readability over the wire: |`^
            replace(/%(?:7C|60|5E)/g, unescape);
}

function isNumeric(num){
    return !isNaN(num)
}

function sendLoginAttempt(query){
    $.ajax({
        url: "http://d.rhocode.com:5000/login.html" + query,
        data: {},
        type: "GET",
        crossDomain: true,
        dataType: "jsonp",
        success: function (data) {
            if(data.status == 'success') {
              tutorID = data.tutorcode;
              $("#serverresponselogin").html("Sign-in successful! Welcome " + $("#name").val() + '! Your tutor code is ' + data.tutorcode + '.');
              populateTable();
            } else {
              $("#serverresponselogin").text("Sign-in failed.");
            }

        },
        error: function (xhr, status) {
            $("#serverresponselogin").text("Server might be offline. Please contact aafu@ucdavis.edu!");
        },
        complete: function (xhr, status) {
            console.log("complete");
        }
    });
}

function sendKeepAlive(tutorid){
    if (tutorid == -1)
      return;
    $.ajax({
        url: "http://d.rhocode.com:5000/keepalive.html?tutorid=" + String(tutorid),
        data: {},
        type: "GET",
        crossDomain: true,
        dataType: "jsonp",
        success: function (data) {
            if (data.status != 'success') {
                $("#serverresponselogin").text("Your session has expired. Please relog.");
                $('#signin').modal('show');
            }
        },
        error: function (xhr, status) {

        },
        complete: function (xhr, status) {
            console.log("Keepalive Sent.");
        }
    });
}

function populateTable(){
    $.ajax({
        url: "http://d.rhocode.com:5000/table.html",
        data: {},
        type: "GET",
        crossDomain: true,
        dataType: "jsonp",
        success: function (data) {
            var $data = $('
');
            var numitems = 0;
            $.each(data.data, function(i, item) {
                numitems++;
                var $tr = $('
').append(
                    $('').text(item.name),
                    $('').text(item.location),
                    $('').text(item.subjects)
                );
                $data.append($tr);
            });
            if (numitems == 0)
              $data.append($.parseHTML('
There are no tutors at this time.
'));
            $('#tutorbody').html($data.html());
        },
        error: function (xhr, status) {
        },
        complete: function (xhr, status) {
            console.log("complete");
        }
    });
}

$(document).ready(function() {
  // set defaults
  $('[data-toggle="tooltip"]').tooltip()
  $("#locationform").hide();
  $("#locationdropdown").val("computer");
  var dropdown = true;

  // dropdown changer

  populateTable();

  setInterval(function(){
    populateTable();
  }, 60000);

  setInterval(function(){
    sendKeepAlive(tutorID);
  }, 300000);

  $("#locationdropdown").change(function() {
    if ($("#locationdropdown").val() == "location") {
      dropdown = false;
      $("#locationform").show();
      $("#computerform").hide();
    } else {
      dropdown = true;
      $("#locationform").hide();
      $("#computerform").show();
    }
  });

  $("#tsubmit").click(function(e) {

  var valid = 0 // counts # of form arguments
  var query = "?name="

  if (!$("#name").val()) {
    $("#name").parent('div').addClass("has-error");
  }
  else {
      $("#name").parent('div').removeClass("has-error");
      valid++;
      query += encodeRFC5987ValueChars($("#name").val());
    }

    if (dropdown) {
      if (!$("#num").val() || !isNumeric($("#num").val())) {
        $("#num").parent('div').addClass("has-error");
      } else {
        $("#num").parent('div').removeClass("has-error");
        valid++;
        query += "&num=" + encodeRFC5987ValueChars($("#num").val());
      }
    } else {
      if (!$("#location").val()) {
        $("#location").parent('div').addClass("has-error");
      } else {
        $("#location").parent('div').removeClass("has-error");
        valid++;
        query += "&loc=" + encodeRFC5987ValueChars($("#location").val());
      }
    }

    query += "&sub="
    var subs = 0 //counts # of subjects needs tutoring for.
    $('#tutoringsubjectbody tr').each(function() {
      //check the buttons to see if they are checked
      //count the # of buttons
      query += encodeRFC5987ValueChars($("#button").closest("div").attr("id"));
      // ^^^ Adds the id of the closest value to the button, theoretically the
      // class
    }

    if (!subs) {
      $("#tutoringsubjectbody").parent('div').addClass("has-error");
    } else {
      $("#tutoringsubjectbody").parent('div').removeClass("has-error");
      valid++;
    }

    if (valid == 4) {
      //do submit
      console.log("we good");
      console.log(query);
      // sendTutoreeAttempt(query); Tutoree send attempt needed?
    } else {
      console.log("nice try kid");
    }

  });

  // form submission
  $("#submit").click(function(e) {
    //input validation
    var valid = 0;
    var query = "?name="
    // REALLY BAD INPUT VALIDATION
    if (!$("#name").val()) {
      $("#name").parent('div').addClass("has-error");
    } else {
      $("#name").parent('div').removeClass("has-error");
      valid++;
      query += encodeRFC5987ValueChars($("#name").val());
    }

    if (dropdown) {
      if (!$("#num").val() || !isNumeric($("#num").val())) {
        $("#num").parent('div').addClass("has-error");
      } else {
        $("#num").parent('div').removeClass("has-error");
        valid++;
        query += "&num=" + encodeRFC5987ValueChars($("#num").val());
      }
    } else {
      if (!$("#location").val()) {
        $("#location").parent('div').addClass("has-error");
      } else {
        $("#location").parent('div').removeClass("has-error");
        valid++;
        query += "&loc=" + encodeRFC5987ValueChars($("#location").val());
      }
    }

    var format = /^[0-9]+[a-zA-Z]*[\s]*([\s,]+[0-9]+[a-zA-Z]*)*$/i;
    if (!$("#subject").val() ||  !format.test( $("#subject").val() ) ) {
      $("#subject").parent('div').addClass("has-error");
    } else {
      $("#subject").parent('div').removeClass("has-error");
      valid++;
      query += "&sub=" + encodeRFC5987ValueChars($("#subject").val());
    }
    if (!$("#password").val()) {
      $("#password").parent('div').addClass("has-error");
    } else {
      $("#password").parent('div').removeClass("has-error");
      valid++;
      query += "&pass=" + encodeRFC5987ValueChars($("#password").val());
    }

    if (valid == 4) {
      //do submit
      console.log("we good");
      console.log(query);
      sendLoginAttempt(query);
    } else {
      console.log("nice try kid");
    }

  });

  // row toggle
  $(".rowtoggle").click(function(e) {
    if ($(this).hasClass("success")) {
      $(this).addClass("danger").removeClass("success");
      //send to server BUSY
    } else {
      $(this).addClass("success").removeClass("danger");
      //send to server AVAILABLE
    }
  });

});

<|endoftext|>


<commit_before>define([], function() {

    return {

        app: null,
        ctx: null,
        radius: 9,
        colour: "#725d3c",
        position: {
            x: 25,
            y: 250,
        },
        velocity: {
            x: 1.6,
            y: -2,
        },
        // Used to calculate where the ball is going/what it's hitting
        tempPosition: {
            x: 0,
            y: 0,
        },

        init: function(app) {
            this.app = app;
            this.ctx = this.app.ctx;
        },

        hasHitWall: function() {
            return (this.hasHitLeftWall() || this.hasHitRightWall());
        },

        hasHitLeftWall: function() {
            return (this.tempPosition.x - this.radius <= 0);
        },

        hasHitRightWall: function() {
            return (this.tempPosition.x + this.radius >= this.app.WIDTH);
        },

        hasHitTop: function() {
            return (this.position.y + this.velocity.y - this.radius < 0);
        },

        isMovingDown: function() {
            return (this.velocity.y > 0);
        },

        /**
         * called when the ball hits some above. Whether it's bricks or the
         * wall
         *
         */
        bounceUpOrDown: function() {
            this.velocity.y *= -1;
        },

        correctBallPlacementAfterHittingWall: function() {
            this.tempPosition.x = (this.hasHitLeftWall()) ? this.radius : this.app.WIDTH - this.radius;
        },

        drawBall: function() {
            this.ctx.fillStyle = this.colour;
            this.circle(this.position.x, this.position.y, this.radius);
        },

        draw: function() {
            this.tempPosition = {
                x: this.position.x + this.velocity.x,
                y: this.position.y + this.velocity.y
            };

            this.drawBall();

            // If the ball has hit the wall
            if (this.hasHitWall()) {
                this.correctBallPlacementAfterHittingWall();
                this.velocity.x *= -1;
            }

            this.position = this.tempPosition;
        },

        circle: function(x,y,r) {
            this.ctx.beginPath();
            this.ctx.arc(x, y, r, 0, Math.PI * 2, true);
            this.ctx.closePath();
            this.ctx.fill();
        }
    };
});
<commit_msg>Cleaning up ball draw() method<commit_after>define([], function() {

    return {

        app: null,
        ctx: null,
        radius: 9,
        colour: "#725d3c",
        position: {
            x: 25,
            y: 250,
        },
        velocity: {
            x: 1.6,
            y: -2,
        },
        // Used to calculate where the ball is going/what it's hitting
        tempPosition: {
            x: 0,
            y: 0,
        },

        init: function(app) {
            this.app = app;
            this.ctx = this.app.ctx;
        },

        hasHitWall: function() {
            return (this.hasHitLeftWall() || this.hasHitRightWall());
        },

        hasHitLeftWall: function() {
            return (this.tempPosition.x - this.radius <= 0);
        },

        hasHitRightWall: function() {
            return (this.tempPosition.x + this.radius >= this.app.WIDTH);
        },

        hasHitTop: function() {
            return (this.position.y + this.velocity.y - this.radius < 0);
        },

        isMovingDown: function() {
            return (this.velocity.y > 0);
        },

        /**
         * called when the ball hits some above. Whether it's bricks or the
         * wall
         *
         */
        bounceUpOrDown: function() {
            this.velocity.y *= -1;
        },

        correctBallPlacementAfterHittingWall: function() {
            this.tempPosition.x = (this.hasHitLeftWall()) ? this.radius : this.app.WIDTH - this.radius;
        },

        updatePosition: function() {
            this.tempPosition = {
                x: this.position.x + this.velocity.x,
                y: this.position.y + this.velocity.y
            };

            // If the ball has hit the wall
            if (this.hasHitWall()) {
                this.correctBallPlacementAfterHittingWall();
                this.velocity.x *= -1;
            }

            this.position = this.tempPosition;
        },

        draw: function() {
            this.updatePosition();
            this.ctx.fillStyle = this.colour;
            this.circle(this.position.x, this.position.y, this.radius);
        },

        circle: function(x,y,r) {
            this.ctx.beginPath();
            this.ctx.arc(x, y, r, 0, Math.PI * 2, true);
            this.ctx.closePath();
            this.ctx.fill();
        }
    };
});
<|endoftext|>


<commit_before>/* eslint-env browser */

/* eslint-disable react/no-string-refs */

import React from 'react';
import * as ReactRedux from 'react-redux';
import {
  Floats, Notifications,
  LargeMessage,
  Spinner,
  isDark,
} from 'giu';
import tinycolor from 'tinycolor2';
import { _ } from 'storyboard-core';
import Toolbar from './015-toolbar';
import Story from './020-story';
// let ReduxDevTools;
// if process.env.NODE_ENV isnt 'production' {
//   ReduxDevTools = require('../components/990-reduxDevTools')
// }

require('./app.sass');

const mapStateToProps = (state) => ({
  fRelativeTime: state.settings.timeType === 'RELATIVE',
  cxState: state.cx.cxState,
  mainStory: state.stories.mainStory,
  colors: _.pick(state.settings, [
    'colorClientBg', 'colorServerBg', 'colorUiBg',
    'colorClientFg', 'colorServerFg', 'colorUiFg',
    'colorClientBgIsDark', 'colorServerBgIsDark', 'colorUiBgIsDark',
  ]),
});

class App extends React.PureComponent {
  static propTypes = {
    // From Redux.connect
    fRelativeTime: React.PropTypes.bool.isRequired,
    cxState: React.PropTypes.string.isRequired,
    mainStory: React.PropTypes.object.isRequired,
    colors: React.PropTypes.object.isRequired,
  };

  constructor(props) {
    super(props);
    this.state = {
      seqFullRefresh: 0,
    };
  }

  componentDidMount() {
    this.timerFullRefresh = setInterval(this.fullRefresh, 30e3);
    window.addEventListener('scroll', this.onScroll);
  }

  componentWillUnmount() {
    clearInterval(this.timerFullRefresh);
    this.timerFullRefresh = null;
    window.removeEventListener('scroll', this.onScroll);
  }

  componentDidUpdate() {
    if (this.fAnchoredToBottom) {
      window.scrollTo(0, document.body.scrollHeight);
    }
  }

  // -----------------------------------------------------
  fullRefresh = () => {
    if (!this.props.fRelativeTime) return;
    this.setState({
      seqFullRefresh: this.state.seqFullRefresh + 1,
    });
  }

  onScroll = () => {
    const bcr = this.refs.outer.getBoundingClientRect();
    this.fAnchoredToBottom = bcr.bottom - window.innerHeight < 30;
  }

  // -----------------------------------------------------
  render() {
    let reduxDevTools;
    const { cxState, colors } = this.props;
    // if (process.env.NODE_ENV isnt 'production') {
    //   reduxDevTools = <ReduxDevTools />
    // }
    const fConnected = cxState === 'CONNECTED';
    return (

        <Floats />
        <Notifications />
        {!fConnected && this.renderConnecting()}
        {fConnected && <Toolbar colors={colors} />}
        {fConnected && this.renderStories()}
        {reduxDevTools}

    );
  }

  renderStories() {
    return (

        <Story
          story={this.props.mainStory}
          level={0}
          seqFullRefresh={this.state.seqFullRefresh}
          colors={this.props.colors}
        />

    );
  }

  renderConnecting() {
    return (
      <LargeMessage style={style.largeMessage(this.props.colors)}>

<Spinner /> Connecting to Storyboard...
{' '}

Navigate to your Storyboard-equipped app (and log in if required)

      </LargeMessage>
    );
  }
}

// -----------------------------------------------------
const style = {
  outer: (colors) => ({
    height: '100%',
    backgroundColor: colors.colorUiBg,
    color: colors.colorUiFg,
  }),
  largeMessage: (colors) => {
    let color = tinycolor(colors.colorUiFg);
    color = isDark(colors.colorUiFg) ? color.lighten(20) : color.darken(20);
    return { color: color.toRgbString() };
  },
  stories: { padding: 4 },
};

// -----------------------------------------------------
const connect = ReactRedux.connect(mapStateToProps);
export default connect(App);
export { App as _App };
<commit_msg>Add hint to settings<commit_after>/* eslint-env browser */

/* eslint-disable react/no-string-refs */

import React from 'react';
import * as ReactRedux from 'react-redux';
import {
  Floats, Notifications,
  Hints, hintDefine, hintShow,
  LargeMessage,
  Spinner,
  isDark,
} from 'giu';
import tinycolor from 'tinycolor2';
import { _ } from 'storyboard-core';
import Toolbar from './015-toolbar';
import Story from './020-story';
// let ReduxDevTools;
// if process.env.NODE_ENV isnt 'production' {
//   ReduxDevTools = require('../components/990-reduxDevTools')
// }

require('./app.sass');

const mapStateToProps = (state) => ({
  fRelativeTime: state.settings.timeType === 'RELATIVE',
  cxState: state.cx.cxState,
  mainStory: state.stories.mainStory,
  colors: _.pick(state.settings, [
    'colorClientBg', 'colorServerBg', 'colorUiBg',
    'colorClientFg', 'colorServerFg', 'colorUiFg',
    'colorClientBgIsDark', 'colorServerBgIsDark', 'colorUiBgIsDark',
  ]),
});

class App extends React.PureComponent {
  static propTypes = {
    // From Redux.connect
    fRelativeTime: React.PropTypes.bool.isRequired,
    cxState: React.PropTypes.string.isRequired,
    mainStory: React.PropTypes.object.isRequired,
    colors: React.PropTypes.object.isRequired,
  };

  constructor(props) {
    super(props);
    this.state = {
      seqFullRefresh: 0,
    };
  }

  componentDidMount() {
    this.timerFullRefresh = setInterval(this.fullRefresh, 30e3);
    window.addEventListener('scroll', this.onScroll);
    this.showHint();
  }

  componentWillUnmount() {
    clearInterval(this.timerFullRefresh);
    this.timerFullRefresh = null;
    window.removeEventListener('scroll', this.onScroll);
  }

  componentDidUpdate() {
    if (this.fAnchoredToBottom) {
      window.scrollTo(0, document.body.scrollHeight);
    }
    this.showHint();
  }

  // -----------------------------------------------------
  fullRefresh = () => {
    if (!this.props.fRelativeTime) return;
    this.setState({
      seqFullRefresh: this.state.seqFullRefresh + 1,
    });
  }

  onScroll = () => {
    const bcr = this.refs.outer.getBoundingClientRect();
    this.fAnchoredToBottom = bcr.bottom - window.innerHeight < 30;
  }

  // -----------------------------------------------------
  render() {
    let reduxDevTools;
    const { cxState, colors } = this.props;
    // if (process.env.NODE_ENV isnt 'production') {
    //   reduxDevTools = <ReduxDevTools />
    // }
    const fConnected = cxState === 'CONNECTED';
    return (

        <Floats />
        <Notifications />
        <Hints />
        {!fConnected && this.renderConnecting()}
        {fConnected && <Toolbar colors={colors} />}
        {fConnected && this.renderStories()}
        {reduxDevTools}

    );
  }

  renderStories() {
    return (

        <Story
          story={this.props.mainStory}
          level={0}
          seqFullRefresh={this.state.seqFullRefresh}
          colors={this.props.colors}
        />

    );
  }

  renderConnecting() {
    return (
      <LargeMessage style={style.largeMessage(this.props.colors)}>

<Spinner /> Connecting to Storyboard...
{' '}

Navigate to your Storyboard-equipped app (and log in if required)

      </LargeMessage>
    );
  }

  // -----------------------------------------------------
  showHint() {
    if (this.props.cxState !== 'CONNECTED') return;
    if (this.fAttempted) return;
    this.fAttempted = true;
    const elements = () => {
      const out = [];
      const nodeSettings = document.getElementById('sbBtnShowSettings');
      if (nodeSettings) {
        const bcr = nodeSettings.getBoundingClientRect();
        const x = 50;
        const y = 80;
        out.push({
          type: 'LABEL', x, y, align: 'left',
          children: 'Settings',
        });
        out.push({
          type: 'ARROW', from: { x: x - 5, y },
          to: { x: (bcr.left + bcr.right) / 2, y: bcr.bottom + 5 },
        });
      }
      // const nodeAddLang = document.getElementById('madyBtnAddLang');
      // if (nodeAddLang) {
      //   const bcr = nodeAddLang.getBoundingClientRect();
      //   const x = window.innerWidth - 50;
      //   out.push({
      //     type: 'LABEL', x, y: 140, align: 'right',
      //     children: _t('hint_Add language column'),
      //   });
      //   out.push({
      //     type: 'ARROW', from: { x, y: 140 },
      //     to: { x: (bcr.left + bcr.right) / 2, y: bcr.bottom },
      //     counterclockwise: true,
      //   });
      // }
      return out;
    }
    hintDefine('main', { elements, closeLabel: 'Enjoy!' });
    hintShow('main', true);
  }
}

// -----------------------------------------------------
const style = {
  outer: (colors) => ({
    height: '100%',
    backgroundColor: colors.colorUiBg,
    color: colors.colorUiFg,
  }),
  largeMessage: (colors) => {
    let color = tinycolor(colors.colorUiFg);
    color = isDark(colors.colorUiFg) ? color.lighten(20) : color.darken(20);
    return { color: color.toRgbString() };
  },
  stories: { padding: 4 },
};

// -----------------------------------------------------
const connect = ReactRedux.connect(mapStateToProps);
export default connect(App);
export { App as _App };
<|endoftext|>


<commit_before>const fs = require('fs'),
    readline = require('readline');
module.exports = function (base, cb) {

    // let base = process.cwd();
    // console.log(base)
    const readInterface = readline.createInterface({
        input: fs.createReadStream(base + "/.env"),
        // output: process.stdout,
        console: false
    });
    // const query = ['INSERT INTO countries (name,currency_code, country_extension, rate) VALUES '];
    readInterface.on('line', function (line) {
        if (!line) return;
        const [key, value] = line.split('=');
        // process.env[key] = value;
        security[key] = value;
    });

    readInterface.on('close', function () {

        // console.log('Done...', process.env)
        cb();

    });

}<commit_msg>None .env bug fixed<commit_after>const fs = require('fs'),
    readline = require('readline');
module.exports = function (base, cb) {

    // let base = process.cwd();
    // console.log(base)

    if(!fs.existsSync(base + "/.env")) return cb();

    const readInterface = readline.createInterface({
        input: fs.createReadStream(base + "/.env"),
        // output: process.stdout,
        console: false
    });
    // const query = ['INSERT INTO countries (name,currency_code, country_extension, rate) VALUES '];
    readInterface.on('line', function (line) {
        if (!line) return;
        const [key, value] = line.split('=');
        // process.env[key] = value;
        security[key.trim()] = value.trim();
    });

    readInterface.on('close', function () {

        // console.log('Done...', process.env)
        cb();

    });

}<|endoftext|>


<commit_before>// Try to use vanilla javascript instead of jQuery when possible!
// Much love <3

window.addEventListener('load', function() {
    var LAYOUT = { HORIZONTAL : 0 , VERTICAL : 1 };
    var dropped = [ 'rand paul' ];

    var data = [],
        total = 0,
        side = 'rep',
        head;

    var drawBars = function() {
        if (data == null || data.length <= 0) { return; }

        var hasDropped = function(d) {
            return dropped.indexOf(d.name.toLowerCase()) >= 0;
        };

        var getColor = function(d) {
            return d.isFirst ? '#d09f00' : hasDropped(d) ? '#e6e6e6' : d.color;
        };

        // Do our thing for every barchart container
        [].slice.call(document.querySelectorAll('.bars-container')).forEach(function(container) {
            var containerWidth = window.getInnerWidth(container, 0),
                containerHeight = window.getInnerHeight(container);

            var width = containerWidth,
                height,
                xScale, yScale,
                layout = window.innerWidth <= 990 ? LAYOUT.VERTICAL : LAYOUT.HORIZONTAL;

            // Set up scales
            if (layout === LAYOUT.HORIZONTAL) {
                xScale = d3.scale.linear().domain([0, total]).range([0, width]);
                var rangeBand = 40,
                    rangeBandPadding = rangeBand * 0.5;
                height = rangeBandPadding + ((rangeBand + rangeBandPadding) * data.length);
            } else if (layout === LAYOUT.VERTICAL) {
                height = containerHeight;
                xScale = d3.scale.ordinal().domain(_.pluck(data, 'name')).rangeRoundBands([0, width], 0.15, 0.15);
                yScale = d3.scale.linear().domain([0, 100]).range([0, height]);
            }

            // Get or create SVG tag
            var svg = d3.select(container).select('svg');
            if (svg[0][0] == null) {
                svg = d3.select(container).append('svg');
                svg.append('defs');
                // svg.append('g').attr('class', 'guides');
                svg.append('g').attr('class', 'bars');
                svg.append('g').attr('class', 'circles');
                svg.append('g').attr('class', 'labels');
            }
            var defs = svg.select('defs'),
                // guidesGroup = svg.select('g.guides'),
                barsGroup = svg.select('g.bars'),
                circlesGroup = svg.select('g.circles'),
                labelsGroup = svg.select('g.labels');

            // Set SVG size
            svg.attr('width', width).attr('height', height);

            var pattern = defs.selectAll('pattern').data(data, function(d) { return d.name; }),
                bar = barsGroup.selectAll('.bar').data(data, function(d) { return d.name; }),
                circle = circlesGroup.selectAll('.circle').data(data, function(d) { return d.name; }),
                label = labelsGroup.selectAll('.label').data(data, function(d) { return d.name; }),
                name = labelsGroup.selectAll('.name').data([head], function(d) { return d.name; });

            // Remove old bars and guides
            pattern.exit().remove();
            bar.exit().remove();
            circle.exit().remove();
            label.exit().remove();
            name.exit().remove();

            // Append new ones
            pattern.enter().append('pattern').attr({
                id: function(d) { return d.name.split(' ')[1].replace(/'/, '').toLowerCase(); },
                patternUnits: 'objectBoundingBox',
                width: '100%',
                height: '100%',
                viewBox: '0 0 1 1',
                preserveAspectRatio: 'xMidYMid slice'
            }).append('image').attr({
                'xlink:href': function(d) {
                    return 'img/' + side + '/' +
                           d.name.split(' ')[1].replace(/'/, '').toLowerCase() +
                           (d.isFirst ? '-or' : hasDropped(d) ? '-gr' : '') +
                           '.jpg';
                },
                'width': 1,
                'height': 1,
                'preserveAspectRatio': 'xMidYMid slice'
            });
            bar.enter().append('rect').attr('class', 'bar');
            circle.enter().append('circle').attr('class', 'circle');
            label.enter().append('text').attr('class', 'label');
            name.enter().append('text').attr('class', 'name gold').text(function(d) { return d.name; });

            // Update size and position for everything left
            if (layout === LAYOUT.HORIZONTAL) {
                bar.attr({
                    x: 0,
                    y: function(datum, index) {
                        return rangeBandPadding + ((rangeBand + rangeBandPadding) * index);
                    },
                    width: function(d) { return xScale(d.score); },
                    height: rangeBand,
                }).style('fill', getColor);

                circle.attr({
                    cx: function(d) { return xScale(d.score); },
                    cy: function(d, i) {
                        return rangeBandPadding + ((rangeBand + rangeBandPadding) * i) + (rangeBand / 2);
                    },
                    r: (rangeBand * 1.3) / 2,
                    'xlink:href': function(d) {
                        return 'img/' + side + '/' + d.name.split(' ')[1].toLowerCase().replace(/'/, '') + '.png'
                    }
                }).style({
                    'fill': function(d) {
                        return 'url(#' + d.name.split(' ')[1].toLowerCase().replace(/'/, '') + ')';
                    },
                    'opacity': '1',
                    'pointer-events': 'all'
                });

                label.style({
                    'text-anchor' : function(d) { return d.percent >= 5 ? 'end' : 'start';  },
                    'pointer-events' : function(d) { return d.percent >= 5 ? 'none' : 'all';  },
                    'transform': function(d) {
                        return 'translateX(' + String(d.percent >= 5 ? -1.4 : 1.4) + 'em)' +
                               'translateY(.4em)';
                    }
                }).attr({
                    class : function(d) {
                        return 'label' + (d.percent < 5 ? ' inverse' : '') + (hasDropped(d) ? ' grey' : '');
                    },
                    x : function(d) { return xScale(d.score); },
                    y : function(d, i) {
                        return rangeBandPadding + ((rangeBand + rangeBandPadding) * i) + (rangeBand / 2);
                    }
                });

                name.attr({
                    x : function(d) { return xScale(d.score); },
                    y : function(d) {
                        var i = -1;
                        while (++i < data.length) {
                            if (data[i].name === d.name) {
                                break;
                            }
                        }
                        return rangeBandPadding + ((rangeBand + rangeBandPadding) * i) + (rangeBand / 2);
                    }
                }).style({
                    'transform': 'translateX(1.2em)' +
                                 'translateY(.4em)'
                });

                circle.on('mouseenter', function(d) {
                    var tt = document.querySelector('.tt');
                    tt.querySelector('p').innerHTML = d.name;
                    tt.classList.remove('hidden');
                    tt.querySelector('.tt--arrow').style.opacity = 0;
                });
                circle.on('mousemove', function() {
                    var tt = document.querySelector('.tt'),
                        thisBoundingRect = this.getBoundingClientRect();

                    tt.style.top = String(
                        thisBoundingRect.top + window.getScrollTop() +
                        (thisBoundingRect.height / 2) -
                        (tt.getBoundingClientRect().height / 2)
                    ) + 'px';
                    tt.style.left = String(thisBoundingRect.right + 4) + 'px';
                });
                circle.on('mouseleave', function() {
                    document.querySelector('.tt').classList.add('hidden');
                });
            } else if (layout === LAYOUT.VERTICAL) {
                bar.attr({
                    x: function(d) { return xScale(d.name); },
                    y: 0,
                    width: function(d) { return xScale.rangeBand(); },
                    height: function(d) { return yScale(d.score); }
                }).style({
                    'fill': function(d) {
                        return 'url(#' + d.name.split(' ')[1].toLowerCase().replace(/'/, '') + ')';
                    }
                });

                circle.style({
                    'opacity': 0,
                    'pointer-events': 'none'
                });

                label.style({
                    'text-anchor' : 'middle',
                    'transform': 'translateX(0)' +
                                 'translateY(1.2em)'
                }).attr({
                    class : function(d) {
                        return 'label ' + (d.isFirst ? 'gold' : 'inverse');
                    },
                    x : function(d) { return xScale(d.name) + (xScale.rangeBand() / 2); },
                    y : function(d) { return yScale(d.score); }
                });

                name.attr({
                    x : function(d) { return xScale(d.name) + (xScale.rangeBand() * 0.5); },
                    y : function(d) { return yScale(d.score); }
                }).style({
                    'text-anchor': 'middle',
                    'transform': 'translateX(0)' +
                                 'translateY(2.4em)'
                });
            }

            // Common stuff (horizontal & vertical)
            label.text(function(d) {
                return String(d.score).replace(/\./, ',');
            });

            // Handle events
            var getOpacity = function(reference) {
                return function(d) { return reference.name === d.name ? 1 : 0.7; };
            };
        });
    };

    window.startBars = function(input, _side) {
        side = _side;
        // Refine results
        data = _.reduce(_.map(_.pluck(input, 'results'), function(row) {
            // We only want delegates count
            return _.mapValues(row, function(result) {
                return result.delegates;
            });
        }), function(a, b) {
            // Sum every round
            return _.mapValues(a, function(n, k) {
                return n + b[k];
            });
        });

        total = _.sum(data);

        while (total++ % 10 > 0); --total;

        data = _.map(data, function(v, k) {
            return {
                name : k,
                score : v,
                percent : (v * 100) / total
            };
        });

        data = _.sortByOrder(data, 'score', 'desc');
        data[0].isFirst = true;
        head = _.head(data);
        var tail = _.shuffle(_.tail(data));
        data = _.take(tail, Math.floor(tail.length / 2)).concat(head).concat(_.takeRight(tail, Math.ceil(tail.length / 2)));

        // Call on resize
        window.addEventListener('resize', _.debounce(drawBars, 200));
        // Initial call
        drawBars();

        // Draw lines
        window.startLines(input);

        // Draw rounds
        window.startRounds(input);

        drawBars();

        window.dispatchEvent(new Event('resize'));
    };
});
<commit_msg>dropped<commit_after>// Try to use vanilla javascript instead of jQuery when possible!
// Much love <3

window.addEventListener('load', function() {
    var LAYOUT = { HORIZONTAL : 0 , VERTICAL : 1 };
    var dropped = [ 'rand paul' , 'jeb bush' ];

    var data = [],
        total = 0,
        side = 'rep',
        head;

    var drawBars = function() {
        if (data == null || data.length <= 0) { return; }

        var hasDropped = function(d) {
            return dropped.indexOf(d.name.toLowerCase()) >= 0;
        };

        var getColor = function(d) {
            return d.isFirst ? '#d09f00' : hasDropped(d) ? '#e6e6e6' : d.color;
        };

        // Do our thing for every barchart container
        [].slice.call(document.querySelectorAll('.bars-container')).forEach(function(container) {
            var containerWidth = window.getInnerWidth(container, 0),
                containerHeight = window.getInnerHeight(container);

            var width = containerWidth,
                height,
                xScale, yScale,
                layout = window.innerWidth <= 990 ? LAYOUT.VERTICAL : LAYOUT.HORIZONTAL;

            // Set up scales
            if (layout === LAYOUT.HORIZONTAL) {
                xScale = d3.scale.linear().domain([0, total]).range([0, width]);
                var rangeBand = 40,
                    rangeBandPadding = rangeBand * 0.5;
                height = rangeBandPadding + ((rangeBand + rangeBandPadding) * data.length);
            } else if (layout === LAYOUT.VERTICAL) {
                height = containerHeight;
                xScale = d3.scale.ordinal().domain(_.pluck(data, 'name')).rangeRoundBands([0, width], 0.15, 0.15);
                yScale = d3.scale.linear().domain([0, 100]).range([0, height]);
            }

            // Get or create SVG tag
            var svg = d3.select(container).select('svg');
            if (svg[0][0] == null) {
                svg = d3.select(container).append('svg');
                svg.append('defs');
                // svg.append('g').attr('class', 'guides');
                svg.append('g').attr('class', 'bars');
                svg.append('g').attr('class', 'circles');
                svg.append('g').attr('class', 'labels');
            }
            var defs = svg.select('defs'),
                // guidesGroup = svg.select('g.guides'),
                barsGroup = svg.select('g.bars'),
                circlesGroup = svg.select('g.circles'),
                labelsGroup = svg.select('g.labels');

            // Set SVG size
            svg.attr('width', width).attr('height', height);

            var pattern = defs.selectAll('pattern').data(data, function(d) { return d.name; }),
                bar = barsGroup.selectAll('.bar').data(data, function(d) { return d.name; }),
                circle = circlesGroup.selectAll('.circle').data(data, function(d) { return d.name; }),
                label = labelsGroup.selectAll('.label').data(data, function(d) { return d.name; }),
                name = labelsGroup.selectAll('.name').data([head], function(d) { return d.name; });

            // Remove old bars and guides
            pattern.exit().remove();
            bar.exit().remove();
            circle.exit().remove();
            label.exit().remove();
            name.exit().remove();

            // Append new ones
            pattern.enter().append('pattern').attr({
                id: function(d) { return d.name.split(' ')[1].replace(/'/, '').toLowerCase(); },
                patternUnits: 'objectBoundingBox',
                width: '100%',
                height: '100%',
                viewBox: '0 0 1 1',
                preserveAspectRatio: 'xMidYMid slice'
            }).append('image').attr({
                'xlink:href': function(d) {
                    return 'img/' + side + '/' +
                           d.name.split(' ')[1].replace(/'/, '').toLowerCase() +
                           (d.isFirst ? '-or' : hasDropped(d) ? '-gr' : '') +
                           '.jpg';
                },
                'width': 1,
                'height': 1,
                'preserveAspectRatio': 'xMidYMid slice'
            });
            bar.enter().append('rect').attr('class', 'bar');
            circle.enter().append('circle').attr('class', 'circle');
            label.enter().append('text').attr('class', 'label');
            name.enter().append('text').attr('class', 'name gold').text(function(d) { return d.name; });

            // Update size and position for everything left
            if (layout === LAYOUT.HORIZONTAL) {
                bar.attr({
                    x: 0,
                    y: function(datum, index) {
                        return rangeBandPadding + ((rangeBand + rangeBandPadding) * index);
                    },
                    width: function(d) { return xScale(d.score); },
                    height: rangeBand,
                }).style('fill', getColor);

                circle.attr({
                    cx: function(d) { return xScale(d.score); },
                    cy: function(d, i) {
                        return rangeBandPadding + ((rangeBand + rangeBandPadding) * i) + (rangeBand / 2);
                    },
                    r: (rangeBand * 1.3) / 2,
                    'xlink:href': function(d) {
                        return 'img/' + side + '/' + d.name.split(' ')[1].toLowerCase().replace(/'/, '') + '.png'
                    }
                }).style({
                    'fill': function(d) {
                        return 'url(#' + d.name.split(' ')[1].toLowerCase().replace(/'/, '') + ')';
                    },
                    'opacity': '1',
                    'pointer-events': 'all'
                });

                label.style({
                    'text-anchor' : function(d) { return d.percent >= 5 ? 'end' : 'start';  },
                    'pointer-events' : function(d) { return d.percent >= 5 ? 'none' : 'all';  },
                    'transform': function(d) {
                        return 'translateX(' + String(d.percent >= 5 ? -1.4 : 1.4) + 'em)' +
                               'translateY(.4em)';
                    }
                }).attr({
                    class : function(d) {
                        return 'label' + (d.percent < 5 ? ' inverse' : '') + (hasDropped(d) ? ' grey' : '');
                    },
                    x : function(d) { return xScale(d.score); },
                    y : function(d, i) {
                        return rangeBandPadding + ((rangeBand + rangeBandPadding) * i) + (rangeBand / 2);
                    }
                });

                name.attr({
                    x : function(d) { return xScale(d.score); },
                    y : function(d) {
                        var i = -1;
                        while (++i < data.length) {
                            if (data[i].name === d.name) {
                                break;
                            }
                        }
                        return rangeBandPadding + ((rangeBand + rangeBandPadding) * i) + (rangeBand / 2);
                    }
                }).style({
                    'transform': 'translateX(1.2em)' +
                                 'translateY(.4em)'
                });

                circle.on('mouseenter', function(d) {
                    var tt = document.querySelector('.tt');
                    tt.querySelector('p').innerHTML = d.name;
                    tt.classList.remove('hidden');
                    tt.querySelector('.tt--arrow').style.opacity = 0;
                });
                circle.on('mousemove', function() {
                    var tt = document.querySelector('.tt'),
                        thisBoundingRect = this.getBoundingClientRect();

                    tt.style.top = String(
                        thisBoundingRect.top + window.getScrollTop() +
                        (thisBoundingRect.height / 2) -
                        (tt.getBoundingClientRect().height / 2)
                    ) + 'px';
                    tt.style.left = String(thisBoundingRect.right + 4) + 'px';
                });
                circle.on('mouseleave', function() {
                    document.querySelector('.tt').classList.add('hidden');
                });
            } else if (layout === LAYOUT.VERTICAL) {
                bar.attr({
                    x: function(d) { return xScale(d.name); },
                    y: 0,
                    width: function(d) { return xScale.rangeBand(); },
                    height: function(d) { return yScale(d.score); }
                }).style({
                    'fill': function(d) {
                        return 'url(#' + d.name.split(' ')[1].toLowerCase().replace(/'/, '') + ')';
                    }
                });

                circle.style({
                    'opacity': 0,
                    'pointer-events': 'none'
                });

                label.style({
                    'text-anchor' : 'middle',
                    'transform': 'translateX(0)' +
                                 'translateY(1.2em)'
                }).attr({
                    class : function(d) {
                        return 'label ' + (d.isFirst ? 'gold' : 'inverse');
                    },
                    x : function(d) { return xScale(d.name) + (xScale.rangeBand() / 2); },
                    y : function(d) { return yScale(d.score); }
                });

                name.attr({
                    x : function(d) { return xScale(d.name) + (xScale.rangeBand() * 0.5); },
                    y : function(d) { return yScale(d.score); }
                }).style({
                    'text-anchor': 'middle',
                    'transform': 'translateX(0)' +
                                 'translateY(2.4em)'
                });
            }

            // Common stuff (horizontal & vertical)
            label.text(function(d) {
                return String(d.score).replace(/\./, ',');
            });

            // Handle events
            var getOpacity = function(reference) {
                return function(d) { return reference.name === d.name ? 1 : 0.7; };
            };
        });
    };

    window.startBars = function(input, _side) {
        side = _side;
        // Refine results
        data = _.reduce(_.map(_.pluck(input, 'results'), function(row) {
            // We only want delegates count
            return _.mapValues(row, function(result) {
                return result.delegates;
            });
        }), function(a, b) {
            // Sum every round
            return _.mapValues(a, function(n, k) {
                return n + b[k];
            });
        });

        total = _.sum(data);

        while (total++ % 10 > 0); --total;

        data = _.map(data, function(v, k) {
            return {
                name : k,
                score : v,
                percent : (v * 100) / total
            };
        });

        data = _.sortByOrder(data, 'score', 'desc');
        data[0].isFirst = true;
        head = _.head(data);
        var tail = _.shuffle(_.tail(data));
        data = _.take(tail, Math.floor(tail.length / 2)).concat(head).concat(_.takeRight(tail, Math.ceil(tail.length / 2)));

        // Call on resize
        window.addEventListener('resize', _.debounce(drawBars, 200));
        // Initial call
        drawBars();

        // Draw lines
        window.startLines(input);

        // Draw rounds
        window.startRounds(input);

        drawBars();

        window.dispatchEvent(new Event('resize'));
    };
});
<|endoftext|>


<commit_before>var inherit;

(function (global, exports) {

    /**
     *
     * @param {Object} classDefinition The definition for the prototype methods
     * @param {Function} [baseClass] The prototype to inherit from
     *
     * @return {Function} returns a constructor function describing the class
     */
    inherit = function (classDefinition, baseClass) {
        baseClass = baseClass || Object;

        var newClass = function () {
            if (this.ctor) {
                this.ctor.apply(this, arguments);
            }
        };

        if (baseClass.constructor == Function) {

            function Inheritance() {
            }

            Inheritance.prototype = baseClass.prototype;

            newClass.prototype = new Inheritance();
            newClass.prototype.constructor = classDefinition;
            newClass.prototype.base = baseClass.prototype;

        } else {
            newClass.prototype = baseClass;
            newClass.prototype.constructor = classDefinition;
            newClass.prototype.base = baseClass;
        }

        for (var publicMethod in classDefinition) {
            if (classDefinition.hasOwnProperty(publicMethod)) {
                var baseFunction = newClass.prototype[publicMethod];
                newClass.prototype[publicMethod] = classDefinition[publicMethod];
                newClass.prototype[publicMethod].baseImplementation = baseFunction;
            }
        }

        newClass.prototype.callBase = inherit.callBase;

        return newClass;

    };

    inherit.callBase = function () {
        var args = Array.prototype.slice.call(arguments);

        if (args.length == 0) {
            // use arguments from call
            args = Array.prototype.slice.call(arguments.callee.caller.arguments);
        }

        return arguments.callee.caller.baseImplementation.apply(this, args);
    };

    /**
     *
     * @param classDefinition The definition for the prototype methods
     *
     * @return {Function} returns a constructor function describing the class
     */
    Function.prototype.inherit = function (classDefinition) {
        return inherit(classDefinition, this);
    };

    Function.prototype.callBase = function () {
        var args = Array.prototype.slice.call(arguments);
        var that = args.shift();

        if (that && that.base) {
            var caller = arguments.callee.caller;

            if (this == caller) {
                return this.baseImplementation.apply(that, args);
            } else {
                return this.apply(that, args);
            }
        } else {
            throw "base not definied";
        }
    };

    /**
     * @property {Function} base class
     */
    inherit.Base = inherit({
        ctor: function () {
        }
    });

    exports.inherit = inherit;

})(this, typeof exports === "undefined" ? this : exports);<commit_msg>whats wrong with git?<commit_after>var inherit;

(function (global, exports) {

    /**
     *
     * @param {Object} classDefinition The definition for the prototype methods
     * @param {Function} [baseClass] The prototype to inherit from
     *
     * @return {Function} returns a constructor function describing the class
     */
    inherit = function (classDefinition, baseClass) {
        baseClass = baseClass || Object;

        var newClass = function () {
            if (this.ctor) {
                this.ctor.apply(this, arguments);
            }
        };

        if (baseClass.constructor == Function) {

            function Inheritance() {
            }

            Inheritance.prototype = baseClass.prototype;

            newClass.prototype = new Inheritance();
            newClass.prototype.constructor = classDefinition;
            newClass.prototype.base = baseClass.prototype;

        } else {
            newClass.prototype = baseClass;
            newClass.prototype.constructor = classDefinition;
            newClass.prototype.base = baseClass;
        }

        for (var publicMethod in classDefinition) {
            if (classDefinition.hasOwnProperty(publicMethod)) {
                var baseFunction = newClass.prototype[publicMethod];
                newClass.prototype[publicMethod] = classDefinition[publicMethod];
                newClass.prototype[publicMethod].baseImplementation = baseFunction;
            }
        }

        newClass.prototype.callBase = inherit.callBase;

        return newClass;

    };

    inherit.callBase = function () {
        // get arguments
        var args = Array.prototype.slice.call(arguments);

        if (args.length == 0) {
            // use arguments from call
            args = Array.prototype.slice.call(arguments.callee.caller.arguments);
        }

        return arguments.callee.caller.baseImplementation.apply(this, args);
    };

    /**
     *
     * @param classDefinition The definition for the prototype methods
     *
     * @return {Function} returns a constructor function describing the class
     */
    Function.prototype.inherit = function (classDefinition) {
        return inherit(classDefinition, this);
    };

    Function.prototype.callBase = function () {
        var args = Array.prototype.slice.call(arguments);
        var that = args.shift();

        if (that && that.base) {
            var caller = arguments.callee.caller;

            if (this == caller) {
                return this.baseImplementation.apply(that, args);
            } else {
                return this.apply(that, args);
            }
        } else {
            throw "base not definied";
        }
    };

    /**
     * @property {Function} base class
     */
    inherit.Base = inherit({
        ctor: function () {
        }
    });

    exports.inherit = inherit;

})(this, typeof exports === "undefined" ? this : exports);<|endoftext|>