<commit_before>/*jshint forin:false, eqnull:true*/
/* globals JSYG*/

(function(factory) {

    if (typeof define != "undefined" && define.amd) define("jsyg-pathdrawer",["jsyg-path"],factory);
    else if (typeof JSYG != "undefined") {
        if (JSYG.Path) factory(JSYG);
        else throw new Error("You need JSYG.Path");
    }
    else throw new Error("JSYG is needed");

})(function(JSYG) {

    "use strict";

    /**
     * Tracé de chemins SVG à la souris
     * @param opt optionnel, objet définissant les options.
     * @returns {PathDrawer}
     */
    function PathDrawer(opt) {

        if (opt) this.set(opt);
    }

    PathDrawer.prototype = new JSYG.StdConstruct();

    PathDrawer.prototype.constructor = PathDrawer;

    /**
     * zone sur laquelle on affecte les écouteurs d'évènements (si null, prend le parent svg le plus éloigné)
     */
    PathDrawer.prototype.area = null;
    /**
     * Type de segment utilisés pour le tracé ("L","T", etc). La valeur spéciale "autosmooth" permet un lissage
     * automatique sans se soucier des points de controle.
     */
    PathDrawer.prototype.segment = 'autosmooth';
    /**
     * Type de tracé "freehand" (à main levée) ou "point2point" (ou tout autre valeur) pour tracé point par point.
     */
    PathDrawer.prototype.type = 'freehand';
    /**
     * Indique si un tracé est en cours ou non
     */
    PathDrawer.prototype.inProgress = false;
    /**
     * Pour le tracé à main levée, indique le nombre d'évènement "mousemove" à ignorer entre chaque point
     * (sinon on aurait trop de points)
     */
    //PathDrawer.prototype.skip = 4;
    /**
     * Pour le tracé à main levée, indique la tolérance (en pixels) pour la simplification de la courbe
     * @link http://mourner.github.io/simplify-js/
     */
    PathDrawer.prototype.simplify = 1;
    /**
     * Indique la force de l'aimantation en pixels écran des points extremes entre eux.
     * La valeur null permet d'annuler l'aimantation
     */
    PathDrawer.prototype.strengthClosingMagnet = 5;
    /**
     * Ferme systématiquement ou non le chemin (segment Z)
     */
    PathDrawer.prototype.closePath = false;
    /**
     * fonction(s) à éxécuter pendant le tracé
     */
    PathDrawer.prototype.ondraw = false;
    /**
     * fonction(s) à éxécuter avant la fin du tracé
     */
    PathDrawer.prototype.onbeforeend = false;
    /**
     * fonction(s) à éxécuter à la fin du tracé
     */
    PathDrawer.prototype.onend = false;
    /**
     * fonction(s) à éxécuter avant un nouveau point (type "point2point" uniquement)
     */
    PathDrawer.prototype.onbeforenewseg = false;
    /**
     * fonction(s) à éxécuter à la création d'un nouveau point
     */
    PathDrawer.prototype.onnewseg = false;

    /**
     * Commence le tracé point à point.
     * @param e objet JSYG.Event
     * @returns {PathDrawer}
     */
    PathDrawer.prototype.drawPoint2Point = function(path,e) {

        path = new JSYG.Path(path);

        if (!path.parent().length) throw new Error("Il faut attacher l'objet path à l'arbre DOM");

        var node = path[0],
        jSvg = this.area ? new JSYG(this.area) : path.offsetParent('farthest'),
        autoSmooth = this.segment.toLowerCase() === 'autosmooth',
        segment = autoSmooth ? 'L' : this.segment,
        mtx = path.getMtx('screen').inverse(),
        xy = new JSYG.Vect(e.clientX,e.clientY).mtx(mtx),
        that = this;

        function mousemove(e) {

            var mtx = path.getMtx('screen').inverse(),
            xy = new JSYG.Vect(e.clientX,e.clientY).mtx(mtx),
            nbSegs = path.nbSegs(),
            seg = path.getSeg(nbSegs-1),
            pos,first,ref;

            if (that.strengthClosingMagnet!=null) {

                first = path.getSeg(0);
                ref = new JSYG.Vect(first.x,first.y).mtx(mtx.inverse());
                pos = new JSYG.Vect(e.clientX,e.clientY);

                if (JSYG.distance(ref,pos) < that.strengthClosingMagnet) {
                    xy.x = first.x;
                    xy.y = first.y;
                }
            }

            seg.x = xy.x;
            seg.y = xy.y;

            path.replaceSeg(nbSegs-1,seg);

            if (autoSmooth) path.autoSmooth(nbSegs-1);

            that.trigger('draw',node,e);
        }

        function mousedown(e) {

            if (that.trigger('beforenewseg',node,e) === false) return;

            //si la courbe est fermée, un clic suffit pour terminer.
            if (path.nbSegs() > 3 && path.isClosed()) {

                if (that.trigger('beforeend',node,e) === false) return;
                return that.end();
            }

            if (e.detail === 2) return; //pas d'action au double-clic

            var mtx = path.getMtx('screen').inverse(),
            xy = new JSYG.Vect(e.clientX,e.clientY).mtx(mtx);

            path.addSeg(segment,xy.x,xy.y,xy.x,xy.y,xy.x,xy.y);

            if (autoSmooth) path.autoSmooth(path.nbSegs()-1);

            that.trigger('newseg',node,e);
        }

        function dblclick(e,keepLastSeg) {

            path.removeSeg(path.nbSegs()-1);

            if (that.trigger('beforeend',node,e) === false) return;

            //path.removeSeg(path.nbSegs()-1);

            that.end();
        }

        this.end = function() {

            var first;

            if (that.closePath && !path.isClosed()) {
                first = path.getSeg(0);
                path.addSeg(segment,first.x,first.y,first.x,first.y,first.x,first.y);
            }

            if (autoSmooth) path.autoSmooth(path.nbSegs()-1);

            jSvg.off({
                'mousemove':mousemove,
                'mousedown':mousedown,
                'dblclick':dblclick
            });

            that.inProgress = false;

            that.trigger('end',node,e);

            that.end = function() { return this; };
        };

        if (path.nbSegs() === 0) path.addSeg('M',xy.x,xy.y);

        that.inProgress = true;

        jSvg.on({
            'mousemove':mousemove,
            'mousedown':mousedown,
            'dblclick':dblclick
        });

        mousedown(e);

        return this;
    };

    /**
     * Commence le tracé à main levée.
     * @param e objet Event (évènement mousedown).
     * @returns {PathDrawer}
     */
    PathDrawer.prototype.drawFreeHand = function(path,e) {

        path = new JSYG.Path(path);

        if (!path.parent().length) throw new Error("Il faut attacher l'objet path à l'arbre DOM");

        var node = path[0],
        autoSmooth = this.segment.toLowerCase() === 'autosmooth',
        segment = autoSmooth ? 'L' : this.segment,
        jSvg = this.area ? new JSYG(this.area) : path.offsetParent('farthest'),
        mtx = path.getMtx('screen').inverse(),
        xy = new JSYG.Vect(e.clientX,e.clientY).mtx(mtx),
        that = this;

        function mousemove(e) {

            var xy = new JSYG.Vect(e.clientX,e.clientY).mtx(mtx);

            path.addSeg(segment,xy.x,xy.y,xy.x,xy.y,xy.x,xy.y);
            that.trigger('newseg',node,e);

            that.trigger('draw',node,e);
        }

        function mouseup(e) {
            that.end();
            that.trigger('end',node,e);
        }

        this.end = function() {

            var nbSegs = path.nbSegs(),
            last,first;

            if (nbSegs == 1) path.remove();
            else {

                last = path.getLastSeg();
                first = path.getSeg(0);

                if (that.strengthClosingMagnet!=null) {

                    if (JSYG.distance(first,last) < that.strengthClosingMagnet) {
                        last.x = first.x;
                        last.y = first.y;
                    }

                    path.replaceSeg(nbSegs-1,last);
                }

                if (this.closePath && !path.isClosed()) {
                    path.addSeg(segment,first.x,first.y,first.x,first.y,first.x,first.y);
                }

                if (this.simplify) path.simplify(this.simplify);

                if (autoSmooth) path.autoSmooth();
            }

            that.inProgress = false;

            jSvg.off('vmousemove',mousemove);

            new JSYG(document).off('vmouseup',mouseup);

            that.end = function() { return this; };
        };

        jSvg.on('vmousemove',mousemove);
        new JSYG(document).on('vmouseup',mouseup);

        e.preventDefault();

        path.clear();
        path.addSeg('M',xy.x,xy.y);

        this.inProgress = true;

        return this;
    };

    /**
     * Commence le tracé selon le type défini ("freehand" ou "point2point")
     * @param e objet JSYG.Event (évènement mousedown).
     * @returns
     */
    PathDrawer.prototype.draw = function(path,e) {

        if (this.type.toLowerCase() === 'freehand') this.drawFreeHand(path,e);
        else this.drawPoint2Point(path,e);

        return this;
    };

    /**
     * Termine le tracé.
     * @returns {PathDrawer}
     */
    PathDrawer.prototype.end = function() { return this; };

    JSYG.PathDrawer = PathDrawer;

    return PathDrawer;

});<commit_msg>bug with amd<commit_after>/*jshint forin:false, eqnull:true*/
/* globals JSYG*/

