<commit_before>'use strict';

var camera = require('./scene-camera'),
    glm = require('gl-matrix'),
    createAxes = require('gl-axes'),
    getAxesPixelRange = require('gl-axes/properties'),
    arrtools = require('arraytools'),
    createSelect = require('gl-select-static'),
    createSpikes = require('gl-spikes'),
    pixelLength = require('./compute-tick-length'),
    project = require('./project'),
    tinycolor = require('tinycolor2'),
    arrayCopy1D = arrtools.copy1D,
    arrayCopy2D = arrtools.copy2D,
    mat4 = glm.mat4,
    util = require('util'),
    EventEmitter = require('events').EventEmitter,
    proto;

function str2RgbaArray(color) {
    color = tinycolor(color);
    return arrtools.str2RgbaArray(color.toRgbString());
}

function ticksChanged (ticksA, ticksB) {
    var nticks;
    for (var i = 0; i < 3; ++i) {
        if (ticksA[i].length !== ticksB[i].length) return true;
        nticks = Math.min(ticksA[i].length, ticksB[i].length);
        if (nticks === 0) continue;
        for (var j = 0; j < nticks; j++) {
            if (ticksA[i][j].x !== ticksB[i][j].x ||
                ticksA[i][j].text !== ticksB[i][j].text) {
                return true;
            }
        }
    }

    return false;
}


// Scene Constructor
function Scene (options) {

    EventEmitter.call(this);

    this.Plotly                  = options.Plotly;
    this.container               = options.container || null;
    this.sceneKey                = options.sceneKey || 'scene';
    this.sceneData               = options.sceneData || null;
    this.sceneLayout             = options.sceneLayout || null;
    this.fullLayout              = options.fullLayout || null;
    this.glOptions               = options.glOptions;

    this.initialized             = false;  // needs to go through .init()
    this.setProps();

}

module.exports = Scene;

util.inherits(Scene, EventEmitter);

proto = Scene.prototype;

