<commit_before>'use strict';

module.exports = {
  client: {
    lib: {
      css: [
        'public/lib/bootstrap/dist/css/bootstrap.css',
        'public/lib/bootstrap-additions/dist/bootstrap-additions.css',
        'public/lib/angular-material/angular-material.css',
        'public/lib/components-font-awesome/css/font-awesome.css',
        'public/lib/ng-tags-input/ng-tags-input.css',
        'public/lib/angular-moment-picker/dist/angular-moment-picker.css',
        'public/lib/textAngular/dist/textAngular.css',
        'public/lib/angular-toastr/dist/angular-toastr.css'
      ],
      js: [
        'public/lib/angular/angular.js',
        'public/lib/angular-resource/angular-resource.js',
        'public/lib/angular-animate/angular-animate.js',
        'public/lib/angular-messages/angular-messages.js',
        'public/lib/angular-sanitize/angular-sanitize.js',
        'public/lib/angular-socket-io/socket.js',
        'public/lib/angular-touch/angular-touch.js',
        'public/lib/angular-ui-router/release/angular-ui-router.js',
        'public/lib/angular-ui-utils/ui-utils.js',
        'public/lib/angular-bootstrap/ui-bootstrap-tpls.js',
        'public/lib/angular-bootstrap/ui.bootstrap.materialPicker.js',
        'public/lib/angular-strap/dist/angular-strap.js',
        'public/lib/angular-strap/dist/angular-strap.tpl.js',
        'public/lib/angular-strap/dist/angular-strap.compat.js',
        'public/lib/angular-file-upload/angular-file-upload.js',
        'public/lib/angular-aria/angular-aria.js',
        'public/lib/angular-material/angular-material.js',
        'public/lib/angular-ui-switch/angular-ui-switch.js',
        'public/lib/angular-elastic/elastic.js',
        'public/lib/chart.js/dist/Chart.js',
        'public/lib/angular-chart.js/dist/angular-chart.js',
        'public/lib/ng-tags-input/ng-tags-input.js',
        'public/lib/underscore/underscore.js',
        'public/lib/moment/moment.js',
        'public/lib/angular-moment/angular-moment.js',
        'public/lib/angular-moment-picker/dist/angular-moment-picker.js',
        'public/lib/owasp-password-strength-test/owasp-password-strength-test.js',
        'public/lib/ngInfiniteScroll/build/ng-infinite-scroll.js',
        'public/lib/textAngular/dist/textAngular-rangy.min.js',
        'public/lib/textAngular/dist/textAngular-sanitize.min.js',
        'public/lib/textAngular/dist/textAngular.js',
        'public/lib/textAngular/dist/textAngularSetup.js',
        'public/lib/angular-toastr/dist/angular-toastr.tpls.js'
      ],
      tests: ['public/lib/angular-mocks/angular-mocks.js']
    },
    css: [
      'modules/*/client/css/*.css'
    ],
    less: [
      'modules/*/client/less/*.less'
    ],
    sass: [
      'modules/*/client/scss/*.scss'
    ],
    js: [
      'modules/core/client/app/config.js',
      'modules/core/client/app/init.js',
      'modules/*/client/*.js',
      'modules/*/client/**/*.js',
      'modules/*/client/**/**/*.js',
    ],
    views: ['modules/*/client/views/**/*.html'],
    templates: ['build/templates.js']
  },
  server: {
    gruntConfig: 'gruntfile.js',
    gulpConfig: 'gulpfile.js',
    allJS: ['server.js', 'config/**/*.js', 'modules/*/server/**/*.js'],
    models: 'modules/*/server/models/**/*.js',
    routes: ['modules/!(core)/server/routes/**/*.js', 'modules/core/server/routes/**/*.js'],
    sockets: 'modules/*/server/sockets/**/*.js',
    config: 'modules/*/server/config/*.js',
    policies: 'modules/*/server/policies/*.js',
    views: 'modules/*/server/views/*.html'
  }
};
<commit_msg>Commited from HaNhatLenh at Fri, Jul 07, 2017 10:19:13 AM<commit_after>'use strict';

module.exports = {
  client: {
    lib: {
      css: [
        'public/lib/bootstrap/dist/css/bootstrap.css',
        'public/lib/bootstrap-additions/dist/bootstrap-additions.css',
        'public/lib/angular-material/angular-material.css',
        'public/lib/components-font-awesome/css/font-awesome.css',
        'public/lib/ng-tags-input/ng-tags-input.css',
        'public/lib/angular-moment-picker/dist/angular-moment-picker.css',
        'public/lib/textAngular/dist/textAngular.css',
        'public/lib/angular-toastr/dist/angular-toastr.css'
      ],
      js: [
        'public/lib/angular/angular.js',
        'public/lib/angular-resource/angular-resource.js',
        'public/lib/angular-animate/angular-animate.js',
        'public/lib/angular-messages/angular-messages.js',
        'public/lib/angular-sanitize/angular-sanitize.js',
        'public/lib/angular-socket-io/socket.js',
        'public/lib/angular-touch/angular-touch.js',
        'public/lib/angular-ui-router/release/angular-ui-router.js',
        'public/lib/angular-ui-utils/ui-utils.js',
        'public/lib/angular-bootstrap/ui-bootstrap-tpls.js',
        'public/lib/angular-bootstrap/ui.bootstrap.materialPicker.js',
        'public/lib/angular-strap/dist/angular-strap.js',
        'public/lib/angular-strap/dist/angular-strap.tpl.js',
        'public/lib/angular-strap/dist/angular-strap.compat.js',
        'public/lib/angular-file-upload/angular-file-upload.js',
        'public/lib/angular-aria/angular-aria.js',
        'public/lib/angular-material/angular-material.js',
        'public/lib/angular-ui-switch/angular-ui-switch.js',
        'public/lib/angular-elastic/elastic.js',
        'public/lib/chart.js/dist/Chart.js',
        'public/lib/angular-chart.js/dist/angular-chart.js',
        'public/lib/ng-tags-input/ng-tags-input.js',
        'public/lib/underscore/underscore.js',
        'public/lib/moment/moment.js',
        'public/lib/angular-moment/angular-moment.js',
        'public/lib/angular-moment-picker/dist/angular-moment-picker.js',
        'public/lib/owasp-password-strength-test/owasp-password-strength-test.js',
        'public/lib/ngInfiniteScroll/build/ng-infinite-scroll.js',
        'public/lib/textAngular/dist/textAngular-rangy.min.js',
        'public/lib/textAngular/dist/textAngular-sanitize.min.js',
        'public/lib/textAngular/dist/textAngular.js',
        'public/lib/textAngular/dist/textAngularSetup.js',
        'public/lib/angular-toastr/dist/angular-toastr.js'
      ],
      tests: ['public/lib/angular-mocks/angular-mocks.js']
    },
    css: [
      'modules/*/client/css/*.css'
    ],
    less: [
      'modules/*/client/less/*.less'
    ],
    sass: [
      'modules/*/client/scss/*.scss'
    ],
    js: [
      'modules/core/client/app/config.js',
      'modules/core/client/app/init.js',
      'modules/*/client/*.js',
      'modules/*/client/**/*.js',
      'modules/*/client/**/**/*.js',
    ],
    views: ['modules/*/client/views/**/*.html'],
    templates: ['build/templates.js']
  },
  server: {
    gruntConfig: 'gruntfile.js',
    gulpConfig: 'gulpfile.js',
    allJS: ['server.js', 'config/**/*.js', 'modules/*/server/**/*.js'],
    models: 'modules/*/server/models/**/*.js',
    routes: ['modules/!(core)/server/routes/**/*.js', 'modules/core/server/routes/**/*.js'],
    sockets: 'modules/*/server/sockets/**/*.js',
    config: 'modules/*/server/config/*.js',
    policies: 'modules/*/server/policies/*.js',
    views: 'modules/*/server/views/*.html'
  }
};
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012-2015 Taye Adeyemi
 * Open source under the MIT License.
 * https://raw.github.com/taye/interact.js/master/LICENSE
 */