(function(factory) {

    if (typeof define != "undefined" && define.amd) define("jsyg-pathdrawer",["jsyg","jsyg-path"],factory);
    else if (typeof JSYG != "undefined") {
        if (JSYG.Path) factory(JSYG);
        else throw new Error("You need JSYG.Path");
    }
    else throw new Error("JSYG is needed");

})(function(JSYG) {

    "use strict";

    /**
     * Tracé de chemins SVG à la souris
     * @param opt optionnel, objet définissant les options.
     * @returns {PathDrawer}
     */
    function PathDrawer(opt) {

        if (opt) this.set(opt);
    }

    PathDrawer.prototype = new JSYG.StdConstruct();

    PathDrawer.prototype.constructor = PathDrawer;

    /**
     * zone sur laquelle on affecte les écouteurs d'évènements (si null, prend le parent svg le plus éloigné)
     */
    PathDrawer.prototype.area = null;
    /**
     * Type de segment utilisés pour le tracé ("L","T", etc). La valeur spéciale "autosmooth" permet un lissage
     * automatique sans se soucier des points de controle.
     */
    PathDrawer.prototype.segment = 'autosmooth';
    /**
     * Type de tracé "freehand" (à main levée) ou "point2point" (ou tout autre valeur) pour tracé point par point.
     */
    PathDrawer.prototype.type = 'freehand';
    /**
     * Indique si un tracé est en cours ou non
     */
    PathDrawer.prototype.inProgress = false;
    /**
     * Pour le tracé à main levée, indique le nombre d'évènement "mousemove" à ignorer entre chaque point
     * (sinon on aurait trop de points)
     */
    //PathDrawer.prototype.skip = 4;
    /**
     * Pour le tracé à main levée, indique la tolérance (en pixels) pour la simplification de la courbe
     * @link http://mourner.github.io/simplify-js/
     */
    PathDrawer.prototype.simplify = 1;
    /**
     * Indique la force de l'aimantation en pixels écran des points extremes entre eux.
     * La valeur null permet d'annuler l'aimantation
     */
    PathDrawer.prototype.strengthClosingMagnet = 5;
    /**
     * Ferme systématiquement ou non le chemin (segment Z)
     */
    PathDrawer.prototype.closePath = false;
    /**
     * fonction(s) à éxécuter pendant le tracé
     */
    PathDrawer.prototype.ondraw = false;
    /**
     * fonction(s) à éxécuter avant la fin du tracé
     */
    PathDrawer.prototype.onbeforeend = false;
    /**
     * fonction(s) à éxécuter à la fin du tracé
     */
    PathDrawer.prototype.onend = false;
    /**
     * fonction(s) à éxécuter avant un nouveau point (type "point2point" uniquement)
     */
    PathDrawer.prototype.onbeforenewseg = false;
    /**
     * fonction(s) à éxécuter à la création d'un nouveau point
     */
    PathDrawer.prototype.onnewseg = false;

    /**
     * Commence le tracé point à point.
     * @param e objet JSYG.Event
     * @returns {PathDrawer}
     */
    PathDrawer.prototype.drawPoint2Point = function(path,e) {

        path = new JSYG.Path(path);

        if (!path.parent().length) throw new Error("Il faut attacher l'objet path à l'arbre DOM");

        var node = path[0],
        jSvg = this.area ? new JSYG(this.area) : path.offsetParent('farthest'),
        autoSmooth = this.segment.toLowerCase() === 'autosmooth',
        segment = autoSmooth ? 'L' : this.segment,
        mtx = path.getMtx('screen').inverse(),
        xy = new JSYG.Vect(e.clientX,e.clientY).mtx(mtx),
        that = this;

        function mousemove(e) {

            var mtx = path.getMtx('screen').inverse(),
            xy = new JSYG.Vect(e.clientX,e.clientY).mtx(mtx),
            nbSegs = path.nbSegs(),
            seg = path.getSeg(nbSegs-1),
            pos,first,ref;

            if (that.strengthClosingMagnet!=null) {

                first = path.getSeg(0);
                ref = new JSYG.Vect(first.x,first.y).mtx(mtx.inverse());
                pos = new JSYG.Vect(e.clientX,e.clientY);

                if (JSYG.distance(ref,pos) < that.strengthClosingMagnet) {
                    xy.x = first.x;
                    xy.y = first.y;
                }
            }

            seg.x = xy.x;
            seg.y = xy.y;

            path.replaceSeg(nbSegs-1,seg);

            if (autoSmooth) path.autoSmooth(nbSegs-1);

            that.trigger('draw',node,e);
        }

        function mousedown(e) {

            if (that.trigger('beforenewseg',node,e) === false) return;

            //si la courbe est fermée, un clic suffit pour terminer.
            if (path.nbSegs() > 3 && path.isClosed()) {

                if (that.trigger('beforeend',node,e) === false) return;
                return that.end();
            }

            if (e.detail === 2) return; //pas d'action au double-clic

            var mtx = path.getMtx('screen').inverse(),
            xy = new JSYG.Vect(e.clientX,e.clientY).mtx(mtx);

            path.addSeg(segment,xy.x,xy.y,xy.x,xy.y,xy.x,xy.y);

            if (autoSmooth) path.autoSmooth(path.nbSegs()-1);

            that.trigger('newseg',node,e);
        }

        function dblclick(e,keepLastSeg) {

            path.removeSeg(path.nbSegs()-1);

            if (that.trigger('beforeend',node,e) === false) return;

            //path.removeSeg(path.nbSegs()-1);

            that.end();
        }

        this.end = function() {

            var first;

            if (that.closePath && !path.isClosed()) {
                first = path.getSeg(0);
                path.addSeg(segment,first.x,first.y,first.x,first.y,first.x,first.y);
            }

            if (autoSmooth) path.autoSmooth(path.nbSegs()-1);

            jSvg.off({
                'mousemove':mousemove,
                'mousedown':mousedown,
                'dblclick':dblclick
            });

            that.inProgress = false;

            that.trigger('end',node,e);

            that.end = function() { return this; };
        };

        if (path.nbSegs() === 0) path.addSeg('M',xy.x,xy.y);

        that.inProgress = true;

        jSvg.on({
            'mousemove':mousemove,
            'mousedown':mousedown,
            'dblclick':dblclick
        });

        mousedown(e);

        return this;
    };

    /**
     * Commence le tracé à main levée.
     * @param e objet Event (évènement mousedown).
     * @returns {PathDrawer}
     */
    PathDrawer.prototype.drawFreeHand = function(path,e) {

        path = new JSYG.Path(path);

        if (!path.parent().length) throw new Error("Il faut attacher l'objet path à l'arbre DOM");

        var node = path[0],
        autoSmooth = this.segment.toLowerCase() === 'autosmooth',
        segment = autoSmooth ? 'L' : this.segment,
        jSvg = this.area ? new JSYG(this.area) : path.offsetParent('farthest'),
        mtx = path.getMtx('screen').inverse(),
        xy = new JSYG.Vect(e.clientX,e.clientY).mtx(mtx),
        that = this;

        function mousemove(e) {

            var xy = new JSYG.Vect(e.clientX,e.clientY).mtx(mtx);

            path.addSeg(segment,xy.x,xy.y,xy.x,xy.y,xy.x,xy.y);
            that.trigger('newseg',node,e);

            that.trigger('draw',node,e);
        }

        function mouseup(e) {
            that.end();
            that.trigger('end',node,e);
        }

        this.end = function() {

            var nbSegs = path.nbSegs(),
            last,first;

            if (nbSegs == 1) path.remove();
            else {

                last = path.getLastSeg();
                first = path.getSeg(0);

                if (that.strengthClosingMagnet!=null) {

                    if (JSYG.distance(first,last) < that.strengthClosingMagnet) {
                        last.x = first.x;
                        last.y = first.y;
                    }

                    path.replaceSeg(nbSegs-1,last);
                }

                if (this.closePath && !path.isClosed()) {
                    path.addSeg(segment,first.x,first.y,first.x,first.y,first.x,first.y);
                }

                if (this.simplify) path.simplify(this.simplify);

                if (autoSmooth) path.autoSmooth();
            }

            that.inProgress = false;

            jSvg.off('vmousemove',mousemove);

            new JSYG(document).off('vmouseup',mouseup);

            that.end = function() { return this; };
        };

        jSvg.on('vmousemove',mousemove);
        new JSYG(document).on('vmouseup',mouseup);

        e.preventDefault();

        path.clear();
        path.addSeg('M',xy.x,xy.y);

        this.inProgress = true;

        return this;
    };

    /**
     * Commence le tracé selon le type défini ("freehand" ou "point2point")
     * @param e objet JSYG.Event (évènement mousedown).
     * @returns
     */
    PathDrawer.prototype.draw = function(path,e) {

        if (this.type.toLowerCase() === 'freehand') this.drawFreeHand(path,e);
        else this.drawPoint2Point(path,e);

        return this;
    };

    /**
     * Termine le tracé.
     * @returns {PathDrawer}
     */
    PathDrawer.prototype.end = function() { return this; };

    JSYG.PathDrawer = PathDrawer;

    return PathDrawer;

});<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. licenses this file to you 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 React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter as Router, Redirect, Route, Switch} from 'react-router-dom'
import {getAsyncComponent} from 'async-react-component';

const APIOnBoarding = () => import('./components/Apis/OnBoarding/listing');
const Indexpage = () => import('../pages/index');

class Publisher extends  React.Component  {

    render(){
        return(
            <Router>
                <Switch>
                    <Route path={"/apis/"} component={getAsyncComponent(APIOnBoarding)}/>
                    <Route path={"/"} component={getAsyncComponent(Indexpage)}/>
                </Switch>
            </Router>
        );
    };
}