// Set Scene properties that are independent of 'options'
proto.setProps = function setProps() {

    this.renderQueue             = [];
    this.glDataMap               = {};
    this.sceneDataQueue          = [];

    this.dirty                   = true;  //Set if drawing buffer needs redraw
    this.selectDirty             = true;  //Set if selection buffer needs redraw
    this.moving                  = false; //Set if camera moving (don't draw select axes)


    this.selectBuffers           = [];
    this.pickRadius              = 10; //Number of pixels to search for closest point
    this.objectCount             = 0;

    this.baseRange               = [ [ Infinity,  Infinity,  Infinity],  // min (init opposite)
                                     [-Infinity, -Infinity, -Infinity] ];  // max (init opposite)

    this.range                   = [ [ 0, 0, 0],    // min (init opposite)
                                     [ 6, 6, 6] ];  // max (init opposite)

    ////////////// AXES OPTIONS DEFAULTS ////////////////
    this.axis                    = null;
    this.axesOpts                = {};

    this.axesOpts.bounds         = [ [-10, -10, -10],
                                     [ 10,  10,  10] ];

    this.axesOpts.ticks          = [ [], [], [] ];
    this.axesOpts.tickEnable     = [ true, true, true ];
    this.axesOpts.tickFont       = [ 'sans-serif', 'sans-serif', 'sans-serif' ];
    this.axesOpts.tickSize       = [ 12, 12, 12 ];
    this.axesOpts.tickAngle      = [ 0, 0, 0 ];
    this.axesOpts.tickColor      = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ];
    this.axesOpts.tickPad        = [ 18, 18, 18 ];

    this.axesOpts.labels         = [ 'x', 'y', 'z' ];
    this.axesOpts.labelEnable    = [ true, true, true ];
    this.axesOpts.labelFont      = ['Open Sans','Open Sans','Open Sans'];
    this.axesOpts.labelSize      = [ 20, 20, 20 ];
    this.axesOpts.labelAngle     = [ 0, 0, 0 ];
    this.axesOpts.labelColor     = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ];
    this.axesOpts.labelPad       = [ 30, 30, 30 ];

    this.axesOpts.lineEnable     = [ true, true, true ];
    this.axesOpts.lineMirror     = [ false, false, false ];
    this.axesOpts.lineWidth      = [ 1, 1, 1 ];
    this.axesOpts.lineColor      = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ];

    this.axesOpts.lineTickEnable = [ true, true, true ];
    this.axesOpts.lineTickMirror = [ false, false, false ];
    this.axesOpts.lineTickLength = [ 10, 10, 10 ];
    this.axesOpts.lineTickWidth  = [ 1, 1, 1 ];
    this.axesOpts.lineTickColor  = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ];

    this.axesOpts.gridEnable     = [ true, true, true ];
    this.axesOpts.gridWidth      = [ 1, 1, 1 ];
    this.axesOpts.gridColor      = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ];

    this.axesOpts.zeroEnable     = [ true, true, true ];
    this.axesOpts.zeroLineColor  = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ];
    this.axesOpts.zeroLineWidth  = [ 2, 2, 2 ];

    this.axesOpts.backgroundEnable = [ false, false, false ];
    this.axesOpts.backgroundColor  = [ [0.8, 0.8, 0.8, 0.5],
                                       [0.8, 0.8, 0.8, 0.5],
                                       [0.8, 0.8, 0.8, 0.5] ];

    // some default values are stored for applying model transforms
    this.axesOpts._defaultTickPad         = arrayCopy1D(this.axesOpts.tickPad);
    this.axesOpts._defaultLabelPad        = arrayCopy1D(this.axesOpts.labelPad);
    this.axesOpts._defaultLineTickLength  = arrayCopy1D(this.axesOpts.lineTickLength);

    ///////////////////////////////////////////

    this.axisSpikes      = null;
    this.spikeEnable     = true;
    this.spikeProperties = {
        enable:         [true, true, true],
        colors:         [[0,0,0,1],
                         [0,0,0,1],
                         [0,0,0,1]],
        sides:          [true, true, true],
        width:          [1,1,1]
    };

    this.axesNames       = ['xaxis', 'yaxis', 'zaxis'];

    this.model = new Float32Array([  // ?duplicate?
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1
    ]);

    this.defaultView = [   // set default camera view matrix
        1.25, 1.25, 1.25,
        0,    0,    0,
        0,    0,    1
    ];

    this.selection = null;  // currently selected data point

};


    shell.on('tick', this.onTick.bind(this));

    var self = this;
    shell.on('resize', function() {
        self.dirty = true;
        self.selectDirty = true;
    });

    // Bind on-load method to 'scene-loaded' event
    this.once('scene-loaded', this.onLoad.bind(this, sceneLayout));

    // Emit 'scene-loaded' event
    this.emit('scene-loaded', scene);
    return void 0;
}


};


<commit_msg>rewrite Scene (part 3):<commit_after>'use strict';

var camera = require('./scene-camera'),
    glm = require('gl-matrix'),
    createAxes = require('gl-axes'),
    getAxesPixelRange = require('gl-axes/properties'),
    arrtools = require('arraytools'),
    createSelect = require('gl-select-static'),
    createSpikes = require('gl-spikes'),
    pixelLength = require('./compute-tick-length'),
    project = require('./project'),
    tinycolor = require('tinycolor2'),
    arrayCopy1D = arrtools.copy1D,
    arrayCopy2D = arrtools.copy2D,
    mat4 = glm.mat4,
    util = require('util'),
    EventEmitter = require('events').EventEmitter,
    proto;

function str2RgbaArray(color) {
    color = tinycolor(color);
    return arrtools.str2RgbaArray(color.toRgbString());
}