(function(interact) {
    'use strict';

    var svg,
        svgNS = 'http://www.w3.org/2000/svg',
        SVGElement = window.SVGElement,
        eventTypes = interact.debug().eventTypes;

    function DemoGraphic(id) {
            var width = window.innerWidth,
                height = window.innerHeight,
                group = svg.appendChild(document.createElementNS(svgNS, 'g')),
                ellipse = group.appendChild(document.createElementNS(svgNS, 'ellipse')),
                text = group.appendChild(document.createElementNS( svgNS, 'text')),
                title = group.appendChild(document.createElementNS(svgNS, 'text'));

            ellipse.demo = true;
            ellipse.text = text;
            window[id] = ellipse;

            ellipse.dragX = Math.random()*(width - 200);
            ellipse.dragY = Math.random()*(height - 200);
            ellipse.resizeWidth  = 80;
            ellipse.resizeHeight = 80;

            group.setAttribute('transform', ['translate(', ellipse.dragX, ellipse.dragY, ')'].join(' '));
            group.setAttribute('class', 'demo-node');

            ellipse.setAttribute('cx', 0);
            ellipse.setAttribute('cy', 0);
            ellipse.setAttribute('rx', ellipse.resizeWidth);
            ellipse.setAttribute('ry', ellipse.resizeHeight);

            title.textContent = id;
            title.setAttribute('class', 'title');
            text.setAttribute('class', 'eventData');

            this.group = group;
            this.ellipse = ellipse;
            this.text = text;
            this.title = title;

            /*
            interact(this.ellipse).set({
                draggable: true,
                dropzone: true,
                resizable: true
            });
           */
    }

    function DemoNode (id) {
        this.element = document.body.appendChild(document.createElement('div'));
        this.element.className = 'demo-node';
        this.element.id = id;
        this.element.demo = true;
        this.element.style.width  = '200px';
        this.element.style.height = '200px';

        this.element.text = this.element.appendChild(document.createElement('pre'));
        this.element.appendChild(document.createElement('br'));
        this.element.style.left = Math.random()*((window.innerWidth || 800) - 200) + 'px';
        this.element.style.top = Math.random()*((window.innerHeight || 800) - 200) + 'px';

        /*interact(this.element).set({
            draggable: true,
            dropzone: true,
            resizable: true,
            gesturable: true
        });*/
        window[id] = this.element;
    }

    function nodeEventDebug(e) {
        var textProp,
            target = e.target,
            nl;

        textProp = 'textContent';
        nl = '\n';

        if ( target.demo && indexOf(eventTypes, e.type) !== -1 ) {
            target.text[textProp] = nl + e.type;
            target.text[textProp] += nl + ' x0, y0      : (' + e.x0 + ', ' + e.y0 + ')';
            target.text[textProp] += nl + ' dx, dy      : (' + e.dx + ', ' + e.dy + ')';
            target.text[textProp] += nl + ' pageX, pageY: (' + e.pageX + ', ' + e.pageY + ')';
            target.text[textProp] += nl + ' speed       :  ' + e.speed;

            if (indexOf(e.type, 'gesture') !== -1) {
                target.text[textProp] += nl + ' distance: ' + e.distance;
                target.text[textProp] += nl + ' scale   : ' + e.scale;
                target.text[textProp] += nl + ' angle   : ' + e.angle;
                target.text[textProp] += nl + ' rotation: ' + e.rotation;
            }
        }
    }

    function eventProps(e) {
        var debug = [],
            prop;
        if (typeof e === 'object') {
            debug.push('event: ');
            for (prop in e) {
                if (e.hasOwnProperty(prop)) {
                    debug.push('\n    ' + prop + ' : ' + e[prop]);
                }
            }
        }
        if (event.touches && event.touches.length) {
            debug += 'touches[0]: ';
            for (prop in e.touches[0]) {
                if (e.touches[0].hasOwnProperty(prop)) {
                    debug.push('\n    ' + prop + ' : ' + e.touches[0][prop]);
                }
            }
        }
        for (prop in e) {
            if (e.hasOwnProperty(prop)) {
                debug.push('\n' + prop + ' : ' + e[prop]);
            }
        }

        return debug.join('');
    }

    function dragMove(e) {
        var target = e.target;

        if ('SVGElement' in window && e.target instanceof SVGElement) {
            target.dragX += e.dx;
            target.dragY += e.dy;

            target.parentNode.setAttribute('transform', ['translate(', target.dragX, target.dragY, ')'].join(' '));
        } else {
            target.style.left = parseInt(target.style.left || 0, 10) + e.dx + 'px';
            target.style.top  = parseInt(target.style.top || 0, 10)  + e.dy + 'px';
        }
    }

    function resizeMove(event) {
        var target = event.target;

        if ('SVGElement' in window && target instanceof SVGElement) {
            target.dragX += (event.edges.left? event.deltaRect.left : event.deltaRect.right ) / 2;
            target.dragY += (event.edges.top ? event.deltaRect.top  : event.deltaRect.bottom) / 2;

            target.resizeWidth  += event.deltaRect.width  / 2;
            target.resizeHeight += event.deltaRect.height / 2;

            target.setAttribute('rx',  target.resizeWidth);
            target.setAttribute('ry', target.resizeHeight);

            target.parentNode.setAttribute('transform', ['translate(', target.dragX, target.dragY, ')'].join(' '));
        }
        else {
            target.style.left = parseInt(target.style.left || 0, 10) + event.deltaRect.left + 'px';
            target.style.top  = parseInt(target.style.top  || 0, 10) + event.deltaRect.top  + 'px';

            target.style.width  = Math.max(parseInt(target.style.width  || 0, 10) + event.deltaRect.width , 50) + 'px';
            target.style.height = Math.max(parseInt(target.style.height || 0, 10) + event.deltaRect.height, 50) + 'px';

            //target.style.left = event.rect.left + 'px';
            //target.style.top  = event.rect.top  + 'px';

            //target.style.width  = event.rect.width  + 'px';
            //target.style.height = event.rect.height + 'px';
        }
    }

    interact.on('resizemove', resizeMove);
    interact.on('dragmove', dragMove);

    function dropNode (e) {
        if ('SVGElement' in window && e.draggable instanceof SVGElement) {
            return;
        }

        var dropzone = e.target,
            draggable = e.relatedTarget,
            dropzoneRect = dropzone.getClientRects()[0],
            parent = draggable.parentNode,
            dropRect = {
                x: dropzoneRect.left + 20,
                y: dropzoneRect.top  + 20
            };

        dropRect.x += (window.scrollX || document.documentElement.scrollLeft);
        dropRect.y += (window.scrollY || document.documentElement.scrollTop);
        dropRect.width  = (dropzoneRect.right  - dropzoneRect.left) / 2;
        dropRect.height = (dropzoneRect.bottom - dropzoneRect.top)  / 2;

        draggable.style.left = dropRect.x + 'px';
        draggable.style.top  = dropRect.y + 'px';
        draggable.style.width  = dropRect.width  + 'px';
        draggable.style.height = dropRect.height + 'px';

        parent.appendChild(parent.removeChild(draggable));
    }

    function onReady () {
        var i;

        if ('SVGElement' in window) {
            var width = window.innerWidth,
                height = window.innerHeight;

            svg = document.createElementNS(svgNS, 'svg');
            svg.id = 'svg';
            svg.setAttribute('viewBox', '0 0 ' + width + ' ' + height);
            svg.setAttribute('width', width);
            svg.setAttribute('height', height);
            document.body.appendChild(svg);

            window.svg = svg;

            for (i = 0; i < 2; i++) {
                new DemoGraphic('graphic' + i);
            }
        }

        for (i = 0; i < 2; i++) {
            new DemoNode('node' + i);
        }

        interact('div.demo-node, .demo-node ellipse')
            .draggable({
                max: 2,
                autoScroll: true,
                inertia: true
            })
            .gesturable({ max: 1 })
            .resizable({
                max: 2,
                autoScroll: { enabled: true },
                inertia: { resistance: 40 },
                edges: { left: true, right: true, top: true, bottom: true }
            })
            .dropzone(true);
    }

    function indexOf (array, target) {
        for (var i = 0, len = array.length; i < len; i++) {
            if (array[i] === target) {
                return i;
            }
        }

        return -1;
    }

    interact.maxInteractions(Infinity);

    interact(window).on('addEventListener' in document? 'DOMContentLoaded': 'load', onReady);

    // Display event properties for debugging
    interact.on('resizestart', nodeEventDebug);
    interact.on('resizemove', nodeEventDebug);
    interact.on('resizeend', nodeEventDebug);
    interact.on('gesturestart', nodeEventDebug);
    interact.on('gesturemove', nodeEventDebug);
    interact.on('gestureend', nodeEventDebug);
    interact.on('dragstart', nodeEventDebug);
    interact.on('dragmove', nodeEventDebug);
    interact.on('dragend', nodeEventDebug);

    interact.on('drop', dropNode);

    window.demo = {
        DemoNode      : DemoNode,
        DemoGraphic   : DemoGraphic,
        nodeEventDebug: nodeEventDebug,
        eventProps    : eventProps
    };
}(window.interact));
<commit_msg>demo/html_svg: remove use of interact.debug()<commit_after>/*
 * Copyright (c) 2012-2015 Taye Adeyemi
 * Open source under the MIT License.
 * https://raw.github.com/taye/interact.js/master/LICENSE
 */

(function(interact) {
    'use strict';

    var svg,
        svgNS = 'http://www.w3.org/2000/svg',
        SVGElement = window.SVGElement;

    function DemoGraphic(id) {
            var width = window.innerWidth,
                height = window.innerHeight,
                group = svg.appendChild(document.createElementNS(svgNS, 'g')),
                ellipse = group.appendChild(document.createElementNS(svgNS, 'ellipse')),
                text = group.appendChild(document.createElementNS( svgNS, 'text')),
                title = group.appendChild(document.createElementNS(svgNS, 'text'));

            ellipse.demo = true;
            ellipse.text = text;
            window[id] = ellipse;

            ellipse.dragX = Math.random()*(width - 200);
            ellipse.dragY = Math.random()*(height - 200);
            ellipse.resizeWidth  = 80;
            ellipse.resizeHeight = 80;

            group.setAttribute('transform', ['translate(', ellipse.dragX, ellipse.dragY, ')'].join(' '));
            group.setAttribute('class', 'demo-node');

            ellipse.setAttribute('cx', 0);
            ellipse.setAttribute('cy', 0);
            ellipse.setAttribute('rx', ellipse.resizeWidth);
            ellipse.setAttribute('ry', ellipse.resizeHeight);

            title.textContent = id;
            title.setAttribute('class', 'title');
            text.setAttribute('class', 'eventData');

            this.group = group;
            this.ellipse = ellipse;
            this.text = text;
            this.title = title;

            /*
            interact(this.ellipse).set({
                draggable: true,
                dropzone: true,
                resizable: true
            });
           */
    }

    function DemoNode (id) {
        this.element = document.body.appendChild(document.createElement('div'));
        this.element.className = 'demo-node';
        this.element.id = id;
        this.element.demo = true;
        this.element.style.width  = '200px';
        this.element.style.height = '200px';

        this.element.text = this.element.appendChild(document.createElement('pre'));
        this.element.appendChild(document.createElement('br'));
        this.element.style.left = Math.random()*((window.innerWidth || 800) - 200) + 'px';
        this.element.style.top = Math.random()*((window.innerHeight || 800) - 200) + 'px';

        /*interact(this.element).set({
            draggable: true,
            dropzone: true,
            resizable: true,
            gesturable: true
        });*/
        window[id] = this.element;
    }

    function nodeEventDebug(e) {
        var textProp,
            target = e.target,
            nl;

        textProp = 'textContent';
        nl = '\n';

        target.text[textProp] = nl + e.type;
        target.text[textProp] += nl + ' x0, y0      : (' + e.x0 + ', ' + e.y0 + ')';
        target.text[textProp] += nl + ' dx, dy      : (' + e.dx + ', ' + e.dy + ')';
        target.text[textProp] += nl + ' pageX, pageY: (' + e.pageX + ', ' + e.pageY + ')';
        target.text[textProp] += nl + ' speed       :  ' + e.speed;

        if (indexOf(e.type, 'gesture') !== -1) {
            target.text[textProp] += nl + ' distance: ' + e.distance;
            target.text[textProp] += nl + ' scale   : ' + e.scale;
            target.text[textProp] += nl + ' angle   : ' + e.angle;
            target.text[textProp] += nl + ' rotation: ' + e.rotation;
        }
    }

    function eventProps(e) {
        var debug = [],
            prop;
        if (typeof e === 'object') {
            debug.push('event: ');
            for (prop in e) {
                if (e.hasOwnProperty(prop)) {
                    debug.push('\n    ' + prop + ' : ' + e[prop]);
                }
            }
        }
        if (event.touches && event.touches.length) {
            debug += 'touches[0]: ';
            for (prop in e.touches[0]) {
                if (e.touches[0].hasOwnProperty(prop)) {
                    debug.push('\n    ' + prop + ' : ' + e.touches[0][prop]);
                }
            }
        }
        for (prop in e) {
            if (e.hasOwnProperty(prop)) {
                debug.push('\n' + prop + ' : ' + e[prop]);
            }
        }

        return debug.join('');
    }

    function dragMove(e) {
        var target = e.target;

        if ('SVGElement' in window && e.target instanceof SVGElement) {
            target.dragX += e.dx;
            target.dragY += e.dy;

            target.parentNode.setAttribute('transform', ['translate(', target.dragX, target.dragY, ')'].join(' '));
        } else {
            target.style.left = parseInt(target.style.left || 0, 10) + e.dx + 'px';
            target.style.top  = parseInt(target.style.top || 0, 10)  + e.dy + 'px';
        }
    }

    function resizeMove(event) {
        var target = event.target;

        if ('SVGElement' in window && target instanceof SVGElement) {
            target.dragX += (event.edges.left? event.deltaRect.left : event.deltaRect.right ) / 2;
            target.dragY += (event.edges.top ? event.deltaRect.top  : event.deltaRect.bottom) / 2;

            target.resizeWidth  += event.deltaRect.width  / 2;
            target.resizeHeight += event.deltaRect.height / 2;

            target.setAttribute('rx',  target.resizeWidth);
            target.setAttribute('ry', target.resizeHeight);

            target.parentNode.setAttribute('transform', ['translate(', target.dragX, target.dragY, ')'].join(' '));
        }
        else {
            target.style.left = parseInt(target.style.left || 0, 10) + event.deltaRect.left + 'px';
            target.style.top  = parseInt(target.style.top  || 0, 10) + event.deltaRect.top  + 'px';

            target.style.width  = Math.max(parseInt(target.style.width  || 0, 10) + event.deltaRect.width , 50) + 'px';
            target.style.height = Math.max(parseInt(target.style.height || 0, 10) + event.deltaRect.height, 50) + 'px';

            //target.style.left = event.rect.left + 'px';
            //target.style.top  = event.rect.top  + 'px';

            //target.style.width  = event.rect.width  + 'px';
            //target.style.height = event.rect.height + 'px';
        }
    }

    interact.on('resizemove', resizeMove);
    interact.on('dragmove', dragMove);

    function dropNode (e) {
        if ('SVGElement' in window && e.draggable instanceof SVGElement) {
            return;
        }

        var dropzone = e.target,
            draggable = e.relatedTarget,
            dropzoneRect = dropzone.getClientRects()[0],
            parent = draggable.parentNode,
            dropRect = {
                x: dropzoneRect.left + 20,
                y: dropzoneRect.top  + 20
            };

        dropRect.x += (window.scrollX || document.documentElement.scrollLeft);
        dropRect.y += (window.scrollY || document.documentElement.scrollTop);
        dropRect.width  = (dropzoneRect.right  - dropzoneRect.left) / 2;
        dropRect.height = (dropzoneRect.bottom - dropzoneRect.top)  / 2;

        draggable.style.left = dropRect.x + 'px';
        draggable.style.top  = dropRect.y + 'px';
        draggable.style.width  = dropRect.width  + 'px';
        draggable.style.height = dropRect.height + 'px';

        parent.appendChild(parent.removeChild(draggable));
    }

    function onReady () {
        var i;

        if ('SVGElement' in window) {
            var width = window.innerWidth,
                height = window.innerHeight;

            svg = document.createElementNS(svgNS, 'svg');
            svg.id = 'svg';
            svg.setAttribute('viewBox', '0 0 ' + width + ' ' + height);
            svg.setAttribute('width', width);
            svg.setAttribute('height', height);
            document.body.appendChild(svg);

            window.svg = svg;

            for (i = 0; i < 2; i++) {
                new DemoGraphic('graphic' + i);
            }
        }

        for (i = 0; i < 2; i++) {
            new DemoNode('node' + i);
        }

        interact('div.demo-node, .demo-node ellipse')
            .draggable({
                max: 2,
                autoScroll: true,
                inertia: true
            })
            .gesturable({ max: 1 })
            .resizable({
                max: 2,
                autoScroll: { enabled: true },
                inertia: { resistance: 40 },
                edges: { left: true, right: true, top: true, bottom: true }
            })
            .dropzone(true);
    }

    function indexOf (array, target) {
        for (var i = 0, len = array.length; i < len; i++) {
            if (array[i] === target) {
                return i;
            }
        }

        return -1;
    }

    interact.maxInteractions(Infinity);

    interact(window).on('addEventListener' in document? 'DOMContentLoaded': 'load', onReady);

    // Display event properties for debugging
    interact.on([
        'resizestart',
        'resizemove',
        'resizeend',
        'gesturestart',
        'gesturemove',
        'gestureend',
        'dragstart',
        'dragmove',
        'dragend',
    ], nodeEventDebug);

    interact.on('drop', dropNode);

    window.demo = {
        DemoNode      : DemoNode,
        DemoGraphic   : DemoGraphic,
        nodeEventDebug: nodeEventDebug,
        eventProps    : eventProps
    };
}(window.interact));
<|endoftext|>