export default Publisher;<commit_msg>Add base path<commit_after>/*
 * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. licenses this file to you 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 React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter as Router, Redirect, Route, Switch} from 'react-router-dom'
import {getAsyncComponent} from 'async-react-component';

const APIOnBoarding = () => import('./components/Apis/OnBoarding/listing');
const Indexpage = () => import('../pages/index');

class Publisher extends  React.Component  {

    render(){
        return(
            <Router basename="/publisher">
                <Switch>
                    <Route path={"/apis/"} component={getAsyncComponent(APIOnBoarding)}/>
                    <Route path={"/"} component={getAsyncComponent(Indexpage)}/>
                </Switch>
            </Router>
        );
    };
}

export default Publisher;<|endoftext|>


<commit_before>var OperationManager = function(_options) {
    this.options = $.extend({
        prefix: "",
        operationKey: null,
        isLite: false,
        controllerUrl: null,
        onOk: null,
        onCancelled: null,
        requestExtraJsonData: null
    }, _options);
};

OperationManager.prototype = {

    runtimeInfo: function() {
        return RuntimeInfoFor(this.options.prefix);
    },

    pf: function(s) {
        return "#" + this.options.prefix.compose(s);
    },

    newPrefix: function() {
        return "New".compose(this.options.prefix);
    },

    requestData: function(newPrefix) {
        log("OperationManager requestData");
        var formChildren = "";
        if (isFalse(this.options.isLite)) {
            if (empty(this.options.prefix)) //NormalWindow
                formChildren = $("form *");
            else //PopupWindow
                formChildren = $(this.pf("panelPopup *") + ", #" + sfReactive + ", #" + sfTabId);
        }
        else {
            formChildren = $('#' + sfTabId);
        }
        formChildren = formChildren.not(".searchControl *");
        var requestData = formChildren.serialize();

        var info = this.runtimeInfo();
        var runtimeType = info.runtimeType();

        var myRuntimeInfoKey = this.options.prefix.compose(sfRuntimeInfo);
        if (formChildren.filter("[name=" + myRuntimeInfoKey + "]").length  == 0) {
            if (empty(runtimeType))
                requestData += qp(myRuntimeInfoKey, info.createValue(StaticInfoFor(this.options.prefix).staticType(), info.id(), info.isNew(), info.ticks()));
            else
                requestData += qp(myRuntimeInfoKey, info.find().val());
        }
        requestData += qp("isLite", this.options.isLite)
                     //+ qp("sfRuntimeType", empty(runtimeType) ? StaticInfoFor(this.options.prefix).staticType() : runtimeType)
                     //+ qp("sfId", info.id())
                     + qp("sfOperationFullKey", this.options.operationKey)
                     + qp(sfPrefix, newPrefix)
                     + qp("sfOldPrefix", this.options.prefix)
                     + qp("sfOnOk", singleQuote(this.options.onOk));

        if (!empty(this.options.requestExtraJsonData)) {
            for (var key in this.options.requestExtraJsonData) {
                if (jQuery.isFunction(this.options.requestExtraJsonData[key]))
                    requestData += qp(key, this.options.requestExtraJsonData[key]());
                else
                    requestData += qp(key, this.options.requestExtraJsonData[key]);
            }
        }

        return requestData;
    },

    operationAjax: function(newPrefix, onSuccess)
    {
        log("OperationManager operationAjax");

        NotifyInfo(lang['executingOperation']);

        if (empty(newPrefix))
            newPrefix = this.options.prefix;

        var self = this;
        $.ajax({
            type: "POST",
            url: this.options.controllerUrl,
            data: this.requestData(newPrefix),
            async: false,
            dataType: "html",
            success: function(operationResult) {
                if (self.executedSuccessfully(operationResult)) {
                    if (onSuccess != null)
                        onSuccess(newPrefix, operationResult);
                }
                else{
                    NotifyInfo(lang['error'], 2000);
                    return;
                }
             },
             error:
                function() { NotifyInfo(lang['error'], 2000); }
        });
    },

    operationSubmit: function()
    {
        log("OperationManager operationSubmit");

////        var info = this.runtimeInfo();
////        if (info.find().length > 0)
////        {
////            $("form").append(hiddenInput("sfRuntimeType", info.runtimeType()) +
////                hiddenInput('sfId', info.id()));
////        }

//        var info = this.runtimeInfo();
//        var runtimeType = info.runtimeType();

//        var myRuntimeInfoKey = this.options.prefix.compose(sfRuntimeInfo);
//        if ($(":input:hidden[name=" + myRuntimeInfoKey + "]").length  == 0) {
//            if (empty(runtimeType))
//                hiddenInput(myRuntimeInfoKey, info.createValue(StaticInfoFor(this.options.prefix).staticType(), info.id(), info.isNew(), info.ticks()));
//            else
//                hiddenInput(myRuntimeInfoKey, info.find().val());
//        }

        $("form").append(hiddenInput('isLite', this.options.isLite) +
            hiddenInput('sfOperationFullKey', this.options.operationKey) +
            hiddenInput("sfOldPrefix", this.options.prefix));

        if (!empty(this.options.requestExtraJsonData)) {
            for (var key in this.options.requestExtraJsonData) {
                if (jQuery.isFunction(this.options.requestExtraJsonData[key]))
                    $("form").append(hiddenInput(key, this.options.requestExtraJsonData[key]()));
                else
                    $("form").append(hiddenInput(key, this.options.requestExtraJsonData[key]));
            }
        }

        Submit(this.options.controllerUrl);
    },

    executedSuccessfully: function(operationResult) {
        log("OperationManager executedSuccessfully");
        if (operationResult.indexOf("ModelState") < 0)
            return true;

        eval('var result=' + operationResult);
        var modelState = result["ModelState"];
        if (empty(this.options.prefix))
            new Validator().showErrors(modelState);
        else {
            var info = this.runtimeInfo();
            new PartialValidator({ prefix: this.options.prefix, type: info.runtimeType(), id: info.id() }).showErrors(modelState);
        }
        return false;
    },

    defaultSubmit: function() {
        log("OperationManager defaultSubmit");

        if (isTrue(this.options.isLite))
            operationSubmit();
        else {
            var onSuccess = function() { this.operationSubmit(); };
            var self = this;
            if (!EntityIsValid({prefix:this.options.prefix}, function(){onSuccess.call(self)}))
                return;
        }
    }
};

var OperationExecutor = function(_options) {
    OperationManager.call(this, $.extend({
        controllerUrl: "Operation/OperationExecute"
    }, _options));

    this.defaultExecute = function() {
        log("OperationExecutor defaultExecute");

        var onSuccess = function()
        {
            this.operationAjax(null, OpReloadContent);
            NotifyInfo(lang['operationExecuted'], 2000);
        };

        var self = this;
        if (isTrue(this.options.isLite))
            onSuccess.call(this);
        else {
            if (!EntityIsValid({ prefix: this.options.prefix }, function() { onSuccess.call(self) }))
                return;
        }
    };
};

OperationExecutor.prototype = new OperationManager();

//ConstructorFrom options = OperationManager options + returnType
var ConstructorFrom = function(_options) {
    OperationManager.call(this, $.extend({
        controllerUrl: "Operation/ConstructFromExecute",
        returnType: null
    }, _options));

    this.defaultConstruct = function() {
        log("ConstructorFrom construct");

        var onSuccess = function()
        {
            this.operationAjax(this.newPrefix(), OpOpenPopup);
            NotifyInfo(lang['operationExecuted'], 2000);
        }

        var self = this;
        if (isTrue(this.options.isLite))
            onSuccess.call(this);
        else {
            if (!EntityIsValid({ prefix: this.options.prefix }, function() { onSuccess.call(self) }))
                return;
        }
    };
};

ConstructorFrom.prototype = new OperationManager();

var DeleteExecutor = function(_options) {
    OperationManager.call(this, $.extend({
        controllerUrl: "Operation/DeleteExecute"
    }, _options));

    this.execute = function() {
        log("DeleteOperation delete");

        if (!empty(this.options.confirmMsg) && !confirm(this.options.confirmMsg))
            return;

        NotifyInfo(lang['executingOperation']);

        if (!this.options.avoidValidation && isFalse(this.options.isLite)) {
            if (!this.entityIsValid()) {
                NotifyInfo(lang['error'], 2000);
                return;
            }
        }

        var self = this;
        $.ajax({
            type: "POST",
            url: this.options.controllerUrl,
            data: this.requestData(this.newPrefix()),
            async: false,
            dataType: "html",
            success: function(operationResult) {
                if (!self.executedSuccessfully(operationResult)) {
                    NotifyInfo(lang['error'], 2000);
                    return;
                }

                if (self.options.navigateOnSuccess) {
                    Submit(operationResult);
                    return;
                }

                if (!empty(self.options.onOperationSuccess))
                    self.options.onOperationSuccess();

                NotifyInfo(lang['operationExecuted'], 2000);
            },
            error:
                function() { NotifyInfo(lang['error'], 2000); }
        });
    };
};

DeleteExecutor.prototype = new OperationManager();

function OperationDelete(deleteExecutor) {
    deleteExecutor.execute();
}

//ConstructorFromMany options = OperationManager options + returnType
var ConstructorFromMany = function(_options) {
    OperationManager.call(this, $.extend({
        controllerUrl: "Operation/ConstructFromManyExecute",
        returnType: null
    }, _options));

    this.requestData = function(newPrefix, items) {
        log("ConstructorFromMany requestData");

        var requestData = $('#' + sfTabId).serialize();
        requestData += qp("sfRuntimeType", $(this.pf(sfEntityTypeName)).val())
                     + qp("sfOperationFullKey", this.options.operationKey)
                     + qp(sfPrefix, newPrefix)
                     + qp("sfOldPrefix", this.options.prefix)
                     + qp("sfOnOk", singleQuote(this.options.onOk));

        for(var i = 0; i<items.length; i++)
            requestData += qp("sfIds", items[i].id);

        if (!empty(this.options.requestExtraJsonData)) {
            for (var key in this.options.requestExtraJsonData) {
                if (jQuery.isFunction(this.options.requestExtraJsonData[key]))
                    requestData += qp(key, this.options.requestExtraJsonData[key]());
                else
                    requestData += qp(key, this.options.requestExtraJsonData[key]);
            }
        }

        return requestData;
    };

    this.operationAjax = function(newPrefix, items, onSuccess)
    {
        log("ConstructorFromMany operationAjax");

        NotifyInfo(lang['executingOperation']);

        var self = this;
        $.ajax({
            type: "POST",
            url: this.options.controllerUrl,
            data: this.requestData(this.newPrefix(), items),
            async: false,
            dataType: "html",
            success: function(operationResult) {
                if (self.executedSuccessfully(operationResult)) {
                    if (onSuccess != null)
                        onSuccess(newPrefix, operationResult);
                }
                else{
                    NotifyInfo(lang['error'], 2000);
                    return;
                }
             },
             error:
                function() { NotifyInfo(lang['error'], 2000); }
        });
    };

    this.defaultConstruct = function() {
        log("ConstructorFromMany defaultConstruct");

        var onSuccess = function(items)
        {
            this.operationAjax(this.newPrefix(), items, OpOpenPopup);
            NotifyInfo(lang['operationExecuted'], 2000);
        }

        var self = this;
        HasSelectedItems({ prefix: this.newPrefix() }, onSuccess);
    };
};

ConstructorFromMany.prototype = new OperationManager();

function OperationConstructFromMany(constructorFrom) {
    constructorFromMany.construct();
}

function ReloadEntity(urlController, prefix, parentDiv) {
    $.ajax({
        type: "POST",
        url: urlController,
        data: $("form *").not(".searchControl *").serialize() + qp(sfPrefix, prefix) + qp(sfPartialViewName, $('#' + sfPartialViewName).val()),
        async: false,
        dataType: "html",
        success: function(msg) {
           if (!empty(parentDiv))
               $('#' + parentDiv).html(msg);
           else
               $('#' + prefix.compose("divNormalControl")).html(msg);
        }
    });
}

function OpReloadContent(prefix, operationResult){
    log("OperationExecutor defaultOnSuccess");
    if (empty(prefix)) //NormalWindow
        $("#divNormalControl").html(operationResult);
    else { //PopupWindow
        new ViewNavigator({
            prefix: prefix,
            containerDiv: prefix.compose("externalPopupDiv")
        }).viewSave(operationResult);
    }
}

function OpOpenPopup(prefix, operationResult)
{
    new ViewNavigator({ prefix: prefix }).showCreateSave(operationResult);
}

function OpOpenPopupNoDefaultOk(prefix, operationResult)
{
    new ViewNavigator({ prefix: prefix, onOk: function(){ return false; }}).showCreateSave(operationResult);
}

function OpNavigate(prefix, operationResult)
{
    Submit(operationResult);
}

<commit_msg>(TFS CS 5269)<commit_after>var OperationManager = function(_options) {
    this.options = $.extend({
        prefix: "",
        operationKey: null,
        isLite: false,
        controllerUrl: null,
        onOk: null,
        onCancelled: null,
        requestExtraJsonData: null
    }, _options);
};

OperationManager.prototype = {

    runtimeInfo: function() {
        return RuntimeInfoFor(this.options.prefix);
    },

    pf: function(s) {
        return "#" + this.options.prefix.compose(s);
    },

    newPrefix: function() {
        return "New".compose(this.options.prefix);
    },

    requestData: function(newPrefix) {
        log("OperationManager requestData");
        var formChildren = "";
        if (isFalse(this.options.isLite)) {
            if (empty(this.options.prefix)) //NormalWindow
                formChildren = $("form *");
            else //PopupWindow
                formChildren = $(this.pf("panelPopup *") + ", #" + sfReactive + ", #" + sfTabId);
        }
        else {
            formChildren = $('#' + sfTabId);
        }
        formChildren = formChildren.not(".searchControl *");
        var requestData = formChildren.serialize();

        var info = this.runtimeInfo();
        var runtimeType = info.runtimeType();

        var myRuntimeInfoKey = this.options.prefix.compose(sfRuntimeInfo);
        if (formChildren.filter("[name=" + myRuntimeInfoKey + "]").length  == 0) {
            if (empty(runtimeType))
                requestData += qp(myRuntimeInfoKey, info.createValue(StaticInfoFor(this.options.prefix).staticType(), info.id(), info.isNew(), info.ticks()));
            else
                requestData += qp(myRuntimeInfoKey, info.find().val());
        }
        requestData += qp("isLite", this.options.isLite)
                     //+ qp("sfRuntimeType", empty(runtimeType) ? StaticInfoFor(this.options.prefix).staticType() : runtimeType)
                     //+ qp("sfId", info.id())
                     + qp("sfOperationFullKey", this.options.operationKey)
                     + qp(sfPrefix, newPrefix)
                     + qp("sfOldPrefix", this.options.prefix)
                     + qp("sfOnOk", singleQuote(this.options.onOk));

        if (!empty(this.options.requestExtraJsonData)) {
            for (var key in this.options.requestExtraJsonData) {
                if (jQuery.isFunction(this.options.requestExtraJsonData[key]))
                    requestData += qp(key, this.options.requestExtraJsonData[key]());
                else
                    requestData += qp(key, this.options.requestExtraJsonData[key]);
            }
        }

        return requestData;
    },

    operationAjax: function(newPrefix, onSuccess)
    {
        log("OperationManager operationAjax");

        NotifyInfo(lang['executingOperation']);

        if (empty(newPrefix))
            newPrefix = this.options.prefix;

        var self = this;
        $.ajax({
            type: "POST",
            url: this.options.controllerUrl,
            data: this.requestData(newPrefix),
            async: false,
            dataType: "html",
            success: function(operationResult) {
                if (self.executedSuccessfully(operationResult)) {
                    if (onSuccess != null)
                        onSuccess(newPrefix, operationResult);
                }
                else{
                    NotifyInfo(lang['error'], 2000);
                    return;
                }
             },
             error:
                function() { NotifyInfo(lang['error'], 2000); }
        });
    },

    operationSubmit: function()
    {
        log("OperationManager operationSubmit");

////        var info = this.runtimeInfo();
////        if (info.find().length > 0)
////        {
////            $("form").append(hiddenInput("sfRuntimeType", info.runtimeType()) +
////                hiddenInput('sfId', info.id()));
////        }

//        var info = this.runtimeInfo();
//        var runtimeType = info.runtimeType();

//        var myRuntimeInfoKey = this.options.prefix.compose(sfRuntimeInfo);
//        if ($(":input:hidden[name=" + myRuntimeInfoKey + "]").length  == 0) {
//            if (empty(runtimeType))
//                hiddenInput(myRuntimeInfoKey, info.createValue(StaticInfoFor(this.options.prefix).staticType(), info.id(), info.isNew(), info.ticks()));
//            else
//                hiddenInput(myRuntimeInfoKey, info.find().val());
//        }

        $("form").append(hiddenInput('isLite', this.options.isLite) +
            hiddenInput('sfOperationFullKey', this.options.operationKey) +
            hiddenInput("sfOldPrefix", this.options.prefix));

        if (!empty(this.options.requestExtraJsonData)) {
            for (var key in this.options.requestExtraJsonData) {
                if (jQuery.isFunction(this.options.requestExtraJsonData[key]))
                    $("form").append(hiddenInput(key, this.options.requestExtraJsonData[key]()));
                else
                    $("form").append(hiddenInput(key, this.options.requestExtraJsonData[key]));
            }
        }

        Submit(this.options.controllerUrl);
    },

    executedSuccessfully: function(operationResult) {
        log("OperationManager executedSuccessfully");
        if (operationResult.indexOf("ModelState") < 0)
            return true;

        eval('var result=' + operationResult);
        var modelState = result["ModelState"];
        if (empty(this.options.prefix))
            new Validator().showErrors(modelState);
        else {
            var info = this.runtimeInfo();
            new PartialValidator({ prefix: this.options.prefix, type: info.runtimeType(), id: info.id() }).showErrors(modelState);
        }
        return false;
    },

    defaultSubmit: function() {
        log("OperationManager defaultSubmit");

        if (isTrue(this.options.isLite))
            operationSubmit();
        else {
            var onSuccess = function() { this.operationSubmit(); };
            var self = this;
            if (!EntityIsValid({prefix:this.options.prefix}, function(){onSuccess.call(self)}))
                return;
        }
    }
};

var OperationExecutor = function(_options) {
    OperationManager.call(this, $.extend({
        controllerUrl: "Operation/OperationExecute"
    }, _options));

    this.defaultExecute = function() {
        log("OperationExecutor defaultExecute");

        var onSuccess = function()
        {
            this.operationAjax(null, OpReloadContent);
        };

        var self = this;
        if (isTrue(this.options.isLite))
            onSuccess.call(this);
        else {
            if (!EntityIsValid({ prefix: this.options.prefix }, function() { onSuccess.call(self) }))
                return;
        }
    };
};

OperationExecutor.prototype = new OperationManager();

//ConstructorFrom options = OperationManager options + returnType
var ConstructorFrom = function(_options) {
    OperationManager.call(this, $.extend({
        controllerUrl: "Operation/ConstructFromExecute",
        returnType: null
    }, _options));

    this.defaultConstruct = function() {
        log("ConstructorFrom construct");

        var onSuccess = function()
        {
            this.operationAjax(this.newPrefix(), OpOpenPopup);
        }

        var self = this;
        if (isTrue(this.options.isLite))
            onSuccess.call(this);
        else {
            if (!EntityIsValid({ prefix: this.options.prefix }, function() { onSuccess.call(self) }))
                return;
        }
    };
};

ConstructorFrom.prototype = new OperationManager();

var DeleteExecutor = function(_options) {
    OperationManager.call(this, $.extend({
        controllerUrl: "Operation/DeleteExecute"
    }, _options));

    this.execute = function() {
        log("DeleteOperation delete");

        if (!empty(this.options.confirmMsg) && !confirm(this.options.confirmMsg))
            return;

        NotifyInfo(lang['executingOperation']);

        if (!this.options.avoidValidation && isFalse(this.options.isLite)) {
            if (!this.entityIsValid()) {
                NotifyInfo(lang['error'], 2000);
                return;
            }
        }

        var self = this;
        $.ajax({
            type: "POST",
            url: this.options.controllerUrl,
            data: this.requestData(this.newPrefix()),
            async: false,
            dataType: "html",
            success: function(operationResult) {
                if (!self.executedSuccessfully(operationResult)) {
                    NotifyInfo(lang['error'], 2000);
                    return;
                }

                if (self.options.navigateOnSuccess) {
                    Submit(operationResult);
                    return;
                }

                if (!empty(self.options.onOperationSuccess))
                    self.options.onOperationSuccess();

                NotifyInfo(lang['operationExecuted'], 2000);
            },
            error:
                function() { NotifyInfo(lang['error'], 2000); }
        });
    };
};

DeleteExecutor.prototype = new OperationManager();

function OperationDelete(deleteExecutor) {
    deleteExecutor.execute();
}

//ConstructorFromMany options = OperationManager options + returnType
var ConstructorFromMany = function(_options) {
    OperationManager.call(this, $.extend({
        controllerUrl: "Operation/ConstructFromManyExecute",
        returnType: null
    }, _options));

    this.requestData = function(newPrefix, items) {
        log("ConstructorFromMany requestData");

        var requestData = $('#' + sfTabId).serialize();
        requestData += qp("sfRuntimeType", $(this.pf(sfEntityTypeName)).val())
                     + qp("sfOperationFullKey", this.options.operationKey)
                     + qp(sfPrefix, newPrefix)
                     + qp("sfOldPrefix", this.options.prefix)
                     + qp("sfOnOk", singleQuote(this.options.onOk));

        for(var i = 0; i<items.length; i++)
            requestData += qp("sfIds", items[i].id);

        if (!empty(this.options.requestExtraJsonData)) {
            for (var key in this.options.requestExtraJsonData) {
                if (jQuery.isFunction(this.options.requestExtraJsonData[key]))
                    requestData += qp(key, this.options.requestExtraJsonData[key]());
                else
                    requestData += qp(key, this.options.requestExtraJsonData[key]);
            }
        }

        return requestData;
    };

    this.operationAjax = function(newPrefix, items, onSuccess)
    {
        log("ConstructorFromMany operationAjax");

        NotifyInfo(lang['executingOperation']);

        var self = this;
        $.ajax({
            type: "POST",
            url: this.options.controllerUrl,
            data: this.requestData(this.newPrefix(), items),
            async: false,
            dataType: "html",
            success: function(operationResult) {
                if (self.executedSuccessfully(operationResult)) {
                    if (onSuccess != null)
                        onSuccess(newPrefix, operationResult);
                }
                else{
                    NotifyInfo(lang['error'], 2000);
                    return;
                }
             },
             error:
                function() { NotifyInfo(lang['error'], 2000); }
        });
    };

    this.defaultConstruct = function() {
        log("ConstructorFromMany defaultConstruct");

        var onSuccess = function(items)
        {
            this.operationAjax(this.newPrefix(), items, OpOpenPopup);
        }

        var self = this;
        HasSelectedItems({ prefix: this.newPrefix() }, onSuccess);
    };
};

ConstructorFromMany.prototype = new OperationManager();

function OperationConstructFromMany(constructorFrom) {
    constructorFromMany.construct();
}

function ReloadEntity(urlController, prefix, parentDiv) {
    $.ajax({
        type: "POST",
        url: urlController,
        data: $("form *").not(".searchControl *").serialize() + qp(sfPrefix, prefix) + qp(sfPartialViewName, $('#' + sfPartialViewName).val()),
        async: false,
        dataType: "html",
        success: function(msg) {
           if (!empty(parentDiv))
               $('#' + parentDiv).html(msg);
           else
               $('#' + prefix.compose("divNormalControl")).html(msg);
        }
    });
}

function OpReloadContent(prefix, operationResult){
    log("OperationExecutor defaultOnSuccess");
    if (empty(prefix)) //NormalWindow
        $("#divNormalControl").html(operationResult);
    else { //PopupWindow
        new ViewNavigator({
            prefix: prefix,
            containerDiv: prefix.compose("externalPopupDiv")
        }).viewSave(operationResult);
    }
}

function OpOpenPopup(prefix, operationResult)
{
    new ViewNavigator({ prefix: prefix }).showCreateSave(operationResult);
    NotifyInfo(lang['operationExecuted'], 2000);
}

function OpOpenPopupNoDefaultOk(prefix, operationResult)
{
    new ViewNavigator({ prefix: prefix, onOk: function() { return false; } }).showCreateSave(operationResult);
    NotifyInfo(lang['operationExecuted'], 2000);
}

function OpNavigate(prefix, operationResult)
{
    Submit(operationResult);
}

<|endoftext|>


<commit_before>/*
Mif.Tree.Checkbox
*/
Mif.Tree.implement({

	initCheckbox: function(type){
		this.checkboxType=type||'simple';
		this.dfltState.checked='unchecked';
		this.wrapper.addEvent('click',this.checkboxClick.bindWithEvent(this));
		if(this.checkboxType=='simple') return;
		this.addEvent('loadChildren', function(node){
			if(node.state.checked=='unchecked') return;
			node.recursive(function(){
				this.state.checked='checked';
			});
		});
	},

	checkboxClick: function(event){
		if(this.mouse.target!='checkbox') {return;}
		this.mouse.node['switch']();
	},

	getChecked: function(){
		var checked=[];
		this.root.recursive(function(){
			if(this.state.checked) checked.push(checked);
		});
		return checked;
	}

});