function ticksChanged (ticksA, ticksB) {
    var nticks;
    for (var i = 0; i < 3; ++i) {
        if (ticksA[i].length !== ticksB[i].length) return true;
        nticks = Math.min(ticksA[i].length, ticksB[i].length);
        if (nticks === 0) continue;
        for (var j = 0; j < nticks; j++) {
            if (ticksA[i][j].x !== ticksB[i][j].x ||
                ticksA[i][j].text !== ticksB[i][j].text) {
                return true;
            }
        }
    }

    return false;
}


// Scene Constructor
function Scene (options) {

    EventEmitter.call(this);

    this.Plotly                  = options.Plotly;
    this.container               = options.container || null;
    this.sceneKey                = options.sceneKey || 'scene';
    this.sceneData               = options.sceneData || null;
    this.sceneLayout             = options.sceneLayout || null;
    this.fullLayout              = options.fullLayout || null;
    this.glOptions               = options.glOptions;

    this.initialized             = false;  // needs to go through .init()
    this.setProps();

}

module.exports = Scene;

util.inherits(Scene, EventEmitter);

proto = Scene.prototype;

// Set Scene properties that are independent of 'options'
proto.setProps = function setProps() {

    this.renderQueue             = [];
    this.glDataMap               = {};
    this.sceneDataQueue          = [];

    this.dirty                   = true;  //Set if drawing buffer needs redraw
    this.selectDirty             = true;  //Set if selection buffer needs redraw
    this.moving                  = false; //Set if camera moving (don't draw select axes)


    this.selectBuffers           = [];
    this.pickRadius              = 10; //Number of pixels to search for closest point
    this.objectCount             = 0;

    this.baseRange               = [ [ Infinity,  Infinity,  Infinity],  // min (init opposite)
                                     [-Infinity, -Infinity, -Infinity] ];  // max (init opposite)

    this.range                   = [ [ 0, 0, 0],    // min (init opposite)
                                     [ 6, 6, 6] ];  // max (init opposite)

    ////////////// AXES OPTIONS DEFAULTS ////////////////
    this.axis                    = null;
    this.axesOpts                = {};

    this.axesOpts.bounds         = [ [-10, -10, -10],
                                     [ 10,  10,  10] ];

    this.axesOpts.ticks          = [ [], [], [] ];
    this.axesOpts.tickEnable     = [ true, true, true ];
    this.axesOpts.tickFont       = [ 'sans-serif', 'sans-serif', 'sans-serif' ];
    this.axesOpts.tickSize       = [ 12, 12, 12 ];
    this.axesOpts.tickAngle      = [ 0, 0, 0 ];
    this.axesOpts.tickColor      = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ];
    this.axesOpts.tickPad        = [ 18, 18, 18 ];

    this.axesOpts.labels         = [ 'x', 'y', 'z' ];
    this.axesOpts.labelEnable    = [ true, true, true ];
    this.axesOpts.labelFont      = ['Open Sans','Open Sans','Open Sans'];
    this.axesOpts.labelSize      = [ 20, 20, 20 ];
    this.axesOpts.labelAngle     = [ 0, 0, 0 ];
    this.axesOpts.labelColor     = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ];
    this.axesOpts.labelPad       = [ 30, 30, 30 ];

    this.axesOpts.lineEnable     = [ true, true, true ];
    this.axesOpts.lineMirror     = [ false, false, false ];
    this.axesOpts.lineWidth      = [ 1, 1, 1 ];
    this.axesOpts.lineColor      = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ];

    this.axesOpts.lineTickEnable = [ true, true, true ];
    this.axesOpts.lineTickMirror = [ false, false, false ];
    this.axesOpts.lineTickLength = [ 10, 10, 10 ];
    this.axesOpts.lineTickWidth  = [ 1, 1, 1 ];
    this.axesOpts.lineTickColor  = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ];

    this.axesOpts.gridEnable     = [ true, true, true ];
    this.axesOpts.gridWidth      = [ 1, 1, 1 ];
    this.axesOpts.gridColor      = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ];

    this.axesOpts.zeroEnable     = [ true, true, true ];
    this.axesOpts.zeroLineColor  = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ];
    this.axesOpts.zeroLineWidth  = [ 2, 2, 2 ];

    this.axesOpts.backgroundEnable = [ false, false, false ];
    this.axesOpts.backgroundColor  = [ [0.8, 0.8, 0.8, 0.5],
                                       [0.8, 0.8, 0.8, 0.5],
                                       [0.8, 0.8, 0.8, 0.5] ];

    // some default values are stored for applying model transforms
    this.axesOpts._defaultTickPad         = arrayCopy1D(this.axesOpts.tickPad);
    this.axesOpts._defaultLabelPad        = arrayCopy1D(this.axesOpts.labelPad);
    this.axesOpts._defaultLineTickLength  = arrayCopy1D(this.axesOpts.lineTickLength);

    ///////////////////////////////////////////

    this.axisSpikes      = null;
    this.spikeEnable     = true;
    this.spikeProperties = {
        enable:         [true, true, true],
        colors:         [[0,0,0,1],
                         [0,0,0,1],
                         [0,0,0,1]],
        sides:          [true, true, true],
        width:          [1,1,1]
    };

    this.axesNames       = ['xaxis', 'yaxis', 'zaxis'];

    this.model = new Float32Array([  // ?duplicate?
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1
    ]);

    this.defaultView = [   // set default camera view matrix
        1.25, 1.25, 1.25,
        0,    0,    0,
        0,    0,    1
    ];

    this.selection = null;  // currently selected data point

};