<commit_before>/**
 *
 * GeometryCanvasWithOptions
 *
 */

import { compose } from 'recompose';
import React from 'react';
import PropTypes from 'prop-types';
import { withCookies } from 'react-cookie';

import { withStyles } from 'material-ui/styles';
import Modal from 'material-ui/Modal';
import Grid from 'material-ui/Grid';
import Button from 'material-ui/Button';
import IconButton from 'material-ui/IconButton';
import { MdFullscreen } from 'react-icons/lib/md';

import GeometryCanvasCifdata from 'components/GeometryCanvasCifdata';

const styles = (theme) => ({
  avatar: {
    fontColor: '#000000',
    fontSize: 18,
    backgroundColor: '#ffffff',
    marginLeft: -14,
    marginRight: -14,
    marginTop: -5,
    textTranformation: 'none',
    [theme.breakpoints.down('sm')]: {
      fontSize: 12,
    },
  },
  iconButton: {
    fontColor: '#000000',
    backgroundColor: '#ffffff',
    [theme.breakpoints.down('sm')]: {
      fontSize: 12,
      height: 15,
      width: 15,
    },
    [theme.breakpoints.down('xs')]: {
      fontSize: 12,
      height: 10,
      width: 10,
    },
  },
  iconButtonIcon: {
    fontColor: '#000000',
    backgroundColor: '#ffffff',
    marginTop: 7,
  },
});

const initialState = {
  open: false,
  height: Math.max(Math.min(window.innerWidth * 0.5, 600), 300),
  width: Math.max(Math.min(window.innerWidth * 0.5, 600), 300),
  color: '#fff',
  x: 2,
  y: 2,
  z: 1,
  borderWidth: 0,
  altLabels: {},
  perspective: true,
  tiltToRotate: true,
};

class GeometryCanvasWithOptions extends React.Component { // eslint-disable-line react/prefer-stateless-function
  constructor(props) {
    super(props);
    this.state = initialState;
  }
  handleOpen() {
    this.setState({ open: true });
  }

  handleClose() {
    this.setState({ open: false });
  }

  handleChange(axis, diff) {
    return () => {
      this.setState({
        [axis]: Math.max(1, this.state[axis] + diff),
      });
    };
  }

  render() {
    return (

        <Modal
          aria-labelledby="simple-modal-title"
          aria-describedby="simple-modal-description"
          open={this.state.open}
          onClose={() => { this.handleClose(); }}
        >
          <GeometryCanvasCifdata
            uniqueId={`fs_${this.props.uniqueId}`}
            cifdata={this.props.cifdata}
            id={`fs_${this.props.id}`}
            x={this.state.x}
            y={this.state.y}
            z={this.state.z}
            height={window.innerHeight - 50}
            width={window.innerWidth - 50}
          />
        </Modal>
        <GeometryCanvasCifdata
          uniqueId={this.props.uniqueId}
          cifdata={this.props.cifdata}
          id={this.props.id}
          x={this.state.x}
          y={this.state.y}
          z={this.state.z}
        />
        <Grid
          container
          direction="row"
          justify="space-between"
        >
          <Grid item>
            <Grid container direction="row">
              <Grid item>
                <Button onClick={this.handleChange('x', -1)} mini fab className={this.props.classes.iconButton}>-</Button>
              </Grid>
              <Grid item>
                <IconButton size="small" className={this.props.classes.avatar}>x={this.state.x}</IconButton>
              </Grid>
              <Grid item>
                <Button onClick={this.handleChange('x', +1)} mini fab className={this.props.classes.iconButton}>+</Button>
              </Grid>
            </Grid>
          </Grid>
          <Grid item>
            <Grid container direction="row">
              <Grid item>
                <Button onClick={this.handleChange('y', -1)} mini fab className={this.props.classes.iconButton}>-</Button>
              </Grid>
              <Grid item>
                <IconButton className={this.props.classes.avatar}>y={this.state.y}</IconButton>
              </Grid>
              <Grid item>
                <Button onClick={this.handleChange('y', +1)} mini fab className={this.props.classes.iconButton}>+</Button>
              </Grid>
            </Grid>
          </Grid>
          <Grid item>
            <Grid container direction="row">
              <Grid item>
                <Button onClick={this.handleChange('z', -1)} mini fab className={this.props.classes.iconButton}>-</Button>
              </Grid>
              <Grid item>
                <IconButton className={this.props.classes.avatar} >z={this.state.z}</IconButton>
              </Grid>
              <Grid item>
                <Button onClick={this.handleChange('z', +1)} mini fab className={this.props.classes.iconButton}>+</Button>
              </Grid>
            </Grid>
          </Grid>
          <Grid>
            <Grid container direction="row">
              <Grid item>
                <Button mini fab className={this.props.classes.iconButtonIcon} onClick={() => { this.setState({ open: true }); }} ><MdFullscreen /></Button>
              </Grid>
            </Grid>
          </Grid>
        </Grid>

    );
  }
}

GeometryCanvasWithOptions.propTypes = {
  classes: PropTypes.object,
  uniqueId: PropTypes.string.isRequired,
  cifdata: PropTypes.string.isRequired,
  id: PropTypes.string.isRequired,
};

export default compose(
  withStyles(styles, { withTheme: true }),
  withCookies,
)(GeometryCanvasWithOptions);
<commit_msg>Disable +/- button with reasonable limits<commit_after>/**
 *
 * GeometryCanvasWithOptions
 *
 */

import { compose } from 'recompose';
import React from 'react';
import PropTypes from 'prop-types';
import { withCookies } from 'react-cookie';

import { withStyles } from 'material-ui/styles';
import Modal from 'material-ui/Modal';
import Grid from 'material-ui/Grid';
import Button from 'material-ui/Button';
import IconButton from 'material-ui/IconButton';
import { MdFullscreen } from 'react-icons/lib/md';

import GeometryCanvasCifdata from 'components/GeometryCanvasCifdata';

const styles = (theme) => ({
  avatar: {
    fontColor: '#000000',
    fontSize: 18,
    backgroundColor: '#ffffff',
    marginLeft: -14,
    marginRight: -14,
    marginTop: -5,
    textTranformation: 'none',
    [theme.breakpoints.down('sm')]: {
      fontSize: 12,
    },
  },
  iconButton: {
    fontColor: '#000000',
    backgroundColor: '#ffffff',
    [theme.breakpoints.down('sm')]: {
      fontSize: 12,
      height: 15,
      width: 15,
    },
    [theme.breakpoints.down('xs')]: {
      fontSize: 12,
      height: 10,
      width: 10,
    },
  },
  iconButtonIcon: {
    fontColor: '#000000',
    backgroundColor: '#ffffff',
    marginTop: 7,
  },
});

const initialState = {
  open: false,
  height: Math.max(Math.min(window.innerWidth * 0.5, 600), 300),
  width: Math.max(Math.min(window.innerWidth * 0.5, 600), 300),
  color: '#fff',
  x: 2,
  y: 2,
  z: 1,
  borderWidth: 0,
  altLabels: {},
  perspective: true,
  tiltToRotate: true,
};

class GeometryCanvasWithOptions extends React.Component { // eslint-disable-line react/prefer-stateless-function
  constructor(props) {
    super(props);
    this.state = initialState;
  }
  handleOpen() {
    this.setState({ open: true });
  }

  handleClose() {
    this.setState({ open: false });
  }

  handleChange(axis, diff) {
    return () => {
      this.setState({
        [axis]: Math.max(1, this.state[axis] + diff),
      });
    };
  }