Mif.Tree.Node.implement({

	'switch' : function(state){
		if(this.state.checked==state) return;
		var type=this.tree.checkboxType;
		var checked=(this.state.checked=='checked') ? 'unchecked' : 'checked';
		var setState=function(node, state){
			var oldState=node.state.checked;
			node.state.checked=state;
			if(!node.parentNode || (node.parentNode && node.parentNode.$draw)){
				node.getDOM('checkbox').removeClass('mif-tree-node-'+oldState).addClass('mif-tree-node-'+state);
			}
		};
		if(type=='simple'){
			setState(this, checked);
			return false;
		};
		this.recursive(function(){
			setState(this, checked);
		});
		function setParentCheckbox(node){
			if(!node.parentNode || (node.tree.forest && !node.parentNode.parentNode)) return;
			var parent=node.parentNode;
			var state='';
			var children=parent.children;
			for(var i=children.length; i--; i>0){
				var child=children[i];
				var childState=child.state.checked;
				if(childState=='partially'){
					state='partially';
					break;
				}else if(childState=='checked'){
					if(state=='unchecked'){
						state='partially';
						break;
					}
					state='checked';
				}else{
					if(state=='checked'){
						state='partially';
						break;
					}else{
						state='unchecked';
					}
				}
			}
			if(parent.state.checked==state){return;};
			setState(parent, state);
			setParentCheckbox(parent);
		}
		setParentCheckbox(this);
	}

});
<commit_msg>fixed checkbox bug.<commit_after>/*
Mif.Tree.Checkbox
*/
Mif.Tree.implement({

	initCheckbox: function(type){
		this.checkboxType=type||'simple';
		this.dfltState.checked='unchecked';
		this.wrapper.addEvent('click',this.checkboxClick.bindWithEvent(this));
		if(this.checkboxType=='simple') return;
		this.addEvent('loadChildren', function(node){
			if(!node || node.state.checked=='unchecked') return;
			node.recursive(function(){
				this.state.checked='checked';
			});
		});
	},

	checkboxClick: function(event){
		if(this.mouse.target!='checkbox') {return;}
		this.mouse.node['switch']();
	},

	getChecked: function(){
		var checked=[];
		this.root.recursive(function(){
			if(this.state.checked) checked.push(checked);
		});
		return checked;
	}

});