// Takes care of all async stuff; needs to be call only once per scene
proto.init = function init() {

    this.intializing = true;  // keep track of initializing scene shell

    var container = this.container,
        glOptions = this.glOptions,
        self      = this;

    // Once scene is ready, plot!
    this.once('scene-ready', function () {
        self.plotDataQueue();
    });

    // Once iframe is loaded, init the shell!
    container.onload = function () {

        // Try initializing WebGl
        self.shell = container.contentWindow.glnow({
            clearFlags: 0,
            glOptions: glOptions,
            tickRate: 3
        });

        // contain all events within the iframe, necessary to
        // contain zoom events to prevent parent window scrolling.
        self.shell.preventDefaults = true;
        self.shell.stopPropagation = true;

        // Once gl is initialized, initialize the camera and let
        // Scene know about it with 'scene-ready'.
        self.shell.once('gl-init', function () {
            self.initCamera();
            self.emit('scene-ready', self);
            self.initializing = false;
            self.initialized = true;
        });

        /*
         * gl-render is triggered in the animation loop, we hook in
         * glcontext object into the loop here
         */
        self.shell.on('gl-render', self.onRender.bind(self));

        // Attached 'tick' and 'resize' events to shell
        self.shell.on('tick', self.onTick.bind(self));
        self.shell.on('resize', function() {
            self.dirty = true;
            self.selectDirty = true;
        });

        // If an error occur, clean up container.
        self.shell.on('gl-error', function () {

            self.container.style.background = '#FFFFFF';
            self.container.contentDocument.getElementById('no3D').style.display = 'block';
            self.container.contentDocument.body.onclick = function () {
                window.open("http://get.webgl.org")
            };

            // Clean up modebar, add flag in fullLayout (for graph_interact.js)
            var fullLayout = self.fullLayout;
            if ('_modebar' in fullLayout && fullLayout._modebar) {
                fullLayout._modebar.cleanup();
                fullLayout._modebar = null;
            }
            fullLayout._noGL3DSupport = true;

//             // Old code to remove the loading bars
//             // commented out as Scene does not have 'gd'
//             var pb = gd.querySelector('#plotlybars'); // !!!
//             if (pb) {
//                 pb.innerHTML = '';
//                 pb.parentNode.removeChild(pb);
//             }
        });

    };

};


};



{'fraction_non_alphanumeric': 0.15527990230734623, 'fraction_numerical': 0.029821967992801592, 'mean_word_length': 1.7627840909090908, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4459963', 'n_tokens_mistral': 5299, 'n_tokens_neox': 4939, 'n_words': 1072}