  render() {
    return (

        <Modal
          aria-labelledby="simple-modal-title"
          aria-describedby="simple-modal-description"
          open={this.state.open}
          onClose={() => { this.handleClose(); }}
        >
          <GeometryCanvasCifdata
            uniqueId={`fs_${this.props.uniqueId}`}
            cifdata={this.props.cifdata}
            id={`fs_${this.props.id}`}
            x={this.state.x}
            y={this.state.y}
            z={this.state.z}
            height={window.innerHeight - 50}
            width={window.innerWidth - 50}
          />
        </Modal>
        <GeometryCanvasCifdata
          uniqueId={this.props.uniqueId}
          cifdata={this.props.cifdata}
          id={this.props.id}
          x={this.state.x}
          y={this.state.y}
          z={this.state.z}
        />
        <Grid
          container
          direction="row"
          justify="space-between"
        >
          <Grid item>
            <Grid container direction="row">
              <Grid item>
                <Button
                  onClick={this.handleChange('x', -1)}
                  disabled={this.state.x < 2}
                  mini fab className={this.props.classes.iconButton}
                >-</Button>
              </Grid>
              <Grid item>
                <IconButton size="small" className={this.props.classes.avatar}>x={this.state.x}</IconButton>
              </Grid>
              <Grid item>
                <Button
                  onClick={this.handleChange('x', +1)}
                  disabled={this.state.x >= 10}
                  mini fab className={this.props.classes.iconButton}
                >+</Button>
              </Grid>
            </Grid>
          </Grid>
          <Grid item>
            <Grid container direction="row">
              <Grid item>
                <Button
                  onClick={this.handleChange('y', -1)}
                  disabled={this.state.y < 2}
                  mini fab className={this.props.classes.iconButton}
                >-</Button>
              </Grid>
              <Grid item>
                <IconButton className={this.props.classes.avatar}>y={this.state.y}</IconButton>
              </Grid>
              <Grid item>
                <Button
                  onClick={this.handleChange('y', +1)}
                  disabled={this.state.y >= 10}
                  mini fab className={this.props.classes.iconButton}
                >+</Button>
              </Grid>
            </Grid>
          </Grid>
          <Grid item>
            <Grid container direction="row">
              <Grid item>
                <Button
                  onClick={this.handleChange('z', -1)}
                  disabled={this.state.z < 2}
                  mini fab className={this.props.classes.iconButton}
                >-</Button>
              </Grid>
              <Grid item>
                <IconButton className={this.props.classes.avatar} >z={this.state.z}</IconButton>
              </Grid>
              <Grid item>
                <Button
                  onClick={this.handleChange('z', +1)}
                  disabled={this.state.z >= 10}
                  mini fab className={this.props.classes.iconButton}
                >+</Button>
              </Grid>
            </Grid>
          </Grid>
          <Grid>
            <Grid container direction="row">
              <Grid item>
                <Button mini fab className={this.props.classes.iconButtonIcon} onClick={() => { this.setState({ open: true }); }} ><MdFullscreen /></Button>
              </Grid>
            </Grid>
          </Grid>
        </Grid>

    );
  }
}

GeometryCanvasWithOptions.propTypes = {
  classes: PropTypes.object,
  uniqueId: PropTypes.string.isRequired,
  cifdata: PropTypes.string.isRequired,
  id: PropTypes.string.isRequired,
};

export default compose(
  withStyles(styles, { withTheme: true }),
  withCookies,
)(GeometryCanvasWithOptions);
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  ScrollView,
  Dimensions,
  Button,
  ActivityIndicator,
  Image,
  Modal,
  TouchableHighlight,
  AlertIOS,
  TextInput,
  TouchableOpacity
} from 'react-native';
import Camera from 'react-native-camera';
import NavigationBar from 'react-native-navbar';

// PARENT

export default class FoodrFrontend extends Component {
  constructor() {
    super()
    this.state = {
      currentPage: 'SearchPage',
      previousPage: 'DefaultPage',
      foundProduct: {},
      foundProductSaved: false,
      userId: false, // false if not logged in
      searchTerm: ''
    }
    this.updateCurrentPage = this.updateCurrentPage.bind(this)
    this.searchProduct = this.searchProduct.bind(this)
    this.updateSearchTerm = this.updateSearchTerm.bind(this)
    this.saveSearch = this.saveSearch.bind(this)
  }

  searchProduct(upc) {
    this.updateCurrentPage('SearchingPage')

    fetch('https://dbc-foodr-api.herokuapp.com/products/' + upc + "?user_id=" + this.state.userId)
    // fetch('http://localhost:3000/products/' + upc + "?user_id=" + this.state.userId)
    .then((data) => data.json())
    .then((jsonData) => {
      this.setState({ foundProduct: jsonData })
      if (this.state.foundProduct.found) {
        this.setState({foundProductSaved: jsonData.search.is_saved})
        this.updateCurrentPage('ProductPage')
      } else {
        this.updateCurrentPage('NoResultsPage')
      }
    });
  }

  saveSearch(searchId) {
    if (this.state.userId) {
      fetch('http://localhost:3000/searches/' + searchId + '/save', {method: 'POST'})
      .then(data => data.json())
      .then(jsonData => {
        if (jsonData.save_successful) {
          this.setState({foundProductSaved: true});
          AlertIOS.alert('Product Saved!');
        } else {
          this.setState({foundProductSaved: false});
          AlertIOS.alert('Product was not saved.');
        }
      })
    } else {
      AlertIOS.alert('Please sign up or login to save an item.');
    }
  }

  updateCurrentPage(pageName) {
    this.setState({currentPage: pageName})
  }

  updateSearchTerm(searchTerm) {
    this.setState({searchTerm: searchTerm})
  }

  render() {
    const titleConfig = {
      title: 'FOODR',
    };

    const leftButtonConfig = {
      title: 'Profile',
      handler: () => this.updateCurrentPage('UserProfilePage'),
    };

    const rightButtonConfig = {
      title: 'Scan',
      handler: () => this.updateCurrentPage('CameraPage'),
    };

    switch(this.state.currentPage) {
      case 'IndexPage':
        return(
          <View style={styles.parentContainer}>
            <NavigationBar
              style={styles.navbar}
              leftButton={leftButtonConfig}
              title={titleConfig}
              rightButton={rightButtonConfig}
            />
            <ScrollView>
              <IndexPage
              updateCurrentPage = {this.updateCurrentPage} />
            </ScrollView>
          </View>
        )
      case 'SearchPage':
        return(
          <View style={styles.parentContainer}>
            <NavigationBar
              style={styles.navbar}
              leftButton={leftButtonConfig}
              title={titleConfig}
              rightButton={rightButtonConfig}
            />
            <ScrollView>
              <SearchPage
                searchProduct = {this.searchProduct}
                updateSearchTerm = {this.updateSearchTerm}
              />
            </ScrollView>
          </View>
        )
      case 'CameraPage':
        return(
          <View style={styles.parentContainer}>
            <NavigationBar
              style={styles.navbar}
              leftButton={leftButtonConfig}
              title={titleConfig}
            />
            <ScrollView>
              <CameraPage
                updateCurrentPage = {this.updateCurrentPage}
                searchProduct = {this.searchProduct}
                updateSearchTerm = {this.updateSearchTerm}
              />
            </ScrollView>
          </View>
        )
      case 'ProductPage':
        return(
          <View style={styles.parentContainer}>
            <NavigationBar
              style={styles.navbar}
              leftButton={leftButtonConfig}
              title={titleConfig}
              rightButton={rightButtonConfig}
            />
            <ScrollView>
              <ProductPage
                foundProduct = {this.state.foundProduct}
                foundProductSaved = {this.state.foundProductSaved}
                updateCurrentPage = {this.updateCurrentPage}
                saveSearch = {this.saveSearch}
              />
            </ScrollView>
        </View>
        )
      case 'NoResultsPage':
        return(
          <View style={styles.parentContainer}>
            <NavigationBar
              style={styles.navbar}
              leftButton={leftButtonConfig}
              title={titleConfig}
              rightButton={rightButtonConfig}
            />
            <ScrollView>
              <NoResultsPage
                updateCurrentPage = {this.updateCurrentPage}
                searchTerm = {this.state.searchTerm}
                />
            </ScrollView>
          </View>
        )
      case 'SearchingPage':
        return(
          <SearchingPage />
        )
      case 'UserProfilePage':
        return(
          <View style={styles.parentContainer}>
            <NavigationBar
              style={styles.navbar}
              leftButton={leftButtonConfig}
              title={titleConfig}
              rightButton={rightButtonConfig}
            />
            <ScrollView>
              <UserProfilePage />
            </ScrollView>
          </View>
        )
      default:
        return(
          <DefaultPage />
        )
    }
  }
}

// CHILDREN

// VICTORIA

class CameraPage extends Component {
  constructor() {
    super()
    this.onBarCodeRead = this.onBarCodeRead.bind(this)
    this.onPressSearchButton = this.onPressSearchButton.bind(this)

    // for testing
    this.existingItem = this.existingItem.bind(this)
    this.nonExistingItem = this.nonExistingItem.bind(this)
  }

  onBarCodeRead(e) {
    this.props.updateSearchTerm('Product')
    this.props.searchProduct(e.data)
  }

  onPressSearchButton(){
    this.props.updateCurrentPage("SearchPage")
  }

  // for testing
  existingItem() {
    this.props.updateSearchTerm('Product')
    this.props.searchProduct('03077504')
  }

  nonExistingItem() {
    this.props.updateSearchTerm('Product')
    this.props.searchProduct('asdf')
  }

  render() {
    return(
      <View style={styles.body}>
        <Text style={styles.header}>Place Barcode in View</Text>
        <Camera
          ref={(cam) => {this.camera = cam;}}
          style={styles.preview}
          onBarCodeRead = {this.onBarCodeRead}
          aspect={Camera.constants.Aspect.fill}>
        </Camera>
        <Text style={styles.small_content}>The camera will automatically detect when a barcode is present</Text>

        <Text style={styles.small_content}>{"\n\n"}No item to scan?</Text>

        <TouchableOpacity>
          <Button
            title="Enter a Search Term"
            onPress={this.onPressSearchButton}
          />
          <Button
            title="Test: Existing Item"
            onPress={this.existingItem}
            color='red'
          />
          <Button
            title="Test: Nonexisting Item"
            onPress={this.existingItem}
            color='red'
          />
        </TouchableOpacity>
      </View>
    );
  }
}

// TIFF

class ProductPage extends Component {
  constructor() {
    super()
    this.saveItem = this.saveItem.bind(this)
  }

  saveItem() {
    this.props.saveSearch(this.props.foundProduct.search.id);
  }

  scoreConverter() {
    let numberScore = this.props.foundProduct.product.score
      switch(numberScore) {
        case 5:
          return ('A');
        case 4:
          return ('B');
        case 3:
          return ('C');
        case 2:
          return ('D');
        case 1:
          return ('F');
        default:
          return ('Not Found');
      }
  }

  renderIngredientList() {
    return this.props.foundProduct.ingredients.map(ingredient =>
      <View key={ingredient.id}>
        { ingredient.is_natural ?
          <Image
            style={{width: 50, height: 50}}
            source={{uri: "https://image.flaticon.com/icons/png/512/32/32070.png"}}
          />
          :
          <Image
            style={{width: 50, height: 50}}
            source={{uri: "https://d30y9cdsu7xlg0.cloudfront.net/png/909435-200.png"}}
          />
         }

        <IngredientModal ingredient = {ingredient} />
      </View>
    );
  }

  render() {
    return(
      <View>
        <Image
          style={{width: 375, height: 200}}
        source={{uri: this.props.foundProduct.product.img_url}}
        />
        <Text style={styles.header}>{this.props.foundProduct.product.name}</Text>
        <Text>Score: {this.scoreConverter()}</Text>

        {this.props.foundProductSaved ?
          <Text>Product is Saved</Text>
          :
          <Button
            onPress={this.saveItem}
            title="Save Product"
          />
        }

        <Text>Ingredients:</Text>
        {this.renderIngredientList()}

      </View>
    )
  }
}