Mif.Tree.Node.implement({

	'switch' : function(state){
		if(this.state.checked==state) return;
		var type=this.tree.checkboxType;
		var checked=(this.state.checked=='checked') ? 'unchecked' : 'checked';
		var setState=function(node, state){
			var oldState=node.state.checked;
			node.state.checked=state;
			if(!node.parentNode || (node.parentNode && node.parentNode.$draw)){
				node.getDOM('checkbox').removeClass('mif-tree-node-'+oldState).addClass('mif-tree-node-'+state);
			}
		};
		if(type=='simple'){
			setState(this, checked);
			return false;
		};
		this.recursive(function(){
			setState(this, checked);
		});
		function setParentCheckbox(node){
			if(!node.parentNode || (node.tree.forest && !node.parentNode.parentNode)) return;
			var parent=node.parentNode;
			var state='';
			var children=parent.children;
			for(var i=children.length; i--; i>0){
				var child=children[i];
				var childState=child.state.checked;
				if(childState=='partially'){
					state='partially';
					break;
				}else if(childState=='checked'){
					if(state=='unchecked'){
						state='partially';
						break;
					}
					state='checked';
				}else{
					if(state=='checked'){
						state='partially';
						break;
					}else{
						state='unchecked';
					}
				}
			}
			if(parent.state.checked==state){return;};
			setState(parent, state);
			setParentCheckbox(parent);
		}
		setParentCheckbox(this);
	}

});
<|endoftext|>