class IngredientModal extends Component {
  constructor() {
    super()
    this.state = {
      modalVisible: false
    }
    this.setModalVisible = this.setModalVisible.bind(this)
  }

  setModalVisible(visible) {
    this.setState({modalVisible: visible});
  }

  render() {
    return (
      <View style={{marginTop: 22}}>

        <Modal
          animationType={"slide"}
          transparent={false}
          visible={this.state.modalVisible}
          onRequestClose={() => {alert("Modal has been closed.")}}
          >
          <View>
            <Image
              style={{width: 375, height: 200}}
            source={{uri: this.props.ingredient.img_url}}
            />

            <Text style={styles.header}>{this.props.ingredient.name}</Text>
            <Text>{this.props.ingredient.description}</Text>

            <TouchableHighlight onPress={() => {this.setModalVisible(!this.state.modalVisible)}}>
              <Text>Hide Modal</Text>
            </TouchableHighlight>

          </View>
        </Modal>

        <TouchableHighlight onPress={() => {this.setModalVisible(true)}}>
          <Text>{this.props.ingredient.name}</Text>
        </TouchableHighlight>

      </View>
    );
  }
}

// KANAN

class NoResultsPage extends Component {
  constructor(){
    super()
    this.searchAgain = this.searchAgain.bind(this)
    this.scanAgain = this.scanAgain.bind(this)
  }

  searchAgain(){
    this.props.updateCurrentPage("SearchPage")
  }

  scanAgain(){
    this.props.updateCurrentPage("CameraPage")
  }

  render() {
    return (
      <View>
        <Text style={styles.header}>{this.props.searchTerm} was not found</Text>
        <Text> Would you like to try another product?</Text>
        <Button
         title="Scan Another Product"
         onPress={this.scanAgain}
         color="blue"
        />
        <Text>or</Text>
        <Button
         title="Search Product"
         onPress={this.searchAgain}
         color="green"
        />
      </View>
    );
  }
}

// KANAN

class SearchPage extends Component {
  constructor(){
    super();
    this.state = {
      text: ''
    };
    this.startSearch = this.startSearch.bind(this)
  }

  startSearch() {
    this.props.updateSearchTerm(this.state.text)
    this.props.searchProduct(this.state.text)
  }

  render() {
    return (
      <View style={styles.body}>
        <Text style={styles.header}>Search for a Product:</Text>
        <TextInput
          placeholder="Enter a Product Name or UPC"
          placeholderTextColor='#949799'
          returnKeyType="search"
          keyboardType="default"
          style={styles.input}
          onChangeText={(text) => this.setState({text})}
          onSubmitEditing={this.startSearch}
        />
        <TouchableOpacity>
          <Button title="Search" onPress={this.startSearch}/>
        </TouchableOpacity>
      </View>
    )
  }
}

// KANAN

class IndexPage extends Component {
  constructor(){
    super()
    this._onPressSearchButton = this._onPressSearchButton.bind(this)
    this._onPressScanButton = this._onPressScanButton.bind(this)
    this._onPressSignUpButton = this._onPressSignUpButton.bind(this)
    this._onPressSignInButton = this._onPressSignInButton.bind(this)
  }

  _onPressSearchButton(){
    this.props.updateCurrentPage("SearchPage")
  }

  _onPressScanButton(){
    this.props.updateCurrentPage("CameraPage")
  }

  _onPressSignUpButton(){
    this.props.updateCurrentPage("IndexPage")
  }

  _onPressSignInButton(){
    this.props.updateCurrentPage("IndexPage")
  }

  render() {
    return (
      <View>
        <TouchableOpacity>
          <Button title="Scan Product" onPress={this._onPressScanButton} />
        </TouchableOpacity>
        <TouchableOpacity>
          <Button title="Search Product" onPress={this._onPressSearchButton} />
        </TouchableOpacity>
        <TouchableOpacity>
          <Button onPress={this._onPressSignUpButton} title="Sign Up" />
        </TouchableOpacity>
        <TouchableOpacity>
          <Button onPress={this._onPressSignInButton} title="Sign In" />
        </TouchableOpacity>
      </View>
    );
  }
}

// DONE

class SearchingPage extends Component {
  render() {
    return(
      <View style={styles.body}>
        <ActivityIndicator
          animating = {true}
          size = 'large'
          style={styles.activityIndicator}
        />
        <Text>Searching...</Text>
      </View>
    );
  }
}

// FOR TESTING

class UserProfilePage extends Component {
  render() {
    return(
      <View style={styles.body}>
        <Text style={styles.header}>User Profile Page</Text>
        <Text>This is where the users info will go.</Text>
      </View>
    );
  }
}

class DefaultPage extends Component {
  render() {
    return(
      <View style={styles.body}>
        <Text style={styles.header}>Default Page</Text>
        <Text>The case statement hit default</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  parentContainer: {
    flex: 1,
    // justifyContent: 'center',
    // alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  body: {
    justifyContent: 'center',
    alignItems: 'center',
  },
  input: {
    height: 40,
    width: 300,
    borderRadius: 10,
    margin: 10,
    textAlign: 'center',
    borderColor: 'gray',
    borderWidth: 1,
  },
  buttonContainer: {
    backgroundColor: "green",
    borderRadius: 15,
    padding: 5
  },
  header: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  small_content: {
    textAlign: 'center',
    margin: 10,
  },
  preview: {
    height: 300,
    width: '100%',
  },
  activityIndicator: {
    marginBottom: 20,
  },
  navbar: {
    justifyContent: 'space-around',
    width: '100%',
    backgroundColor: '#EAF1F4',
  },
});

AppRegistry.registerComponent('FoodrFrontend', () => FoodrFrontend);
<commit_msg>Normalize Product Page and Ingredient Modal styles to use TouchableOpacity. No more use of TouchableHighlight.<commit_after>import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  ScrollView,
  Dimensions,
  Button,
  ActivityIndicator,
  Image,
  Modal,
  AlertIOS,
  TextInput,
  TouchableOpacity
} from 'react-native';
import Camera from 'react-native-camera';
import NavigationBar from 'react-native-navbar';

// PARENT

export default class FoodrFrontend extends Component {
  constructor() {
    super()
    this.state = {
      currentPage: 'CameraPage',
      previousPage: 'DefaultPage',
      foundProduct: {},
      foundProductSaved: false,
      userId: false, // false if not logged in
      searchTerm: ''
    }
    this.updateCurrentPage = this.updateCurrentPage.bind(this)
    this.searchProduct = this.searchProduct.bind(this)
    this.updateSearchTerm = this.updateSearchTerm.bind(this)
    this.saveSearch = this.saveSearch.bind(this)
  }

  searchProduct(upc) {
    this.updateCurrentPage('SearchingPage')

    // fetch('https://dbc-foodr-api.herokuapp.com/products/' + upc + "?user_id=" + this.state.userId)
    fetch('http://localhost:3000/products/' + upc + "?user_id=" + this.state.userId)
    .then((data) => data.json())
    .then((jsonData) => {
      this.setState({ foundProduct: jsonData })
      if (this.state.foundProduct.found) {
        this.setState({foundProductSaved: jsonData.search.is_saved})
        this.updateCurrentPage('ProductPage')
      } else {
        this.updateCurrentPage('NoResultsPage')
      }
    });
  }

  saveSearch(searchId) {
    if (this.state.userId) {
      fetch('http://localhost:3000/searches/' + searchId + '/save', {method: 'POST'})
      .then(data => data.json())
      .then(jsonData => {
        if (jsonData.save_successful) {
          this.setState({foundProductSaved: true});
          AlertIOS.alert('Product Saved!');
        } else {
          this.setState({foundProductSaved: false});
          AlertIOS.alert('Product was not saved.');
        }
      })
    } else {
      AlertIOS.alert('Please sign up or login to save an item.');
    }
  }

  updateCurrentPage(pageName) {
    this.setState({currentPage: pageName})
  }

  updateSearchTerm(searchTerm) {
    this.setState({searchTerm: searchTerm})
  }

  render() {
    const titleConfig = {
      title: 'FOODR',
    };

    const leftButtonConfig = {
      title: 'Profile',
      handler: () => this.updateCurrentPage('UserProfilePage'),
    };

    const rightButtonConfig = {
      title: 'Scan',
      handler: () => this.updateCurrentPage('CameraPage'),
    };

    switch(this.state.currentPage) {
      case 'IndexPage':
        return(
          <View style={styles.parentContainer}>
            <NavigationBar
              style={styles.navbar}
              leftButton={leftButtonConfig}
              title={titleConfig}
              rightButton={rightButtonConfig}
            />
            <ScrollView>
              <IndexPage
              updateCurrentPage = {this.updateCurrentPage} />
            </ScrollView>
          </View>
        )
      case 'SearchPage':
        return(
          <View style={styles.parentContainer}>
            <NavigationBar
              style={styles.navbar}
              leftButton={leftButtonConfig}
              title={titleConfig}
              rightButton={rightButtonConfig}
            />
            <ScrollView>
              <SearchPage
                searchProduct = {this.searchProduct}
                updateSearchTerm = {this.updateSearchTerm}
              />
            </ScrollView>
          </View>
        )
      case 'CameraPage':
        return(
          <View style={styles.parentContainer}>
            <NavigationBar
              style={styles.navbar}
              leftButton={leftButtonConfig}
              title={titleConfig}
            />
            <ScrollView>
              <CameraPage
                updateCurrentPage = {this.updateCurrentPage}
                searchProduct = {this.searchProduct}
                updateSearchTerm = {this.updateSearchTerm}
              />
            </ScrollView>
          </View>
        )
      case 'ProductPage':
        return(
          <View style={styles.parentContainer}>
            <NavigationBar
              style={styles.navbar}
              leftButton={leftButtonConfig}
              title={titleConfig}
              rightButton={rightButtonConfig}
            />
            <ScrollView>
              <ProductPage
                foundProduct = {this.state.foundProduct}
                foundProductSaved = {this.state.foundProductSaved}
                updateCurrentPage = {this.updateCurrentPage}
                saveSearch = {this.saveSearch}
              />
            </ScrollView>
        </View>
        )
      case 'NoResultsPage':
        return(
          <View style={styles.parentContainer}>
            <NavigationBar
              style={styles.navbar}
              leftButton={leftButtonConfig}
              title={titleConfig}
              rightButton={rightButtonConfig}
            />
            <ScrollView>
              <NoResultsPage
                updateCurrentPage = {this.updateCurrentPage}
                searchTerm = {this.state.searchTerm}
                />
            </ScrollView>
          </View>
        )
      case 'SearchingPage':
        return(
          <SearchingPage />
        )
      case 'UserProfilePage':
        return(
          <View style={styles.parentContainer}>
            <NavigationBar
              style={styles.navbar}
              leftButton={leftButtonConfig}
              title={titleConfig}
              rightButton={rightButtonConfig}
            />
            <ScrollView>
              <UserProfilePage />
            </ScrollView>
          </View>
        )
      default:
        return(
          <DefaultPage />
        )
    }
  }
}

// CHILDREN

// VICTORIA

class CameraPage extends Component {
  constructor() {
    super()
    this.onBarCodeRead = this.onBarCodeRead.bind(this)
    this.onPressSearchButton = this.onPressSearchButton.bind(this)

    // for testing
    this.existingItem = this.existingItem.bind(this)
    this.nonExistingItem = this.nonExistingItem.bind(this)
  }