<commit_before>var syncManager = require('lsyncmanager')
  , host = "http://localhost:8042/"
  , fs = require('fs')
  , locker = require('../Common/node/locker')
  , request = require('request')
  , https = require('https')
  , querystring = require('querystring')
  , lconfig = require('../Common/node/lconfig')
  , foursquare = {"provider" : "foursquare",
      "accessTokenResponse" : "json",
      "endPoint" : "https://foursquare.com/oauth2/",
      "redirectURI" : "auth/foursquare/auth",
      "grantType" : "authorization_code"}
  , facebook = {"provider" : "facebook",
      "endPoint" : "https://graph.facebook.com/oauth",
      "redirectURI" : "auth/facebook/auth",
      "grantType" : ''}
  , github = {"provider" : "github",
      "endPoint" : "https://github.com/login/oauth",
      "redirectURI" : "auth/github/auth"}
  , gcontacts = {"provider" : "gcontacts",
      "endPoint" : "https://accounts.google.com/o/oauth2/token",
      "redirectURI" : "auth/gcontacts/auth",
      "grantType" : "authorization_code"}
  , apiKeys = {}
  ;

try{
    apiKeys = JSON.parse(fs.readFileSync(lconfig.lockerDir + "/" + lconfig.me + "/apikeys.json", 'ascii'))
}catch(e){}

module.exports = function(locker) {
    locker.get('/auth/foursquare/auth', function(req, res) {
        handleOAuth2(req.param('code'), foursquare, res);
    });
    locker.get('/auth/facebook/auth', function(req, res) {
        handleOAuth2(req.param('code'), facebook, res);
    });
    locker.get('/auth/github/auth', function(req, res) {
        handleOAuth2(req.param('code'), github, res);
    });
    locker.get('/auth/gcontacts/auth', function(req, res) {
        handleOAuth2Post(req.param('code'), gcontacts, res);
    });
    locker.get('/auth/twitter/auth', function(req, res) {
        handleTwitter(req, res);
    });
};

function handleOAuth2 (code, options, res) {
    var newUrl = options.endPoint + '/access_token' +
                    '?client_id=' + apiKeys[options.provider].appKey +
                    '&client_secret=' + apiKeys[options.provider].appSecret +
                    '&grant_type=' + options.grantType +
                    '&redirect_uri=' + host + options.redirectURI +
                    '&code=' + code;
    request.get({url:newUrl}, function(err, resp, body) {
        auth = {};
        if (options.accessTokenResponse == 'json') {
            auth.accessToken = JSON.parse(body).access_token;
        } else {
            auth.accessToken = querystring.parse(body).access_token;
        }
        if (options.provider === 'github') {
            request.get({url:"https://github.com/api/v2/json/user/show?access_token=" + auth.accessToken}, function(err, resp, body) {
                try {
                    var resp = JSON.parse(body);
                    auth.username = resp.user.login;
                    installSynclet(options.provider, auth);
                } catch (e) {
                    console.error('Failed to auth github - ' + body);
                }
            });
        } else {
            installSynclet(options.provider, auth);
        }
        res.end("<script type='text/javascript'> window.close(); </script>");
    });
}

function handleOAuth2Post (code, options, res) {
    var postData = {grant_type:options.grantType,
              code:code,
              client_id:apiKeys[options.provider].appKey,
              client_secret:apiKeys[options.provider].appSecret,
              redirect_uri:host + options.redirectURI};
    // request won't ever return here.  no idea why.
    //
    // request({method: 'post', uri :options.endPoint, body: querystring.stringify(postData)}, function(err, resp, body) {
    //     console.error(err);
    //     console.error(resp);
    //     console.error(body);
    //     auth = {};
    //     auth.token = JSON.parse(data);
    //     installSynclet(options.provider, auth);
    //     res.end("<script type='text/javascript'>if (window.opener) { window.opener.location.reload(true); } window.close(); </script>");
    // });

    var httpOptions = {
        host: 'accounts.google.com',
        port: 443,
        path: '/o/oauth2/token',
        method: 'POST',
        headers: {'Content-Type':'application/x-www-form-urlencoded'}
    };
    var httpsReq = https.request(httpOptions, function(httpsRes) {
        httpsRes.on('data', function(data) {
            auth = {};
            auth.clientID = apiKeys[options.provider].appKey;
            auth.clientSecret = apiKeys[options.provider].appSecret;
            auth.token = JSON.parse(data);
            installSynclet(options.provider, auth);
            res.end("<script type='text/javascript'> window.close(); </script>");
        });
    });
    httpsReq.write(querystring.stringify(postData));
    httpsReq.on('error', function(e) {
        callback(e, null);
    });
    httpsReq.end();
}

function handleTwitter (req, res) {
    // twitter's annoying.
    // for the current ghetto flow, we're only allowing 1 twitter synclet to be installed
    // unless i come up with a better solution
    //
    var installed = syncManager.synclets().installed;
    for (var i in installed) {
        if (i == 'twitter') {
            return res.end('twitter already installed!!!');
        }
    }
    require('../Connectors/twitter/twitter_client')(apiKeys.twitter.appKey, apiKeys.twitter.appSecret, host + "auth/twitter/auth")
        .getAccessToken(req, res, function(err, newToken) {
            var auth = {};
            auth.consumerKey = apiKeys.twitter.appKey;
            auth.consumerSecret = apiKeys.twitter.appSecret;
            auth.token = newToken;
            installSynclet("twitter", auth);
            res.end("<script type='text/javascript'> window.close(); </script>");
        });
}

function installSynclet (provider, auth) {
    var avail = syncManager.synclets().available;
    var newSynclet;
    for (var i = 0; i < avail.length; i++) {
        if (avail[i].provider == provider) newSynclet = avail[i];
    }
    newSynclet.auth = auth;
    var svcInfo = syncManager.install(newSynclet);
    syncManager.syncNow(svcInfo.id, function() {});
}<commit_msg>Revert "dont refresh opener"<commit_after>var syncManager = require('lsyncmanager')
  , host = "http://localhost:8042/"
  , fs = require('fs')
  , locker = require('../Common/node/locker')
  , request = require('request')
  , https = require('https')
  , querystring = require('querystring')
  , lconfig = require('../Common/node/lconfig')
  , foursquare = {"provider" : "foursquare",
      "accessTokenResponse" : "json",
      "endPoint" : "https://foursquare.com/oauth2/",
      "redirectURI" : "auth/foursquare/auth",
      "grantType" : "authorization_code"}
  , facebook = {"provider" : "facebook",
      "endPoint" : "https://graph.facebook.com/oauth",
      "redirectURI" : "auth/facebook/auth",
      "grantType" : ''}
  , github = {"provider" : "github",
      "endPoint" : "https://github.com/login/oauth",
      "redirectURI" : "auth/github/auth"}
  , gcontacts = {"provider" : "gcontacts",
      "endPoint" : "https://accounts.google.com/o/oauth2/token",
      "redirectURI" : "auth/gcontacts/auth",
      "grantType" : "authorization_code"}
  , apiKeys = {}
  ;

try{
    apiKeys = JSON.parse(fs.readFileSync(lconfig.lockerDir + "/" + lconfig.me + "/apikeys.json", 'ascii'))
}catch(e){}

module.exports = function(locker) {
    locker.get('/auth/foursquare/auth', function(req, res) {
        handleOAuth2(req.param('code'), foursquare, res);
    });
    locker.get('/auth/facebook/auth', function(req, res) {
        handleOAuth2(req.param('code'), facebook, res);
    });
    locker.get('/auth/github/auth', function(req, res) {
        handleOAuth2(req.param('code'), github, res);
    });
    locker.get('/auth/gcontacts/auth', function(req, res) {
        handleOAuth2Post(req.param('code'), gcontacts, res);
    });
    locker.get('/auth/twitter/auth', function(req, res) {
        handleTwitter(req, res);
    });
};

function handleOAuth2 (code, options, res) {
    var newUrl = options.endPoint + '/access_token' +
                    '?client_id=' + apiKeys[options.provider].appKey +
                    '&client_secret=' + apiKeys[options.provider].appSecret +
                    '&grant_type=' + options.grantType +
                    '&redirect_uri=' + host + options.redirectURI +
                    '&code=' + code;
    request.get({url:newUrl}, function(err, resp, body) {
        auth = {};
        if (options.accessTokenResponse == 'json') {
            auth.accessToken = JSON.parse(body).access_token;
        } else {
            auth.accessToken = querystring.parse(body).access_token;
        }
        if (options.provider === 'github') {
            request.get({url:"https://github.com/api/v2/json/user/show?access_token=" + auth.accessToken}, function(err, resp, body) {
                try {
                    var resp = JSON.parse(body);
                    auth.username = resp.user.login;
                    installSynclet(options.provider, auth);
                } catch (e) {
                    console.error('Failed to auth github - ' + body);
                }
            });
        } else {
            installSynclet(options.provider, auth);
        }
        res.end("<script type='text/javascript'>if (window.opener) { window.opener.location.reload(true); } window.close(); </script>");
    });
}

function handleOAuth2Post (code, options, res) {
    var postData = {grant_type:options.grantType,
              code:code,
              client_id:apiKeys[options.provider].appKey,
              client_secret:apiKeys[options.provider].appSecret,
              redirect_uri:host + options.redirectURI};
    // request won't ever return here.  no idea why.
    //
    // request({method: 'post', uri :options.endPoint, body: querystring.stringify(postData)}, function(err, resp, body) {
    //     console.error(err);
    //     console.error(resp);
    //     console.error(body);
    //     auth = {};
    //     auth.token = JSON.parse(data);
    //     installSynclet(options.provider, auth);
    //     res.end("<script type='text/javascript'>if (window.opener) { window.opener.location.reload(true); } window.close(); </script>");
    // });

    var httpOptions = {
        host: 'accounts.google.com',
        port: 443,
        path: '/o/oauth2/token',
        method: 'POST',
        headers: {'Content-Type':'application/x-www-form-urlencoded'}
    };
    var httpsReq = https.request(httpOptions, function(httpsRes) {
        httpsRes.on('data', function(data) {
            auth = {};
            auth.clientID = apiKeys[options.provider].appKey;
            auth.clientSecret = apiKeys[options.provider].appSecret;
            auth.token = JSON.parse(data);
            installSynclet(options.provider, auth);
            res.end("<script type='text/javascript'>if (window.opener) { window.opener.location.reload(true); } window.close(); </script>");
        });
    });
    httpsReq.write(querystring.stringify(postData));
    httpsReq.on('error', function(e) {
        callback(e, null);
    });
    httpsReq.end();
}

function handleTwitter (req, res) {
    // twitter's annoying.
    // for the current ghetto flow, we're only allowing 1 twitter synclet to be installed
    // unless i come up with a better solution
    //
    var installed = syncManager.synclets().installed;
    for (var i in installed) {
        if (i == 'twitter') {
            return res.end('twitter already installed!!!');
        }
    }
    require('../Connectors/twitter/twitter_client')(apiKeys.twitter.appKey, apiKeys.twitter.appSecret, host + "auth/twitter/auth")
        .getAccessToken(req, res, function(err, newToken) {
            var auth = {};
            auth.consumerKey = apiKeys.twitter.appKey;
            auth.consumerSecret = apiKeys.twitter.appSecret;
            auth.token = newToken;
            installSynclet("twitter", auth);
            res.end("<script type='text/javascript'>if (window.opener) { window.opener.location.reload(true); } window.close(); </script>");
        });
}

function installSynclet (provider, auth) {
    var avail = syncManager.synclets().available;
    var newSynclet;
    for (var i = 0; i < avail.length; i++) {
        if (avail[i].provider == provider) newSynclet = avail[i];
    }
    newSynclet.auth = auth;
    var svcInfo = syncManager.install(newSynclet);
    syncManager.syncNow(svcInfo.id, function() {});
}<|endoftext|>


<commit_before>#!/usr/bin/env node
/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @flow
 * @providesModule http_test_server
 */
'use strict';

/* eslint-env node */

console.log(`\
Test server for WebSocketExample

This will set a cookie named "wstest" on the response of any incoming request.
`);

/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error
 * found when Flow v0.54 was deployed. To see the error delete this comment and
 * run Flow. */
const connect = require('connect');
const http = require('http');

const app = connect();

app.use(function(req, res) {
  console.log('received request');
  const cookieOptions = {
    //httpOnly: true, // the cookie is not accessible by the user (javascript,...)
    secure: false, // allow HTTP
  };
  res.cookie('wstest', 'OK', cookieOptions);
  res.end('Cookie has been set!\n');
});

http.createServer(app).listen(5556);
<commit_msg>RNTester http_server send cookie fix<commit_after>#!/usr/bin/env node
/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @flow
 * @providesModule http_test_server
 */
'use strict';

/* eslint-env node */

console.log(`\
Test server for WebSocketExample

This will set a cookie named "wstest" on the response of any incoming request.
`);

/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error
 * found when Flow v0.54 was deployed. To see the error delete this comment and
 * run Flow. */
const connect = require('connect');
const http = require('http');

const app = connect();

app.use(function(req, res) {
  console.log('received request');
  res.setHeader('Set-Cookie', ['wstest=OK; Path=/']);
  res.end('Cookie has been set!\n');
});

http.createServer(app).listen(5556);
<|endoftext|>


<commit_before>import { Point } from './../Point'
import Line from './../Line'
import { Rect } from './../Rect'

import Tool from './Tool'

export default class Eraser implements Tool {
  constructor (grid, width) {
    this.width = width

    this.grid = grid

    this.movingEraser = null
    this.eraseLine = null
    this.previousPoint = null
  }

  onPress (event, currScale) {
    const coord = { x: event.offsetX, y: event.offsetY }

    this.erase(coord.x, coord.y, currScale, event.target)

    const point = new Point(Math.round(coord.x), Math.round(coord.y))
    this.previousPoint = point
  }

  onSwipe (event, currScale) {
    const coord = { x: event.offsetX, y: event.offsetY }
    const previousPoint = this.previousPoint
    // Ignore if swiped to last coordinates
    if (previousPoint === null || (previousPoint.x === coord.x && previousPoint.y === coord.y)) {
      return
    }

    const point = new Point(Math.round(coord.x), Math.round(coord.y))
    this.eraseLine = new Line(this.previousPoint, point)
    this.movingEraser = true
    this.erase(coord.x, coord.y, currScale, event.target)

    this.previousPoint = point
  }

  onPressUp () {
    this.onOut()
  }

  onOut () {
    this.movingEraser = false
    this.eraseLine = null
    this.previousPoint = null
  }

  erase (x, y, currScale, canvas) {
    const grid = this.grid
    // calcular limites da area a apagar
    const lix = x / currScale - this.width / 2
    const liy = y / currScale - this.width / 2
    const lsx = x / currScale + this.width / 2
    const lsy = y / currScale + this.width / 2

    const figures = grid
        .getNearestFigures(x / currScale, y / currScale)
        .sort((fig1, fig2) => fig2.id - fig1.id) // inverse order to remove the newest first

    for (const prop in figures) {
      const figure = figures[prop]
      const points = figure.getNearPoints(x / currScale, y / currScale, grid.getMaxLinePart())
      if (figure.points == null) {
        return
      }

      let prev = points[0]
      for (let k = 0; k <= points.length; k++) {
        let currPoint = points[k]
        if (currPoint == null) {
          break
        }
        prev.x = prev.x * currScale
        prev.y = prev.y * currScale
        currPoint.x = currPoint.x * currScale
        currPoint.y = currPoint.y * currScale
        // TODO(peddavid, simaovii): width shadowed?
        const width = currPoint.getStyleOf(figure.id).width
        const canvasContext = canvas.getContext('2d')
        const rect = new Rect(prev, currPoint, width, canvasContext)
        const canvasWidth = canvasContext.canvas.width
        const canvasHeight = canvasContext.canvas.height
        // const rect = myContext.getRect(prev, currPoint, width)
        if (this.movingEraser) {
          // TODO(simaovii): não verifica se toda a área da borracha interseta a linha desenhada
          if (this.intersectsLine(this.eraseLine, prev, currPoint)) {
            grid.removeFigure(figure, canvasContext, currScale)
            return
          }
        } else {
          // TODO(simaovii): ver se nao basta iterar sobre os 4 pontos maximos da borracha
          for (let c = lix > 0 ? lix : 0; c < canvasWidth && c < lsx; ++c) {
            for (let l = liy > 0 ? liy : 0; l < canvasHeight && l < lsy; ++l) {
              if (rect.contains({ x: c, y: l })) {
                grid.removeFigure(figure, canvasContext, currScale)
                return
              }
            }
          }
        }
        prev = currPoint
      }
    }
  }