  onBarCodeRead(e) {
    this.props.updateSearchTerm('Product')
    this.props.searchProduct(e.data)
  }

  onPressSearchButton(){
    this.props.updateCurrentPage("SearchPage")
  }

  // for testing
  existingItem() {
    this.props.updateSearchTerm('Product')
    this.props.searchProduct('03077504')
  }

  nonExistingItem() {
    this.props.updateSearchTerm('Product')
    this.props.searchProduct('asdf')
  }

  render() {
    return(
      <View style={styles.body}>
        <Text style={styles.header}>Place Barcode in View</Text>
        <Camera
          ref={(cam) => {this.camera = cam;}}
          style={styles.cameraView}
          onBarCodeRead = {this.onBarCodeRead}
          aspect={Camera.constants.Aspect.fill}>
        </Camera>
        <Text style={styles.small_content}>The camera will automatically detect when a barcode is present</Text>

        <Text style={styles.small_content}>{"\n\n"}No item to scan?</Text>

        <TouchableOpacity>
          <Button
            title="Enter a Search Term"
            onPress={this.onPressSearchButton}
          />
          <Button
            title="Test: Existing Item"
            onPress={this.existingItem}
            color='red'
          />
          <Button
            title="Test: Nonexisting Item"
            onPress={this.nonExistingItem}
            color='red'
          />
        </TouchableOpacity>
      </View>
    );
  }
}

// TIFF

class ProductPage extends Component {
  constructor() {
    super()
    this.saveItem = this.saveItem.bind(this)
  }

  saveItem() {
    this.props.saveSearch(this.props.foundProduct.search.id);
  }

  scoreConverter() {
    let numberScore = this.props.foundProduct.product.score
      switch(numberScore) {
        case 5:
          return ('A');
        case 4:
          return ('B');
        case 3:
          return ('C');
        case 2:
          return ('D');
        case 1:
          return ('F');
        default:
          return ('Not Found');
      }
  }

  renderIngredientList() {
    return this.props.foundProduct.ingredients.map(ingredient =>
      <View style={styles.inlineContainer} key={ingredient.id}>
        { ingredient.is_natural ?
          <Image
            style={{width: 50, height: 50}}
            source={{uri: "https://image.flaticon.com/icons/png/512/32/32070.png"}}
          />
          :
          <Image
            style={{width: 50, height: 50}}
            source={{uri: "https://d30y9cdsu7xlg0.cloudfront.net/png/909435-200.png"}}
          />
         }

        <IngredientModal ingredient = {ingredient} />
      </View>
    );
  }

  render() {
    return(
      <View style={styles.body}>
        <Image
          style={{width: 375, height: 200}}
          source={{uri: this.props.foundProduct.product.img_url}}
        />
        <Text style={styles.header}>{this.props.foundProduct.product.name}</Text>
        <Text>Score: {this.scoreConverter()}</Text>

        {this.props.foundProductSaved ?
          <Text>Product is Saved</Text>
          :
          <Button
            onPress={this.saveItem}
            title="Save Product"
          />
        }

        <Text style={styles.header}>Ingredients:</Text>
        {this.renderIngredientList()}

      </View>
    )
  }
}

class IngredientModal extends Component {
  constructor() {
    super()
    this.state = {
      modalVisible: false
    }
    this.setModalVisible = this.setModalVisible.bind(this)
  }

  setModalVisible(visible) {
    this.setState({modalVisible: visible});
  }

  render() {
    return (
      <View>
        <Modal
          animationType={"slide"}
          transparent={false}
          visible={this.state.modalVisible}
        >
          <View style={{marginTop: 22}}>
            <Image
              style={{width: 375, height: 200}}
              source={{uri: this.props.ingredient.img_url}}
            />

            <Text style={styles.header}>{this.props.ingredient.name}</Text>
            <Text style={styles.small_content}>{this.props.ingredient.description}</Text>

            <TouchableOpacity>
              <Button
                onPress={() => {this.setModalVisible(!this.state.modalVisible)}}
                title="Back to Product"
              />
            </TouchableOpacity>

          </View>
        </Modal>

        <TouchableOpacity>
          <Button
            onPress={() => {this.setModalVisible(true)}}
            title={this.props.ingredient.name}
          />
        </TouchableOpacity>
      </View>
    );
  }
}

// KANAN

class NoResultsPage extends Component {
  constructor(){
    super()
    this.searchAgain = this.searchAgain.bind(this)
    this.scanAgain = this.scanAgain.bind(this)
  }

  searchAgain(){
    this.props.updateCurrentPage("SearchPage")
  }

  scanAgain(){
    this.props.updateCurrentPage("CameraPage")
  }

  render() {
    return (
      <View>
        <Text style={styles.header}>{this.props.searchTerm} was not found</Text>
        <Text> Would you like to try another product?</Text>
        <Button
         title="Scan Another Product"
         onPress={this.scanAgain}
         color="blue"
        />
        <Text>or</Text>
        <Button
         title="Search Product"
         onPress={this.searchAgain}
         color="green"
        />
      </View>
    );
  }
}

// KANAN

class SearchPage extends Component {
  constructor(){
    super();
    this.state = {
      text: ''
    };
    this.startSearch = this.startSearch.bind(this)
  }

  startSearch() {
    this.props.updateSearchTerm(this.state.text)
    this.props.searchProduct(this.state.text)
  }

  render() {
    return (
      <View style={styles.body}>
        <Text style={styles.header}>Search for a Product:</Text>
        <TextInput
          placeholder="Enter a Product Name or UPC"
          placeholderTextColor='#949799'
          returnKeyType="search"
          keyboardType="default"
          style={styles.input}
          onChangeText={(text) => this.setState({text})}
          onSubmitEditing={this.startSearch}
        />
        <TouchableOpacity>
          <Button title="Search" onPress={this.startSearch}/>
        </TouchableOpacity>
      </View>
    )
  }
}

// KANAN

class IndexPage extends Component {
  constructor(){
    super()
    this._onPressSearchButton = this._onPressSearchButton.bind(this)
    this._onPressScanButton = this._onPressScanButton.bind(this)
    this._onPressSignUpButton = this._onPressSignUpButton.bind(this)
    this._onPressSignInButton = this._onPressSignInButton.bind(this)
  }

  _onPressSearchButton(){
    this.props.updateCurrentPage("SearchPage")
  }

  _onPressScanButton(){
    this.props.updateCurrentPage("CameraPage")
  }

  _onPressSignUpButton(){
    this.props.updateCurrentPage("IndexPage")
  }

  _onPressSignInButton(){
    this.props.updateCurrentPage("IndexPage")
  }

  render() {
    return (
      <View>
        <TouchableOpacity>
          <Button title="Scan Product" onPress={this._onPressScanButton} />
        </TouchableOpacity>
        <TouchableOpacity>
          <Button title="Search Product" onPress={this._onPressSearchButton} />
        </TouchableOpacity>
        <TouchableOpacity>
          <Button onPress={this._onPressSignUpButton} title="Sign Up" />
        </TouchableOpacity>
        <TouchableOpacity>
          <Button onPress={this._onPressSignInButton} title="Sign In" />
        </TouchableOpacity>
      </View>
    );
  }
}

// DONE

class SearchingPage extends Component {
  render() {
    return(
      <View style={styles.body}>
        <ActivityIndicator
          animating = {true}
          size = 'large'
          style={styles.activityIndicator}
        />
        <Text>Searching...</Text>
      </View>
    );
  }
}

// FOR TESTING

class UserProfilePage extends Component {
  render() {
    return(
      <View style={styles.body}>
        <Text style={styles.header}>User Profile Page</Text>
        <Text>This is where the users info will go.</Text>
      </View>
    );
  }
}