  // TODO(simaovii): por esta função em Figure para não ter que passar eraseLine
  intersectsLine (eraseLine, lineP1, lineP2) {
    // Por agora, este método apenas verifica se a linha da borracha intersecta a linha da figura.
    // É de ter em conta que esta linha não conta com a espessura. Se for necessário tem de se alterar este método para verificar se a linha
    // da borracha intersecta alguma linha do rectângulo

    // calculate figure line equation => y=mx+n
    let auxLineP2 = { x: lineP2.x, y: lineP2.y }
    const figLineA = auxLineP2.y - lineP1.y
    let figLineB = auxLineP2.x - lineP1.x
    // TODO(cipri): não te esqueças de otimizar, quando as linhas são verticais
    // if line is vertical, we assume that it is not. This deviation do not change the behavior of the algorithm as the line segment distance is too short
    if (figLineB === 0) {
      auxLineP2.x = auxLineP2.x - 1
      figLineB = auxLineP2.x - lineP1.x
    }
    const figLineM = figLineA / figLineB
    const figLineC = auxLineP2.x * lineP1.y - lineP1.x * auxLineP2.y
    const figLineN = figLineC / figLineB

    const prev = eraseLine.start
    const currPoint = eraseLine.end

    // TODO(simaovii): guardar em cache a equação da reta da borracha pois vai ser a mesma para os restantes pontos da figura assim como para as restantes figuras do canvas
    // calculate part of erase line equation => y=mx+n
    const eraseLineA = currPoint.y - prev.y
    let eraseLineB = currPoint.x - prev.x
    // if line is vertical, we assume that it is not. This deviation do not change the behaviour of the algorithm as the line segment distance is too short
    if (eraseLineB === 0) {
      currPoint.x = currPoint.x - 1
      eraseLineB = currPoint.x - prev.x
    }
    // the to lines are vertical ou horizontal -> do not intersect each other
    if ((eraseLineB === 0 && figLineB === 0) || (eraseLineA === 0 && figLineA === 0)) {
      return false
    }

    let eraseLineM = eraseLineA / eraseLineB

    // the two lines are parallel
    if (eraseLineM === figLineM) {
      return false
    }

    const eraseLineC = currPoint.x * prev.y - prev.x * currPoint.y
    let eraseLineN = eraseLineC / eraseLineB

    // calculate point of intersection of the to lines
    const intersectY = ((figLineM * eraseLineN) - (eraseLineM * figLineN)) / (figLineM - eraseLineM)
    const intersectX = (eraseLineN - figLineN) / (figLineM - eraseLineM)

    // check if intersection point of the two lines belongs to both segments
    // segment 1
    // ordenar os pontos. é necessário atribuir os novos pontos a novas variáveis para não mexer com os dados das linhas
    const auxLineP1 = { x: lineP1.x, y: lineP1.y }

    if (auxLineP2.x < lineP1.x) { auxLineP1.x = auxLineP2.x; auxLineP2.x = lineP1.x }
    if (auxLineP2.y < lineP1.y) { auxLineP1.y = auxLineP2.y; auxLineP2.y = lineP1.y }

    // check if intersection point is inside segment interval of figure line
    if (!(intersectX <= auxLineP2.x && intersectX >= auxLineP1.x && intersectY <= auxLineP2.y && intersectY >= auxLineP1.y)) {
      return false
    }

    // check if intersection point of the two lines belongs to both segments
    // segment 2
    // ordenar os pontos. é necessário atribuir os novos pontos a novas variáveis para não mexer com os dados das linhas
    const auxCurrPoint = { x: currPoint.x, y: currPoint.y }
    const auxprevPoint = { x: prev.x, y: prev.y }
    if (currPoint.x < prev.x) { auxCurrPoint.x = prev.x; auxprevPoint.x = currPoint.x }
    if (currPoint.y < prev.y) { auxCurrPoint.y = prev.y; auxprevPoint.y = currPoint.y }

    // check if intersection point is inside segment interval of erase line
    if (intersectX <= auxCurrPoint.x && intersectX >= auxprevPoint.x && intersectY <= auxCurrPoint.y && intersectY >= auxprevPoint.y) {
      return true
    }
    return false
  }
}
<commit_msg>clean some state data of Eraser<commit_after>import { Point } from './../Point'
import Line from './../Line'
import { Rect } from './../Rect'

import Tool from './Tool'

export default class Eraser implements Tool {
  constructor (grid, width) {
    this.width = width
    this.grid = grid
    this.eraseLine = null
  }

  onPress (event, currScale) {
    const coord = { x: event.offsetX, y: event.offsetY }

    this.erase(coord.x, coord.y, currScale, event.target)

    const point = new Point(Math.round(coord.x), Math.round(coord.y))
    this.eraseLine = new Line(null, point)
  }

  onSwipe (event, currScale) {
    if (event.buttons <= 0)
      return

    const coord = { x: event.offsetX, y: event.offsetY }
    const previousPoint = this.eraseLine.end
    // Ignore if swiped to last coordinates
    if (previousPoint === null || (previousPoint.x === coord.x && previousPoint.y === coord.y)) {
      return
    }

    const point = new Point(Math.round(coord.x), Math.round(coord.y))
    this.eraseLine = new Line(previousPoint, point)
    this.erase(coord.x, coord.y, currScale, event.target)
  }

  onPressUp () {
    this.onOut()
  }

  onOut () {
    this.eraseLine = null //todo: this will throw error if user draws back in the canvas. insert a check in onSwipe
  }

  erase (x, y, currScale, canvas) {
    const grid = this.grid
    // calcular limites da area a apagar
    const lix = x / currScale - this.width / 2
    const liy = y / currScale - this.width / 2
    const lsx = x / currScale + this.width / 2
    const lsy = y / currScale + this.width / 2

    const figures = grid
        .getNearestFigures(x / currScale, y / currScale)
        .sort((fig1, fig2) => fig2.id - fig1.id) // inverse order to remove the newest first

    for (const prop in figures) {
      const figure = figures[prop]
      const points = figure.getNearPoints(x / currScale, y / currScale, grid.getMaxLinePart())
      if (figure.points == null) {
        return
      }

      let prev = points[0]
      for (let k = 0; k <= points.length; k++) {
        let currPoint = points[k]
        if (currPoint == null) {
          break
        }
        prev.x = prev.x * currScale
        prev.y = prev.y * currScale
        currPoint.x = currPoint.x * currScale
        currPoint.y = currPoint.y * currScale
        // TODO(peddavid, simaovii): width shadowed?
        const width = currPoint.getStyleOf(figure.id).width
        const canvasContext = canvas.getContext('2d')
        const rect = new Rect(prev, currPoint, width, canvasContext)
        const canvasWidth = canvasContext.canvas.width
        const canvasHeight = canvasContext.canvas.height
        // const rect = myContext.getRect(prev, currPoint, width)
        if (this.eraseLine!=null) {
          // TODO(simaovii): não verifica se toda a área da borracha interseta a linha desenhada
          if (this.intersectsLine(this.eraseLine, prev, currPoint)) {
            grid.removeFigure(figure, canvasContext, currScale)
            return
          }
        } else {
          // TODO(simaovii): ver se nao basta iterar sobre os 4 pontos maximos da borracha
          for (let c = lix > 0 ? lix : 0; c < canvasWidth && c < lsx; ++c) {
            for (let l = liy > 0 ? liy : 0; l < canvasHeight && l < lsy; ++l) {
              if (rect.contains({ x: c, y: l })) {
                grid.removeFigure(figure, canvasContext, currScale)
                return
              }
            }
          }
        }
        prev = currPoint
      }
    }
  }

  // TODO(simaovii): por esta função em Figure para não ter que passar eraseLine
  intersectsLine (eraseLine, lineP1, lineP2) {
    // Por agora, este método apenas verifica se a linha da borracha intersecta a linha da figura.
    // É de ter em conta que esta linha não conta com a espessura. Se for necessário tem de se alterar este método para verificar se a linha
    // da borracha intersecta alguma linha do rectângulo

    // calculate figure line equation => y=mx+n
    let auxLineP2 = { x: lineP2.x, y: lineP2.y }
    const figLineA = auxLineP2.y - lineP1.y
    let figLineB = auxLineP2.x - lineP1.x
    // TODO(cipri): não te esqueças de otimizar, quando as linhas são verticais
    // if line is vertical, we assume that it is not. This deviation do not change the behavior of the algorithm as the line segment distance is too short
    if (figLineB === 0) {
      auxLineP2.x = auxLineP2.x - 1
      figLineB = auxLineP2.x - lineP1.x
    }
    const figLineM = figLineA / figLineB
    const figLineC = auxLineP2.x * lineP1.y - lineP1.x * auxLineP2.y
    const figLineN = figLineC / figLineB

    const prev = eraseLine.start
    const currPoint = eraseLine.end

    // TODO(simaovii): guardar em cache a equação da reta da borracha pois vai ser a mesma para os restantes pontos da figura assim como para as restantes figuras do canvas
    // calculate part of erase line equation => y=mx+n
    const eraseLineA = currPoint.y - prev.y
    let eraseLineB = currPoint.x - prev.x
    // if line is vertical, we assume that it is not. This deviation do not change the behaviour of the algorithm as the line segment distance is too short
    if (eraseLineB === 0) {
      currPoint.x = currPoint.x - 1
      eraseLineB = currPoint.x - prev.x
    }
    // the to lines are vertical ou horizontal -> do not intersect each other
    if ((eraseLineB === 0 && figLineB === 0) || (eraseLineA === 0 && figLineA === 0)) {
      return false
    }

    let eraseLineM = eraseLineA / eraseLineB

    // the two lines are parallel
    if (eraseLineM === figLineM) {
      return false
    }

    const eraseLineC = currPoint.x * prev.y - prev.x * currPoint.y
    let eraseLineN = eraseLineC / eraseLineB

    // calculate point of intersection of the to lines
    const intersectY = ((figLineM * eraseLineN) - (eraseLineM * figLineN)) / (figLineM - eraseLineM)
    const intersectX = (eraseLineN - figLineN) / (figLineM - eraseLineM)

    // check if intersection point of the two lines belongs to both segments
    // segment 1
    // ordenar os pontos. é necessário atribuir os novos pontos a novas variáveis para não mexer com os dados das linhas
    const auxLineP1 = { x: lineP1.x, y: lineP1.y }

    if (auxLineP2.x < lineP1.x) { auxLineP1.x = auxLineP2.x; auxLineP2.x = lineP1.x }
    if (auxLineP2.y < lineP1.y) { auxLineP1.y = auxLineP2.y; auxLineP2.y = lineP1.y }

    // check if intersection point is inside segment interval of figure line
    if (!(intersectX <= auxLineP2.x && intersectX >= auxLineP1.x && intersectY <= auxLineP2.y && intersectY >= auxLineP1.y)) {
      return false
    }

    // check if intersection point of the two lines belongs to both segments
    // segment 2
    // ordenar os pontos. é necessário atribuir os novos pontos a novas variáveis para não mexer com os dados das linhas
    const auxCurrPoint = { x: currPoint.x, y: currPoint.y }
    const auxprevPoint = { x: prev.x, y: prev.y }
    if (currPoint.x < prev.x) { auxCurrPoint.x = prev.x; auxprevPoint.x = currPoint.x }
    if (currPoint.y < prev.y) { auxCurrPoint.y = prev.y; auxprevPoint.y = currPoint.y }

    // check if intersection point is inside segment interval of erase line
    if (intersectX <= auxCurrPoint.x && intersectX >= auxprevPoint.x && intersectY <= auxCurrPoint.y && intersectY >= auxprevPoint.y) {
      return true
    }
    return false
  }
}
<|endoftext|>