class DefaultPage extends Component {
  render() {
    return(
      <View style={styles.body}>
        <Text style={styles.header}>Default Page</Text>
        <Text>The case statement hit default</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  parentContainer: {
    flex: 1,
    // justifyContent: 'center',
    // alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  inlineContainer: {
    flexWrap: 'wrap',
    flexDirection: 'row',
  },
  body: {
    justifyContent: 'center',
    alignItems: 'center',
  },
  input: {
    height: 40,
    width: 300,
    borderRadius: 10,
    margin: 10,
    textAlign: 'center',
    borderColor: 'gray',
    borderWidth: 1,
  },
  header: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  small_content: {
    textAlign: 'center',
    margin: 10,
  },
  cameraView: {
    height: 300,
    width: '100%',
  },
  activityIndicator: {
    marginBottom: 20,
  },
  navbar: {
    justifyContent: 'space-around',
    width: '100%',
    backgroundColor: '#EAF1F4',
  },
});

AppRegistry.registerComponent('FoodrFrontend', () => FoodrFrontend);
<|endoftext|>


<commit_before>/**
 * @author mrdoob / http://mrdoob.com
 * Based on @tojiro's vr-samples-utils.js
 */

var WEBVR = {

	isLatestAvailable: function () {

		console.warn( 'WEBVR: isLatestAvailable() is being deprecated. Use .isAvailable() instead.' );
		return this.isAvailable();

	},

	isAvailable: function () {

		return navigator.getVRDisplays !== undefined;

	},

	getVRDisplay: function ( onDisplay ) {

		if ( 'getVRDisplays' in navigator ) {

			navigator.getVRDisplays()
				.then( function ( displays ) {

					onDisplay( displays[ 0 ] );

				} )
				.catch( function () {
					// no displays
				} );

		}

	},

	getMessage: function () {

		var message;

		if ( navigator.getVRDisplays ) {

			navigator.getVRDisplays().then( function ( displays ) {

				if ( displays.length === 0 ) message = 'WebVR supported, but no VRDisplays found.';

			} );

		} else {

			message = 'Your browser does not support WebVR. See webvr.info for assistance.';

		}

		if ( message !== undefined ) {

			var container = document.createElement( 'div' );
			container.style.position = 'absolute';
			container.style.left = '0';
			container.style.top = '0';
			container.style.right = '0';
			container.style.zIndex = '999';
			container.align = 'center';

			var error = document.createElement( 'div' );
			error.style.fontFamily = 'sans-serif';
			error.style.fontSize = '16px';
			error.style.fontStyle = 'normal';
			error.style.lineHeight = '26px';
			error.style.backgroundColor = '#fff';
			error.style.color = '#000';
			error.style.padding = '10px 20px';
			error.style.margin = '50px';
			error.style.display = 'inline-block';
			error.innerHTML = message;
			container.appendChild( error );

			return container;

		}

	},

	getButton: function ( display, canvas ) {

		/*
		if ( display instanceof VRDisplay === false ) {

			console.error( 'WebVR.getButton() now expects a VRDisplay.' );
			return;

		}
		*/

		var button = document.createElement( 'button' );
		button.style.position = 'absolute';
		button.style.left = 'calc(50% - 50px)';
		button.style.bottom = '20px';
		button.style.width = '100px';
		button.style.border = '0';
		button.style.padding = '8px';
		button.style.cursor = 'pointer';
		button.style.backgroundColor = '#000';
		button.style.color = '#fff';
		button.style.fontFamily = 'sans-serif';
		button.style.fontSize = '13px';
		button.style.fontStyle = 'normal';
		button.style.textAlign = 'center';
		button.style.zIndex = '999';

		if ( display ) {

			button.textContent = 'ENTER VR';
			button.onclick = function () {

				display.isPresenting ? display.exitPresent() : display.requestPresent( [ { source: canvas } ] );

			};

			window.addEventListener( 'vrdisplaypresentchange', function () {

				button.textContent = display.isPresenting ? 'EXIT VR' : 'ENTER VR';

			}, false );

		} else {

			button.textContent = 'NO VR DISPLAY';

		}

		return button;

	}

};
<commit_msg>WebVR: Clean up.<commit_after>/**
 * @author mrdoob / http://mrdoob.com
 * Based on @tojiro's vr-samples-utils.js
 */

var WEBVR = {

	isLatestAvailable: function () {

		console.warn( 'WEBVR: isLatestAvailable() is being deprecated. Use .isAvailable() instead.' );
		return this.isAvailable();

	},

	isAvailable: function () {

		return navigator.getVRDisplays !== undefined;

	},

	getVRDisplay: function ( onDisplay ) {

		if ( 'getVRDisplays' in navigator ) {

			navigator.getVRDisplays()
				.then( function ( displays ) {

					onDisplay( displays[ 0 ] );

				} )
				.catch( function () {
					// no displays
				} );

		}

	},

	getMessage: function () {

		var message;

		if ( navigator.getVRDisplays ) {

			navigator.getVRDisplays().then( function ( displays ) {

				if ( displays.length === 0 ) message = 'WebVR supported, but no VRDisplays found.';

			} );

		} else {

			message = 'Your browser does not support WebVR. See webvr.info for assistance.';

		}

		if ( message !== undefined ) {

			var container = document.createElement( 'div' );
			container.style.position = 'absolute';
			container.style.left = '0';
			container.style.top = '0';
			container.style.right = '0';
			container.style.zIndex = '999';
			container.align = 'center';

			var error = document.createElement( 'div' );
			error.style.fontFamily = 'sans-serif';
			error.style.fontSize = '16px';
			error.style.fontStyle = 'normal';
			error.style.lineHeight = '26px';
			error.style.backgroundColor = '#fff';
			error.style.color = '#000';
			error.style.padding = '10px 20px';
			error.style.margin = '50px';
			error.style.display = 'inline-block';
			error.innerHTML = message;
			container.appendChild( error );

			return container;

		}

	},

	getButton: function ( effect, canvas ) {

		var button = document.createElement( 'button' );
		button.style.position = 'absolute';
		button.style.left = 'calc(50% - 50px)';
		button.style.bottom = '20px';
		button.style.width = '100px';
		button.style.border = '0';
		button.style.padding = '8px';
		button.style.cursor = 'pointer';
		button.style.backgroundColor = '#000';
		button.style.color = '#fff';
		button.style.fontFamily = 'sans-serif';
		button.style.fontSize = '13px';
		button.style.fontStyle = 'normal';
		button.style.textAlign = 'center';
		button.style.zIndex = '999';

		if ( effect.getVRDisplay() ) {

			button.textContent = 'ENTER VR';
			button.onclick = function () {

				effect.isPresenting ? effect.exitPresent() : effect.requestPresent( [ { source: canvas } ] );

			};

			window.addEventListener( 'vrdisplaypresentchange', function () {

				button.textContent = effect.isPresenting ? 'EXIT VR' : 'ENTER VR';

			}, false );

		} else {

			button.textContent = 'NO VR DISPLAY';

		}

		return button;

	}

};
<|endoftext|>


<commit_before>// ==UserScript==
// @name             Get DLC Info from SteamDB
// @namespace        sak32009-get-dlc-info-from-steamdb
// @description      Get DLC Info from SteamDB
// @author           Sak32009
// @contributor      cs.rin.ru
// @version          3.5.8
// @license          MIT
// @homepageURL      https://github.com/Sak32009/GetDLCInfoFromSteamDB/
// @supportURL       http://cs.rin.ru/forum/viewtopic.php?f=10&t=71837
// @updateURL        https://github.com/Sak32009/GetDLCInfoFromSteamDB/raw/master/sak32009-get-dlc-info-from-steamdb.meta.js
// @downloadURL      https://github.com/Sak32009/GetDLCInfoFromSteamDB/raw/master/sak32009-get-dlc-info-from-steamdb.user.js
// @icon             https://raw.githubusercontent.com/Sak32009/GetDLCInfoFromSteamDB/master/sak32009-get-dlc-info-from-steamdb-32.png
// @icon64           https://raw.githubusercontent.com/Sak32009/GetDLCInfoFromSteamDB/master/sak32009-get-dlc-info-from-steamdb-64.png
// @match            *://steamdb.info/app/*
// @match            *://steamdb.info/search/*
// @require          https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @require          https://steamdb.info/static/js/tabbable.4f8f7fce.js
// @grant            none
// @run-at           document-end
// ==/UserScript==
<commit_msg>Update 3.5.9<commit_after>// ==UserScript==
// @name             Get DLC Info from SteamDB
// @namespace        sak32009-get-dlc-info-from-steamdb
// @description      Get DLC Info from SteamDB
// @author           Sak32009
// @contributor      cs.rin.ru
// @version          3.5.9
// @license          MIT
// @homepageURL      https://github.com/Sak32009/GetDLCInfoFromSteamDB/
// @supportURL       http://cs.rin.ru/forum/viewtopic.php?f=10&t=71837
// @updateURL        https://github.com/Sak32009/GetDLCInfoFromSteamDB/raw/master/sak32009-get-dlc-info-from-steamdb.meta.js
// @downloadURL      https://github.com/Sak32009/GetDLCInfoFromSteamDB/raw/master/sak32009-get-dlc-info-from-steamdb.user.js
// @icon             https://raw.githubusercontent.com/Sak32009/GetDLCInfoFromSteamDB/master/sak32009-get-dlc-info-from-steamdb-32.png
// @icon64           https://raw.githubusercontent.com/Sak32009/GetDLCInfoFromSteamDB/master/sak32009-get-dlc-info-from-steamdb-64.png
// @match            *://steamdb.info/app/*
// @match            *://steamdb.info/search/*
// @require          https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @require          https://steamdb.info/static/js/tabbable.4f8f7fce.js
// @grant            none
// @run-at           document-end
// ==/UserScript==
<|endoftext|>


<commit_before>(function(exports){

	/*!
	 *
	 * Table: abstract representation of an HTML table
	 *
	 */
	var node = exports;
	exports.Table = Table;

	// For simple testing
	//module.exports = Table;

	var JSUS = node.JSUS;
	var NDDB = node.NDDB;

	Table.H = ['x','y','z'];
	Table.V = ['y','x', 'z'];

	Table.log = console.log;

  function Table (options, data) {
	var options = options || {};

	JSUS.extend(node.NDDB,this);
    node.NDDB.call(this, options, data);

    Table.log = options.log || Table.log;
    this.defaultDim1 = options.defaultDim1 || 'x';
    this.defaultDim2 = options.defaultDim2 || 'y';
    this.defaultDim3 = options.defaultDim3 || 'z';

    // Class for missing cells
    this.missing = options.missing || 'missing';
    this.pointers = {
    				x: options.pointerX || 0,
    				y: options.pointerY || 0,
    				z: options.pointerZ || 0
    };

    this.id = options.id || 'table';

//	if (options.root) {
//		this.setRoot(options.root);
//	}
//	else {
//		this.root = this.createRoot(this.id, options);
//	}
//
//	this.pointer = this.root; // Points to the last row added;
//	this.odd = 'odd';
  };

  Table.prototype.setRoot = function(root) {
	  if (!root) return false;
	  if (this.root && this.root.childNodes) {
		  root.appendChild(children);
	  }
	  this.root = root;
	  this.id = ('undefined' !== typeof root.id) ? root.id : this.id;
  };

  Table.prototype.append = function(root) {
    return root.appendChild(this.root);
  };

  Table.prototype.createRoot = function (id, options) {
    var root = document.createElement('table');
    root.id = id;
    return root;
  };

  Table.prototype.addHeaderRow = function (data, attributes) {
    var thead = document.createElement('thead');
    return this.addRow(data, attributes, thead);
  };

//  Table.prototype.addRow = function (data, attributes, container) {
//    var row = document.createElement('tr');
//
//    if (attributes) {
//    	node.window.addAttributes2Elem(row, attributes);
//    }
//
//    for (var i = 0; i < data.length; i++) {
//            var cell = document.createElement('td');
//            var cellContent = document.createTextNode(data[i]);
//            cell.appendChild(cellContent);
//            row.appendChild(cell);
//        }
//
//    // If we have other elements, e.g. thead, add them.
//    // If it is not a normal no even or odd class is added.
//    if (container) {
//      container.appendChild(row);
//      return this.appendRow(container, false);
//    }
//    else {
//      return this.appendRow(row);
//    }
//
//  };
//
  Table.prototype.appendRow = function (row, addClass) {
    var addClass = ('undefined' !== typeof addClass) ? addClass : true;
    this.root.appendChild(row);
    this.pointer = row;
    if (addClass) {
      row.className += this.id + '_' + this.odd;
      this.odd = (this.odd == 'odd') ? 'even' : 'odd'; // toggle pointer to odd or even row
    }
    return row;
  };

  Table._checkDim123 = function (dims) {
	  var t = Table.H.slice(0);
	  for (var i=0; i< dims.length; i++) {
		  if (!JSUS.removeElement(dims[i],t)) return false;
	  }
	  return true;
  };

  /**
   * Updates the reference to the foremost element in the table.
   *
   * @param
   */
  Table.prototype.updatePointer = function (pointer, value) {
	 if (!pointer) return false;
	 if (!JSUS.in_array(pointer, Table.H)) {
		 Table.log('Cannot update invalid pointer: ' + pointer, 'ERR');
		 return false;
	 }

	 if (value > this.pointers[pointer]) {
		 this.pointers[pointer] = value;
		 return true;
	 }

  };

  Table.prototype._add = function (data, dims, x, y, z) {
	if (!data) return false;
	if (dims) {
		if (!Table._checkDim123(dims)){
			Table.log('Invalid value for dimensions. Accepted only: x,y,z.')
			return false
		}
	}
	else {
		dims = Table.H;
	}

//	console.log('DATA TBL');
//	console.log(data);

	// By default, only the second dimension is incremented
	var x = x || this.pointers[dims[0]];
	var y = y || this.pointers[dims[1]] + 1;
	var z = z || this.pointers[dims[2]];

	if ('object' !== typeof data) data = [data];

	var insertCell = function (content){
		//console.log('content');
//		console.log(x + ' ' + y + ' ' + z);
//		console.log(i + ' ' + j + ' ' + h);

		var cell = {};
		cell[dims[0]] = i; // i always defined
		cell[dims[1]] = (j) ? y+j : y;
		cell[dims[2]] = (h) ? z+h : z;
		cell['content'] = content;
		//console.log(cell);
		this.insert(new Cell(cell));
		this.updatePointer(dims[0],cell[dims[0]]);
		this.updatePointer(dims[1],cell[dims[1]]);
		this.updatePointer(dims[2],cell[dims[2]]);
	};

	var cell = null;
	// Loop Dim1
	for (var i = 0; i < data.length; i++) {
		//console.log('data_i');
		//console.log(data[i]);
		if (data[i] instanceof Array) {
			// Loop Dim2
			for (var j = 0; j < data[i].length; j++) {
//				console.log(data[i]);
				if (data[i][j] instanceof Array) {
//					Table.log(data[i][j]);
//					Table.log(typeof data[i][j]);
					// Loop Dim3
					for (var h = 0; h < data[i][j].length; h++) {
						//console.log('Here h');
						insertCell.call(this, data[i][j][h]);
					}
					h=0; // reset h
				}
				else {
					//console.log('Here j');
					insertCell.call(this, data[i][j]);
				}
			}
			j=0; // reset j
		}
		else {
			//console.log('Here i');
			insertCell.call(this, data[i]);
		}
	}
//
//	console.log('After insert');
//	console.log(this.db);

  };

  Table.prototype.addColumn = function (data, attributes, container) {
	if (!data) return false;
	return this._add(data, Table.V);
  };

  Table.prototype.addRow = function (data, attributes, container) {
		if (!data) return false;
		return this._add(data, Table.H);
	  };

  Table.prototype.getRoot = function() {
    return this.root;
  };

  // TODO: Only 2D for now
  Table.prototype.parse = function() {
	  var root = document.createElement('table');
	  if (this.size() ===  0) return root;

	  this.sort(['y','x']); // z to add first
	  var trid = -1;
	  // TODO: What happens if the are missing at the beginning ??
	  var f = this.first();
	  var old_x = f.x;
	  // TODO: Do we need old_y and old_z ?
	  var old_y = f.y;
	  var old_z = f.z;
	  console.log(this);
	  for (var i=0; i < this.db.length; i++) {
		  //if (this.db[i].x !==
		  if (trid !== this.db[i].y) {
			  var TR = document.createElement('tr');
			  root.appendChild(TR);
			  trid = this.db[i].y;
			  //console.log(trid);
			  old_x = f.x - 1; // must start exactly from the first
//			  old_y = f.y - 1;
//			  old_z = f.z - 1;
		  }

		  // Insert missing cells
		  if (this.db[i].x > old_x + 1) {
			  var diff = this.db[i].x - (old_x + 1);
			  for (var j=0; j < diff; j++ ) {
				  var TD = document.createElement('td');
				  TD.setAttribute('class', this.missing);
				  TR.appendChild(TD);
			  }
		  }
		  // Normal Insert
		  var TD = document.createElement('td');
		  var c = this.db[i].content;
		  var content = (!JSUS.isNode(c) || !JSUS.isElement(c)) ? document.createTextNode(c) : c;
		  TD.appendChild(content);
		  TR.appendChild(TD);

		  // Update old refs
		  old_x = this.db[i].x;
//		  old_y = this.db[i].y;
//		  old_z = this.db[i].z;
	  }

	  return root;
  }

  // Cell Class

  function Cell (cell){

	  this.x = ('undefined' !== typeof cell.x) ? cell.x : null;
	  this.y = ('undefined' !== typeof cell.y) ? cell.y : null;
	  this.z = ('undefined' !== typeof cell.z) ? cell.z : null;

	  this.content = ('undefined' !== typeof cell.content) ? cell.content : '';
	  this.style = ('undefined' !== typeof cell.style) ? cell.style : null;
  };

})(('undefined' !== typeof node) ? node : module.parent.exports);
<commit_msg>NDDB: creates new objects based on the constructor. New methods added by inheriting classes are copied as well<commit_after>(function(exports){

	/*!
	 *
	 * Table: abstract representation of an HTML table
	 *
	 */
	var node = exports;
	exports.Table = Table;

	// For simple testing
	module.exports = Table;

	var JSUS = node.JSUS;
	var NDDB = node.NDDB;

	Table.H = ['x','y','z'];
	Table.V = ['y','x', 'z'];

	Table.log = console.log;

  function Table (options, data) {
	var options = options || {};

	JSUS.extend(node.NDDB,this);
    node.NDDB.call(this, options, data);

    Table.log = options.log || Table.log;
    this.defaultDim1 = options.defaultDim1 || 'x';
    this.defaultDim2 = options.defaultDim2 || 'y';
    this.defaultDim3 = options.defaultDim3 || 'z';

    // Class for missing cells
    this.missing = options.missing || 'missing';
    this.pointers = {
    				x: options.pointerX || 0,
    				y: options.pointerY || 0,
    				z: options.pointerZ || 0
    };

    this.id = options.id || 'table';

//	if (options.root) {
//		this.setRoot(options.root);
//	}
//	else {
//		this.root = this.createRoot(this.id, options);
//	}
//
//	this.pointer = this.root; // Points to the last row added;
//	this.odd = 'odd';
  };

  Table.prototype.setRoot = function(root) {
	  if (!root) return false;
	  if (this.root && this.root.childNodes) {
		  root.appendChild(children);
	  }
	  this.root = root;
	  this.id = ('undefined' !== typeof root.id) ? root.id : this.id;
  };

  Table.prototype.append = function(root) {
    return root.appendChild(this.root);
  };

  Table.prototype.createRoot = function (id, options) {
    var root = document.createElement('table');
    root.id = id;
    return root;
  };

  Table.prototype.addHeaderRow = function (data, attributes) {
    var thead = document.createElement('thead');
    return this.addRow(data, attributes, thead);
  };

//  Table.prototype.addRow = function (data, attributes, container) {
//    var row = document.createElement('tr');
//
//    if (attributes) {
//    	node.window.addAttributes2Elem(row, attributes);
//    }
//
//    for (var i = 0; i < data.length; i++) {
//            var cell = document.createElement('td');
//            var cellContent = document.createTextNode(data[i]);
//            cell.appendChild(cellContent);
//            row.appendChild(cell);
//        }
//
//    // If we have other elements, e.g. thead, add them.
//    // If it is not a normal no even or odd class is added.
//    if (container) {
//      container.appendChild(row);
//      return this.appendRow(container, false);
//    }
//    else {
//      return this.appendRow(row);
//    }
//
//  };
//
  Table.prototype.appendRow = function (row, addClass) {
    var addClass = ('undefined' !== typeof addClass) ? addClass : true;
    this.root.appendChild(row);
    this.pointer = row;
    if (addClass) {
      row.className += this.id + '_' + this.odd;
      this.odd = (this.odd == 'odd') ? 'even' : 'odd'; // toggle pointer to odd or even row
    }
    return row;
  };

  Table._checkDim123 = function (dims) {
	  var t = Table.H.slice(0);
	  for (var i=0; i< dims.length; i++) {
		  if (!JSUS.removeElement(dims[i],t)) return false;
	  }
	  return true;
  };

  /**
   * Updates the reference to the foremost element in the table.
   *
   * @param
   */
  Table.prototype.updatePointer = function (pointer, value) {
	 if (!pointer) return false;
	 if (!JSUS.in_array(pointer, Table.H)) {
		 Table.log('Cannot update invalid pointer: ' + pointer, 'ERR');
		 return false;
	 }

	 if (value > this.pointers[pointer]) {
		 this.pointers[pointer] = value;
		 return true;
	 }

  };

  Table.prototype._add = function (data, dims, x, y, z) {
	if (!data) return false;
	if (dims) {
		if (!Table._checkDim123(dims)){
			Table.log('Invalid value for dimensions. Accepted only: x,y,z.')
			return false
		}
	}
	else {
		dims = Table.H;
	}

//	console.log('DATA TBL');
//	console.log(data);

	// By default, only the second dimension is incremented
	var x = x || this.pointers[dims[0]];
	var y = y || this.pointers[dims[1]] + 1;
	var z = z || this.pointers[dims[2]];

	if ('object' !== typeof data) data = [data];

	var insertCell = function (content){
		//console.log('content');
//		console.log(x + ' ' + y + ' ' + z);
//		console.log(i + ' ' + j + ' ' + h);

		var cell = {};
		cell[dims[0]] = i; // i always defined
		cell[dims[1]] = (j) ? y+j : y;
		cell[dims[2]] = (h) ? z+h : z;
		cell['content'] = content;
		//console.log(cell);
		this.insert(new Cell(cell));
		this.updatePointer(dims[0],cell[dims[0]]);
		this.updatePointer(dims[1],cell[dims[1]]);
		this.updatePointer(dims[2],cell[dims[2]]);
	};

	var cell = null;
	// Loop Dim1
	for (var i = 0; i < data.length; i++) {
		//console.log('data_i');
		//console.log(data[i]);
		if (data[i] instanceof Array) {
			// Loop Dim2
			for (var j = 0; j < data[i].length; j++) {
//				console.log(data[i]);
				if (data[i][j] instanceof Array) {
//					Table.log(data[i][j]);
//					Table.log(typeof data[i][j]);
					// Loop Dim3
					for (var h = 0; h < data[i][j].length; h++) {
						//console.log('Here h');
						insertCell.call(this, data[i][j][h]);
					}
					h=0; // reset h
				}
				else {
					//console.log('Here j');
					insertCell.call(this, data[i][j]);
				}
			}
			j=0; // reset j
		}
		else {
			//console.log('Here i');
			insertCell.call(this, data[i]);
		}
	}
//
//	console.log('After insert');
//	console.log(this.db);

  };

  Table.prototype.addColumn = function (data, attributes, container) {
	if (!data) return false;
	return this._add(data, Table.V);
  };

  Table.prototype.addRow = function (data, attributes, container) {
		if (!data) return false;
		return this._add(data, Table.H);
	  };

  Table.prototype.getRoot = function() {
    return this.root;
  };

  // TODO: Only 2D for now
  Table.prototype.parse = function() {
	  var root = document.createElement('table');
	  if (this.size() ===  0) return root;

	  this.sort(['y','x']); // z to add first
	  var trid = -1;
	  // TODO: What happens if the are missing at the beginning ??
	  var f = this.first();
	  var old_x = f.x;
	  // TODO: Do we need old_y and old_z ?
	  var old_y = f.y;
	  var old_z = f.z;
	  console.log(this);
	  for (var i=0; i < this.db.length; i++) {
		  //if (this.db[i].x !==
		  if (trid !== this.db[i].y) {
			  var TR = document.createElement('tr');
			  root.appendChild(TR);
			  trid = this.db[i].y;
			  //console.log(trid);
			  old_x = f.x - 1; // must start exactly from the first
//			  old_y = f.y - 1;
//			  old_z = f.z - 1;
		  }

		  // Insert missing cells
		  if (this.db[i].x > old_x + 1) {
			  var diff = this.db[i].x - (old_x + 1);
			  for (var j=0; j < diff; j++ ) {
				  var TD = document.createElement('td');
				  TD.setAttribute('class', this.missing);
				  TR.appendChild(TD);
			  }
		  }
		  // Normal Insert
		  var TD = document.createElement('td');
		  var c = this.db[i].content;
		  var content = (!JSUS.isNode(c) || !JSUS.isElement(c)) ? document.createTextNode(c) : c;
		  TD.appendChild(content);
		  TR.appendChild(TD);

		  // Update old refs
		  old_x = this.db[i].x;
//		  old_y = this.db[i].y;
//		  old_z = this.db[i].z;
	  }

	  return root;
  }

  // Cell Class

  function Cell (cell){

	  this.x = ('undefined' !== typeof cell.x) ? cell.x : null;
	  this.y = ('undefined' !== typeof cell.y) ? cell.y : null;
	  this.z = ('undefined' !== typeof cell.z) ? cell.z : null;

	  this.content = ('undefined' !== typeof cell.content) ? cell.content : '';
	  this.style = ('undefined' !== typeof cell.style) ? cell.style : null;
  };

})(('undefined' !== typeof node) ? node : module.parent.exports);
<|endoftext|>