<commit_before>
var Protos = require('protos');

Protos.bootstrap(__dirname, {

  // Server configuration

  server: {
    host: 'localhost',
    port: 8080,
    multiProcess: false,
    stayUp: 'production'
  },

  // Application environments

  environments: {

    // Default Environment
    default: 'development',

    development: function(app) {

      // Debug messages on development
      app.debugLog = false;

      // Development Logging
      app.use('logger', {
        accessLog: true,
        accessLogFormat: 'default',
        accessLogConsole: true,
        infoLevel: {console: true},
        errorLevel: {console: true}
      });

    },

    production: function(app) {

      // Debug messages on production
      app.debugLog = false;

      // Production Logging
      app.use('logger', {
        accessLog: true,
        accessLogFormat: 'default',
        accessLogConsole: false,
        infoLevel: {file: 'info.log'},
        errorLevel: {file: 'error.log'}
      });

    }
  },

  // Application events

  events: {

    init: function(app) {

      // Markdown processing
      app.use('markdown', {
        flags: {
          content: ['autolink', 'extraFootnote'],
          untrusted: ['noHTML', 'noTables', 'strict']
        },
        sanitize: ['untrusted']
      });

      // Shortcodes
      app.use('shortcode');

      // Static file server
      app.use('static_server');

      // Asset compiler
      if (app.environment === 'production') {
        // Serve minified assets on production
        app.use('asset_compiler', {
          minify: {
            'css/client.min.css': ['css/blueprint.css', 'css/print.less', 'css/main.less'],
            'js/client.min.js': 'js/client.js'
          }
        });
      } else {
        // Compile & Watch on development/debug
        app.use('asset_compiler');
      }

      // Optimize performance by caching responses in storage
      app.use('response_cache', {
        storage: 'redis:response_cache'
      });

      // Load lib extensions
      app.libExtensions();
    }

  }

});

module.exports = protos.app;
<commit_msg>Added Worker pid header<commit_after>
var crypto = require('crypto');
var Protos = require('protos');

Protos.bootstrap(__dirname, {

  // Server configuration

  server: {
    host: 'localhost',
    port: 8080,
    multiProcess: false,
    stayUp: 'production'
  },

  // Application environments

  environments: {

    // Default Environment
    default: 'development',

    development: function(app) {

      // Debug messages on development
      app.debugLog = false;

      // Development Logging
      app.use('logger', {
        accessLog: true,
        accessLogFormat: 'default',
        accessLogConsole: true,
        infoLevel: {console: true},
        errorLevel: {console: true}
      });

    },

    production: function(app) {

      // Debug messages on production
      app.debugLog = false;

      // Production Logging
      app.use('logger', {
        accessLog: true,
        accessLogFormat: 'default',
        accessLogConsole: false,
        infoLevel: {file: 'info.log'},
        errorLevel: {file: 'error.log'}
      });

    }
  },

  // Application events

  events: {

    init: function(app) {

      // Markdown processing
      app.use('markdown', {
        flags: {
          content: ['autolink', 'extraFootnote'],
          untrusted: ['noHTML', 'noTables', 'strict']
        },
        sanitize: ['untrusted']
      });

      // Shortcodes
      app.use('shortcode');

      // Static file server
      app.use('static_server');

      // Asset compiler
      if (app.environment === 'production') {
        // Serve minified assets on production
        app.use('asset_compiler', {
          minify: {
            'css/client.min.css': ['css/blueprint.css', 'css/print.less', 'css/main.less'],
            'js/client.min.js': 'js/client.js'
          }
        });
      } else {
        // Compile & Watch on development/debug
        app.use('asset_compiler');
      }

      // Optimize performance by caching responses in storage
      app.use('response_cache', {
        storage: 'redis:response_cache'
      });

      // Display worker pid
      var pid = crypto.createHash('md5').update(process.pid+'').digest('hex').slice(-5);
      app.config.headers['X-Worker-Pid'] = function() { return pid; }

      // Load lib extensions
      app.libExtensions();
    }

  }

});

module.exports = protos.app;
<|endoftext|>


<commit_before>var FileList = require('enb/lib/file-list'),
    vow = require('vow'),
    path = require('path'),
    fs = require('fs');

/**
 * Plain scheme for level.
 *
 * @namespace level-plain
 * @see {@link Level}
 */
module.exports = {
    buildLevel: function (levelPath, levelBuilder) {
        return vow.when(addPlainFiles(levelPath, levelBuilder)).then(function () {
            levelBuilder.build();
        });
    },

    buildFilePath: function (levelPath, blockName, elemName, modName, modVal) {
        return path.join(levelPath, blockName) +
            (elemName ? '__' + elemName : '') +
            (modName ? '_' + modName : '') +
            (modVal ? '_' + modVal : '');
    }
};

function addPlainFiles(directory, levelBuilder) {
    filterFiles(fs.readdirSync(directory)).forEach(function (filename) {
        var fullname = path.join(directory, filename),
            stat = fs.statSync(fullname),
            bem;
        if (stat.isDirectory()) {
            if (filename.indexOf('.') !== -1) {
                bem = FileList.parseFilename(filename).bem;
                levelBuilder.addFile(fullname, bem.block, bem.elem, bem.modName, bem.modVal);
            } else {
                addPlainFiles(fullname, levelBuilder);
            }
        } else {
            bem = FileList.parseFilename(filename).bem;
            levelBuilder.addFile(fullname, bem.block, bem.elem, bem.modName, bem.modVal);
        }
    });
}

function filterFiles(filenames) {
    return filenames.filter(function (filename) {
        return filename.charAt(0) !== '.';
    });
}
<commit_msg>levels-plain@v2: FileList.parseFilename call removed (closes #248)<commit_after>var bemNaming = require('bem-naming'),
    vow = require('vow'),
    path = require('path'),
    fs = require('fs');

/**
 * Plain scheme for level.
 *
 * @namespace level-plain
 * @see {@link Level}
 */
module.exports = {
    buildLevel: function (levelPath, levelBuilder) {
        return vow.when(addPlainFiles(levelPath, levelBuilder)).then(function () {
            levelBuilder.build();
        });
    },

    buildFilePath: function (levelPath, blockName, elemName, modName, modVal) {
        return path.join(levelPath, blockName) +
            (elemName ? '__' + elemName : '') +
            (modName ? '_' + modName : '') +
            (modVal ? '_' + modVal : '');
    }
};

function addPlainFiles(directory, levelBuilder) {
    filterFiles(fs.readdirSync(directory)).forEach(function (filename) {
        var fullname = path.join(directory, filename),
            stat = fs.statSync(fullname),
            bem;
        if (stat.isDirectory()) {
            if (filename.indexOf('.') !== -1) {
                bem = parseFilename(filename);
                levelBuilder.addFile(fullname, bem.block, bem.elem, bem.modName, bem.modVal);
            } else {
                addPlainFiles(fullname, levelBuilder);
            }
        } else {
            bem = parseFilename(filename);
            levelBuilder.addFile(fullname, bem.block, bem.elem, bem.modName, bem.modVal);
        }
    });
}

function filterFiles(filenames) {
    return filenames.filter(function (filename) {
        return filename.charAt(0) !== '.';
    });
}

function parseFilename(filename) {
    return bemNaming.parse(filename.split('.')[0]);
}
<|endoftext|>


<commit_before>var home = exports;

home.weld = function(data, dom) {

  // perform weld

  return dom;

};

home.generate = function(data, dom) {

  // write toc to file system

};

home.load = function(data, dom) {
  return {};
};<commit_msg>[api]: Home page now dumps all articles<commit_after>var docs = require('../docs');

var home = exports;

var fs = require('fs');

home.weld = function(data, dom) {

  // perform weld

  return dom;

};

home.generate = function(output) {
  // write home to file system
  //output = docs.helpers.filesToTree(output);
  fs.writeFileSync('./public/index.html', JSON.stringify(output, true, 2));
};

home.load = function(data, dom) {
  return docs.content.article;
};<|endoftext|>


<commit_before><commit_msg>Adding nb of cards to the list<commit_after><|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import ClassNames from 'classnames/bind';
import style from './button.css';

/**
 * Component Descriptions
 */
const Button = ({className, outline, href, loading, primary, secondary, success, warning, danger, link, large, small, block, disabled, children, ...others}) => {

    const element = href ? 'a' : 'button';
    const cx = ClassNames.bind(style);
    let classNames = cx({
        large,
        small,
        block,
        disabled,
        className
    });

    if (outline) {
      classNames += ' ' + cx({
        primary_outline: !secondary && !success && !warning && !danger && !link,
        secondary,
        success_outline: success,
        warning_outline: warning,
        danger_outline: danger,
        link_outline: link
      });
    } else {
      classNames += ' ' + cx({
        primary: !secondary && !success && !warning && !danger && !link,
        secondary,
        success,
        warning,
        danger,
        link
      });
    }

    let role;
    if (element === 'a') {
      role = 'button';
    }
    const props = {
      ...others,
      href,
      className: classNames,
      disabled: disabled || loading,
      role
    };

    return React.createElement(element, props,
      children
    );

};

Button.styleguide = {
  index: '1.1',
  category: 'Buttons'
};

Button.propTypes = {
  children: PropTypes.node,
    /**
     * define a custom css class name
     * @examples "btn", "btn-active"
     */
  className: PropTypes.string,
  disabled: PropTypes.bool,
  outline: PropTypes.bool,
  href: PropTypes.string,
  loading: PropTypes.bool,
  primary: PropTypes.bool,
  type: PropTypes.string,
  secondary: PropTypes.bool,
  success: PropTypes.bool,
  warning: PropTypes.bool,
  danger: PropTypes.bool,
  link: PropTypes.bool,
  large: PropTypes.bool,
  small: PropTypes.bool,
  block: PropTypes.bool
};

Button.defaultProps = {
  className: '',
  outline: false,
  loading: false,
  mini: false,
  primary: false,
  secondary: false,
  success: false,
  warning: false,
  danger: false,
  link: false,
  raised: false,
  large: false,
  small: false,
  disabled: false
};

export default Button;
<commit_msg>Button example kitchen-sink<commit_after>import React, { PropTypes } from 'react';
import ClassNames from 'classnames/bind';
import style from './button.css';

/**
 * A Generic button component.
 */
const Button = ({className, outline, href, loading, primary, secondary, success, warning, danger, link, large, small, block, disabled, children, ...others}) => {

    const element = href ? 'a' : 'button';
    const cx = ClassNames.bind(style);
    let classNames = cx({
        large,
        small,
        block,
        disabled,
        className
    });

    if (outline) {
      classNames += ' ' + cx({
        primary_outline: !secondary && !success && !warning && !danger && !link,
        secondary,
        success_outline: success,
        warning_outline: warning,
        danger_outline: danger,
        link_outline: link
      });
    } else {
      classNames += ' ' + cx({
        primary: !secondary && !success && !warning && !danger && !link,
        secondary,
        success,
        warning,
        danger,
        link
      });
    }

    let role;
    if (element === 'a') {
      role = 'button';
    }
    const props = {
      ...others,
      href,
      className: classNames,
      disabled: disabled || loading,
      role
    };

    return React.createElement(element, props,
      children
    );

};

Button.styleguide = {
  index: '1.1',
  category: 'Buttons',
  example: `

Regular Buttons

    <Button>Button</Button>
    <Button secondary>Secondary</Button>
    <Button success>Success</Button>
    <Button warning>Warning</Button>
    <Button danger>Danger</Button>
    <Button href="#" link>Link</Button>

Disabled Regular Buttons

    <Button disabled primary>Button</Button>
    <Button disabled secondary>Secondary</Button>
    <Button disabled success>Success</Button>
    <Button disabled warning>Warning</Button>
    <Button disabled danger>Danger</Button>
    <Button href="#" disabled link>Link</Button>

Outline Buttons

    <Button outline primary>Button</Button>
    <Button outline secondary>Secondary</Button>
    <Button success outline>Success</Button>
    <Button warning outline>Warning</Button>
    <Button danger outline>Danger</Button>
    <Button href="#" link outline>Link</Button>

Disabled Outline Buttons

    <Button disabled outline primary>Button</Button>
    <Button disabled secondary outline>Secondary</Button>
    <Button disabled success outline>Success</Button>
    <Button disabled warning outline>Warning</Button>
    <Button disabled danger outline>Danger</Button>
    <Button href="#" disabled link outline>Link</Button>

Large Buttons

    <Button large>Button</Button>
    <Button large secondary>Secondary</Button>

Small Buttons

    <Button small primary>Button</Button>
    <Button small secondary>Secondary</Button>

Block Level Buttons

    <Button block>Button</Button>
    <Button block secondary>Secondary</Button>

  `
};

Button.propTypes = {
    /**
     * Anything that can be in a button. Usually text, but could also be icons/glyphs.
     * @examples 'Save', 'Cancel'
     */
  children: PropTypes.node,
    /**
     * define a custom css class name
     * @examples "btn", "btn-active"
     */
  className: PropTypes.string,
    /**
     * define a custom css class name
     * @examples "btn", "btn-active"
     */
  disabled: PropTypes.bool,
    /**
     * use outline styled button
     * @examples <Button outline>
     */
  outline: PropTypes.bool,
    /**
     * define button href if anchor
     * @examples '#', 'http://some-website.com/'
     */
  href: PropTypes.string,
    /**
     * set loading animation on button
     * @examples <Button loading>
     */
  loading: PropTypes.bool,
    /**
     * use primary style button (button is set to this by default)
     * @examples <Button primary>
     */
  primary: PropTypes.bool,
  type: PropTypes.string,
    /**
     * use secondary style button
     * @examples <Button secondary>
     */
  secondary: PropTypes.bool,
    /**
     * use success style button
     * @examples <Button success>
     */
  success: PropTypes.bool,
    /**
     * use warning style button
     * @examples <Button warning>
     */
  warning: PropTypes.bool,
    /**
     * use danger style button
     * @examples <Button danger>
     */
  danger: PropTypes.bool,
    /**
     * use link style button
     * @examples <Button link>
     */
  link: PropTypes.bool,
    /**
     * use large style button
     * @examples <Button large>
     */
  large: PropTypes.bool,
    /**
     * use small style button
     * @examples <Button small>
     */
  small: PropTypes.bool,
    /**
     * use block style button
     * @examples <Button block>
     */
  block: PropTypes.bool
};

Button.defaultProps = {
  children: "Default Button",
  className: '',
  outline: false,
  loading: false,
  mini: false,
  primary: false,
  secondary: false,
  success: false,
  warning: false,
  danger: false,
  link: false,
  raised: false,
  large: false,
  small: false,
  disabled: false
};

export default Button;
<|endoftext|>


<commit_before>// create table view data object
var data = [];

for (var x=0;x<4;x++)
{
	var label = Ti.UI.createLabel({
		text:'Row Label ' + x,
		height:'auto',
		width:'auto',
		color:'#336699',
		left:10
	});
	var row = Ti.UI.createTableViewRow({height:50});
	row.add(label);
	data.push(row);
}

// create table view
var tableview = Titanium.UI.createTableView({
	data:data,
});

tableview.addEventListener('touchstart', function(e)
{
	e.row.children[0].color = '#fff';
});

tableview.addEventListener('touchend', function(e)
{
	e.row.children[0].color = '#336699';
});

// add table view to the window
Titanium.UI.currentWindow.add(tableview);
<commit_msg>Workaround example for table touch events.<commit_after>// create table view data object
var data = [];

for (var x=0;x<4;x++)
{
	var view = Ti.UI.createView();
	var label = Ti.UI.createLabel({
		text:'Row Label ' + x,
		height:'auto',
		width:'auto',
		color:'#336699',
		left:10
	});
	var row = Ti.UI.createTableViewRow({height:50});
	view.add(label);
	row.add(view);
	data.push(row);
}

// create table view
var tableview = Titanium.UI.createTableView({
	data:data,
});

tableview.addEventListener('touchstart', function(e)
{
	e.row.children[0].children[0].color = '#fff';
});

tableview.addEventListener('touchend', function(e)
{
	e.row.children[0].children[0].color = '#336699';
});

// add table view to the window
Titanium.UI.currentWindow.add(tableview);
<|endoftext|>


<commit_before>[
{"id":"layer_new","title":"Nueva capa"},
{"id":"layer_delete","title":"Suprimir capa"},
{"id":"layer_rename","title":"Renombrar capa"},
{"id":"layer_up","title":"Mover la capa hacia arriba"},
{"id":"layer_down","title":"Mover la capa hacia abajo"},
{"id":"tool_clear","title":"Nueva imagen"},
{"id":"tool_open","title":"Abrir imagen"},
{"id":"tool_save","title":"Guardar imagen"},
{"id":"tool_docprops","title":"Propiedades del documento"},
{"id":"tool_source","title":"Editar código fuente"},
{"id":"tool_undo","title":"Deshacer"},
{"id":"tool_redo","title":"Rehacer"},
{"id":"tool_clone","title":"Clonar elemento"},
{"id":"tool_delete","title":"Suprimir elemento"},
{"id":"tool_move_top","title":"Mover arriba"},
{"id":"tool_move_bottom","title":"Mover abajo"},
{"id":"group_opacity","title":"Cambiar la opacidad de elemento seleccionado"},
{"id":"angle","title":"Cambiar el ángulo de rotación"},
{"id":"tool_clone_multi","title":" Clonar elementos"},
{"id":"tool_delete_multi","title":"Suprimir los elementos seleccionados"},
{"id":"tool_alignleft","title":"Alinear lado izquierdo"},
{"id":"tool_aligncenter","title":"Centrar verticalmente"},
{"id":"tool_alignright","title":"Alinear lado derecho"},
{"id":"tool_aligntop","title":"Alinear parte superior"},
{"id":"tool_alignmiddle","title":"Centrar horizontalmente"},
{"id":"tool_alignbottom","title":"Alinear parte inferior"},
{"id":"align_relative_to","title":"Alinear con respecto a ..."},
{"id":"tool_group","title":"Agrupar elementos"},
{"id":"tool_ungroup","title":"Desagrupar elementos"},
{"id":"rect_width","title":"Cambiar el ancho rectángulo"},
{"id":"rect_height","title":"Cambiar la altura del rectágulo"},
{"id":"rect_rx","title":"Cambiar el radio de las esquinas del rectángulo"},
{"id":"image_width","title":"Cambiar el ancho de la imagen"},
{"id":"image_height","title":"Cambiar la altura de la imagen"},
{"id":"image_url","title":"Modificar URL"},
{"id":"circle_cx","title":"Cambiar la posición horizonral cx del círculo"},
{"id":"circle_cy","title":"Cambiar la posición vertical cy del círculo"},
{"id":"circle_r","title":"Cambiar el radio del círculo"},
{"id":"ellipse_cx","title":"Cambiar la posición horizontal cx de la elipse"},
{"id":"ellipse_cy","title":"Cambiar la posición vertical cy de la elipse"},
{"id":"ellipse_rx","title":"Cambiar el radio horizontal X de la elipse"},
{"id":"ellipse_ry","title":"Cambiar el radio vertical Y de la elipse"},
{"id":"line_x1","title":"Cambiar la posición horizontal X del comienzo de la línea"},
{"id":"line_y1","title":"Cambiar la posición vertical Y del comienzo de la línea"},
{"id":"line_x2","title":"Cambiar la posición horizontal X del final de la línea"},
{"id":"line_y2","title":"Cambiar la poición vertical Y del final de la línea"},
{"id":"tool_bold","title":"Texto en negrita"},
{"id":"tool_italic","title":"Texto en cursiva"},
{"id":"font_family","title":"Tipo de fuente"},
{"id":"font_size","title":"Tamaño de la fuente"},
{"id":"text","title":"Modificar el texto"},
{"id":"tool_select","title":"Herramienta de selección"},
{"id":"tool_fhpath","title":"Herramienta de lápiz"},
{"id":"tool_line","title":"Trazado de líneas"},
{"id":"tools_rect_show","title":"Cuadrado / Rectángulo"},
{"id":"tools_ellipse_show","title":"Círculo / Elipse"},
{"id":"tool_text","title":"Insertar texto"},
{"id":"tool_path","title":"Polígono"},
{"id":"tool_image","title":"Insertar imagen"},
{"id":"tool_zoom","title":"Zoom"},
{"id":"zoom","title":"Cambiar el nivel de zoom"},
{"id":"fill_color","title":"Cambiar el color de relleno"},
{"id":"stroke_color","title":"Cambiar el color del contorno"},
{"id":"stroke_width","title":"Cambiar el ancho del contorno"},
{"id":"stroke_style","title":"Cambiar el estilo del trazo del contorno"},
{"id":"palette","title":"Haga clic para cambiar el color de relleno. Pulse Mayús y haga clic para cambiar el color del contorno."},
{"id":"tool_square","title":"Cuadrado"},
{"id":"tool_rect","title":"Rectángulo"},
{"id":"tool_fhrect","title":"Rectángulo a mano alzada"},
{"id":"tool_circle","title":"Círculo"},
{"id":"tool_ellipse","title":"Elipse"},
{"id":"tool_fhellipse","title":"Elipse a mano alzada"},
{"id":"bkgnd_color","title":"Cambiar color de fondo / opacidad"},
{"id":"rwidthLabel","textContent":"Ancho:"},
{"id":"rheightLabel","textContent":"Alto:"},
{"id":"cornerRadiusLabel","textContent":"Radio de la esquina:"},
{"id":"iwidthLabel","textContent":"ancho:"},
{"id":"iheightLabel","textContent":"alto:"},
{"id":"svginfo_width","textContent":"Ancho:"},
{"id":"svginfo_height","textContent":"Alto:"},
{"id":"angleLabel","textContent":"ángulo:"},
{"id":"relativeToLabel","textContent":"en relación con:"},
{"id":"zoomLabel","textContent":"Zoom:"},
{"id":"layersLabel","textContent":"Capas:"},
{"id":"selectedPredefined","textContent":"Seleccionar predefinido:"},
{"id":"fitToContent","textContent":"Ajustar al contenido"},
{"id":"tool_source_save","textContent":"Aplicar cambios"},
{"id":"tool_docprops_save","textContent":"Aceptar"},
{"id":"tool_docprops_cancel","textContent":"Cancelar"},
{"id":"tool_source_cancel","textContent":"Cancelar"},
{"id":"fit_to_all","textContent":"Ajustar a todo el contenido"},
{"id":"fit_to_layer_content","textContent":"Ajustar al contenido de la capa"},
{"id":"fit_to_sel","textContent":"Ajustar a la selección"},
{"id":"fit_to_canvas","textContent":"Ajustar al lienzo"},
{"id":"selected_objects","textContent":"Objetos seleccionados"},
{"id":"largest_object","textContent":"El objeto más grande"},
{"id":"smallest_object","textContent":"El objeto más pequeño"},
{"id":"page","textContent":"Página"},
{"id":"fill_tool_bottom","textContent":"Relleno:"},
{"id":"stroke_tool_bottom","textContent":"Contorno:"},
{"id":"svninfo_dim","textContent":"Dimensiones del lienzo"},
{"id":"path_node_x","title":"Cambiar la posición horizontal X del nodo"},
{"id":"path_node_y","title":"Cambiar la posición vertical Y del nodo"},
{"id":"seg_type","title":"Cambiar el tipo de segmento"},
{"id":"straight_segments","textContent":"Recto"},
{"id":"curve_segments","textContent":"Curvo"},
{"id":"tool_node_clone","title":"Clonar nodo"},
{"id":"tool_node_delete","title":"Suprimir nodo"},
{"id":"selLayerLabel","textContent":"Desplazar elementos hacia:"},
{"id":"selLayerNames","title":"Mover los elementos seleccionados a otra capa"},
{"id":"sidepanel_handle","title":"Arrastrar hacia la izquierda/derecha para modificar el tamaño del panel lateral","textContent":"C a p a s"},
{"id":"tool_wireframe","title":"Modo wireframe"},
{"id":"svginfo_image_props","textContent":"Propiedades de Imagen"},
{"id":"svginfo_title","textContent":"Título"},
{"id":"svginfo_dim","textContent":"Tamaño del lienzo"},
{"id":"includedImages","textContent":"Imágenes integradas"},
{"id":"image_opt_embed","textContent":"Integrar imágenes en forma de datos (archivos locales)"},
{"id":"image_opt_ref","textContent":"Usar la referencia del archivo"},
{"id":"svginfo_editor_prefs","textContent":"Preferencias del Editor"},
{"id":"svginfo_lang","textContent":"Idioma"},
{"id":"svginfo_change_background","textContent":"Fondo del editor"},
{"id":"svginfo_bg_note","textContent":"Nota: El fondo no se guardará junto con la imagen."},
{"id":"svginfo_icons","textContent":"Tamaño de los iconos"},
{"id":"icon_small","textContent":"Pequeño"},
{"id":"icon_medium","textContent":"Mediano"},
{"id":"icon_large","textContent":"Grande"},
{"id":"icon_xlarge","textContent":"Muy grande"},
{"id":"selected_x","title":"Cambiar la posición horizontal X"},
{"id":"selected_y","title":"Cambiar la posición vertical Y"},
{"id":"tool_topath","title":"Convertir en ruta"},
{"id":"tool_reorient","title":"Reorientar la ruta"},
{"id":"tool_node_link","title":"Enlazar puntos de control"},
{"js_strings": {
	"invalidAttrValGiven":"Valor no válido",
	"noContentToFitTo":"No existe un contenido al que ajustarse.",
	'layer':"Capa",
	"dupeLayerName":"¡Ya existe una capa con este nombre!",
	"enterUniqueLayerName":"Introduzca otro nombre distinto para la capa.",
	"enterNewLayerName":"Introduzca el nuevo nombre de la capa.",
	"layerHasThatName":"El nombre introducido es el nombre actual de la capa.",
	"QmoveElemsToLayer":"¿Desplazar los elementos seleccionados a la capa '%s'?",
	"QwantToClear":"¿Desea suprimir el dibujo?\n¡El historial de acciones también se borrará!",
	"QerrorsRevertToSource":"Existen errores sintácticos en su código fuente SVG.\n¿Desea volver al código fuente SVG original?",
	"QignoreSourceChanges":"¿Desea ignorar los cambios realizados sobre el código fuente SVG?",
	"featNotSupported":"Función no compatible.",
	"enterNewImgURL":"Introduzca la nueva URL de la imagen.",
	"Aceptar":"Aceptar",
	"cancel":"Cancelar",
	"pathNodeTooltip":"Arrastre el nodo para desplazarlo. Haga doble clic sobre el nodo para cambiar el tipo de segmento.",
	"pathCtrlPtTooltip":"Arrastre el punto de control para ajustar las propiedades de la curva.",
	"key_up":"arriba",
	"key_down":"abajo",
	"key_backspace":"retroceso",
	"key_del":"suprimir"
	}
}
]<commit_msg>Update the Spanish language file by Alicia.<commit_after>[
{"id":"layer_new","title":"Nueva capa"},
{"id":"layer_delete","title":"Suprimir capa"},
{"id":"layer_rename","title":"Renombrar capa"},
{"id":"layer_up","title":"Mover la capa hacia arriba"},
{"id":"layer_down","title":"Mover la capa hacia abajo"},
{"id":"tool_clear","title":"Nueva imagen"},
{"id":"tool_open","title":"Abrir imagen"},
{"id":"tool_save","title":"Guardar imagen"},
{"id":"tool_docprops","title":"Propiedades del documento"},
{"id":"tool_source","title":"Editar código fuente"},
{"id":"tool_undo","title":"Deshacer"},
{"id":"tool_redo","title":"Rehacer"},
{"id":"tool_clone","title":"Clonar elemento"},
{"id":"tool_delete","title":"Suprimir elemento"},
{"id":"tool_move_top","title":"Mover arriba"},
{"id":"tool_move_bottom","title":"Mover abajo"},
{"id":"group_opacity","title":"Cambiar la opacidad de elemento seleccionado"},
{"id":"angle","title":"Cambiar el ángulo de rotación"},
{"id":"tool_clone_multi","title":" Clonar elementos"},
{"id":"tool_delete_multi","title":"Suprimir los elementos seleccionados"},
{"id":"tool_alignleft","title":"Alinear lado izquierdo"},
{"id":"tool_aligncenter","title":"Centrar verticalmente"},
{"id":"tool_alignright","title":"Alinear lado derecho"},
{"id":"tool_aligntop","title":"Alinear parte superior"},
{"id":"tool_alignmiddle","title":"Centrar horizontalmente"},
{"id":"tool_alignbottom","title":"Alinear parte inferior"},
{"id":"align_relative_to","title":"Alinear con respecto a ..."},
{"id":"tool_group","title":"Agrupar elementos"},
{"id":"tool_ungroup","title":"Desagrupar elementos"},
{"id":"rect_width","title":"Cambiar el ancho rectángulo"},
{"id":"rect_height","title":"Cambiar la altura del rectágulo"},
{"id":"rect_rx","title":"Cambiar el radio de las esquinas del rectángulo"},
{"id":"image_width","title":"Cambiar el ancho de la imagen"},
{"id":"image_height","title":"Cambiar la altura de la imagen"},
{"id":"image_url","title":"Modificar URL"},
{"id":"circle_cx","title":"Cambiar la posición horizonral cx del círculo"},
{"id":"circle_cy","title":"Cambiar la posición vertical cy del círculo"},
{"id":"circle_r","title":"Cambiar el radio del círculo"},
{"id":"ellipse_cx","title":"Cambiar la posición horizontal cx de la elipse"},
{"id":"ellipse_cy","title":"Cambiar la posición vertical cy de la elipse"},
{"id":"ellipse_rx","title":"Cambiar el radio horizontal X de la elipse"},
{"id":"ellipse_ry","title":"Cambiar el radio vertical Y de la elipse"},
{"id":"line_x1","title":"Cambiar la posición horizontal X del comienzo de la línea"},
{"id":"line_y1","title":"Cambiar la posición vertical Y del comienzo de la línea"},
{"id":"line_x2","title":"Cambiar la posición horizontal X del final de la línea"},
{"id":"line_y2","title":"Cambiar la poición vertical Y del final de la línea"},
{"id":"tool_bold","title":"Texto en negrita"},
{"id":"tool_italic","title":"Texto en cursiva"},
{"id":"font_family","title":"Tipo de fuente"},
{"id":"font_size","title":"Tamaño de la fuente"},
{"id":"text","title":"Modificar el texto"},
{"id":"tool_select","title":"Herramienta de selección"},
{"id":"tool_fhpath","title":"Herramienta de lápiz"},
{"id":"tool_line","title":"Trazado de líneas"},
{"id":"tools_rect_show","title":"Cuadrado / Rectángulo"},
{"id":"tools_ellipse_show","title":"Círculo / Elipse"},
{"id":"tool_text","title":"Insertar texto"},
{"id":"tool_path","title":"Herramienta de trazado"},
{"id":"tool_image","title":"Insertar imagen"},
{"id":"tool_zoom","title":"Zoom"},
{"id":"zoom","title":"Cambiar el nivel de zoom"},
{"id":"fill_color","title":"Cambiar el color de relleno"},
{"id":"stroke_color","title":"Cambiar el color del contorno"},
{"id":"stroke_width","title":"Cambiar el ancho del contorno"},
{"id":"stroke_style","title":"Cambiar el estilo del trazo del contorno"},
{"id":"palette","title":"Haga clic para cambiar el color de relleno. Pulse Mayús y haga clic para cambiar el color del contorno."},
{"id":"tool_square","title":"Cuadrado"},
{"id":"tool_rect","title":"Rectángulo"},
{"id":"tool_fhrect","title":"Rectángulo a mano alzada"},
{"id":"tool_circle","title":"Círculo"},
{"id":"tool_ellipse","title":"Elipse"},
{"id":"tool_fhellipse","title":"Elipse a mano alzada"},
{"id":"bkgnd_color","title":"Cambiar color de fondo / opacidad"},
{"id":"rwidthLabel","textContent":"Ancho:"},
{"id":"rheightLabel","textContent":"Alto:"},
{"id":"cornerRadiusLabel","textContent":"Radio de la esquina:"},
{"id":"iwidthLabel","textContent":"ancho:"},
{"id":"iheightLabel","textContent":"alto:"},
{"id":"svginfo_width","textContent":"Ancho:"},
{"id":"svginfo_height","textContent":"Alto:"},
{"id":"angleLabel","textContent":"ángulo:"},
{"id":"relativeToLabel","textContent":"en relación con:"},
{"id":"zoomLabel","textContent":"Zoom:"},
{"id":"layersLabel","textContent":"Capas:"},
{"id":"selectedPredefined","textContent":"Seleccionar predefinido:"},
{"id":"fitToContent","textContent":"Ajustar al contenido"},
{"id":"tool_source_save","textContent":"Aplicar cambios"},
{"id":"tool_docprops_save","textContent":"Aceptar"},
{"id":"tool_docprops_cancel","textContent":"Cancelar"},
{"id":"tool_source_cancel","textContent":"Cancelar"},
{"id":"fit_to_all","textContent":"Ajustar a todo el contenido"},
{"id":"fit_to_layer_content","textContent":"Ajustar al contenido de la capa"},
{"id":"fit_to_sel","textContent":"Ajustar a la selección"},
{"id":"fit_to_canvas","textContent":"Ajustar al lienzo"},
{"id":"selected_objects","textContent":"Objetos seleccionados"},
{"id":"largest_object","textContent":"El objeto más grande"},
{"id":"smallest_object","textContent":"El objeto más pequeño"},
{"id":"page","textContent":"Página"},
{"id":"fill_tool_bottom","textContent":"Relleno:"},
{"id":"stroke_tool_bottom","textContent":"Contorno:"},
{"id":"path_node_x","title":"Cambiar la posición horizontal X del nodo"},
{"id":"path_node_y","title":"Cambiar la posición vertical Y del nodo"},
{"id":"seg_type","title":"Cambiar el tipo de segmento"},
{"id":"straight_segments","textContent":"Recto"},
{"id":"curve_segments","textContent":"Curvo"},
{"id":"tool_node_clone","title":"Clonar nodo"},
{"id":"tool_node_delete","title":"Suprimir nodo"},
{"id":"selLayerLabel","textContent":"Desplazar elementos hacia:"},
{"id":"selLayerNames","title":"Mover los elementos seleccionados a otra capa"},
{"id":"sidepanel_handle","title":"Arrastrar hacia la izquierda/derecha para modificar el tamaño del panel lateral","textContent":"C a p a s"},
{"id":"tool_wireframe","title":"Modo wireframe"},
{"id":"svginfo_image_props","textContent":"Propiedades de Imagen"},
{"id":"svginfo_title","textContent":"Título"},
{"id":"svginfo_dim","textContent":"Tamaño del lienzo"},
{"id":"includedImages","textContent":"Imágenes integradas"},
{"id":"image_opt_embed","textContent":"Integrar imágenes en forma de datos (archivos locales)"},
{"id":"image_opt_ref","textContent":"Usar la referencia del archivo"},
{"id":"svginfo_editor_prefs","textContent":"Preferencias del Editor"},
{"id":"svginfo_lang","textContent":"Idioma"},
{"id":"svginfo_change_background","textContent":"Fondo del editor"},
{"id":"svginfo_bg_note","textContent":"Nota: El fondo no se guardará junto con la imagen."},
{"id":"svginfo_icons","textContent":"Tamaño de los iconos"},
{"id":"icon_small","textContent":"Pequeño"},
{"id":"icon_medium","textContent":"Mediano"},
{"id":"icon_large","textContent":"Grande"},
{"id":"icon_xlarge","textContent":"Muy grande"},
{"id":"selected_x","title":"Cambiar la posición horizontal X"},
{"id":"selected_y","title":"Cambiar la posición vertical Y"},
{"id":"tool_topath","title":"Convertir en ruta"},
{"id":"tool_reorient","title":"Reorientar la ruta"},
{"id":"tool_node_link","title":"Enlazar puntos de control"},
{"js_strings": {
	"invalidAttrValGiven":"Valor no válido",
	"noContentToFitTo":"No existe un contenido al que ajustarse.",
	'layer':"Capa",
	"dupeLayerName":"¡Ya existe una capa con este nombre!",
	"enterUniqueLayerName":"Introduzca otro nombre distinto para la capa.",
	"enterNewLayerName":"Introduzca el nuevo nombre de la capa.",
	"layerHasThatName":"El nombre introducido es el nombre actual de la capa.",
	"QmoveElemsToLayer":"¿Desplazar los elementos seleccionados a la capa '%s'?",
	"QwantToClear":"¿Desea suprimir el dibujo?\n¡El historial de acciones también se borrará!",
	"QerrorsRevertToSource":"Existen errores sintácticos en su código fuente SVG.\n¿Desea volver al código fuente SVG original?",
	"QignoreSourceChanges":"¿Desea ignorar los cambios realizados sobre el código fuente SVG?",
	"featNotSupported":"Función no compatible.",
	"enterNewImgURL":"Introduzca la nueva URL de la imagen.",
	"Aceptar":"Aceptar",
	"cancel":"Cancelar",
	"pathNodeTooltip":"Arrastre el nodo para desplazarlo. Haga doble clic sobre el nodo para cambiar el tipo de segmento.",
	"pathCtrlPtTooltip":"Arrastre el punto de control para ajustar las propiedades de la curva.",
	"key_up":"arriba",
	"key_down":"abajo",
	"key_backspace":"retroceso",
	"key_del":"suprimir"
	}
}
]<|endoftext|>


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

const path = require("path");
const fileSystem = require("fs");
const fileUtility = require("./fileUtility");
const documentService = require("./documentService");
const cacheManager = require("./cacheManager");
const guidManager = require("./guidManager");
const configServer = require('config').get('server');
const os = require("os");

let docManager = {};

docManager.dir = null;
docManager.req = null;
docManager.res = null;

docManager.existsSync = function(path) {
    let res = true;
    try {
        fileSystem.accessSync(path, fileSystem.F_OK);
    } catch (e) {
        res = false;
    }
    return res;
};
docManager.createDirectory = function(path) {
    if (!this.existsSync(path)) {
        fileSystem.mkdirSync(path);
    }
};

docManager.init = function (dir, req, res) {
    docManager.dir = dir;
    docManager.req = req;
    docManager.res = res;
};

docManager.getLang = function () {
    if (docManager.req.query.lang) {
        return docManager.req.query.lang;
    } else {
        return "en"
    }
};

docManager.getCustomParams = function () {
    let params = "";

    const userid = docManager.req.query.userid;
    params += (userid ? "&userid=" + userid : "");

    const name = docManager.req.query.name;
    params += (name ? "&name=" + name : "");

    const lang = docManager.req.query.lang;
    params += (lang ? "&lang=" + docManager.getLang() : "");

    const fileName = docManager.req.query.fileName;
    params += (fileName ? "&fileName=" + fileName : "");

    const mode = docManager.req.query.mode;
    params += (mode ? "&mode=" + mode : "");

    const type = docManager.req.query.type;
    params += (type ? "&type=" + type : "");

    return params;
};

docManager.getCorrectName = function (fileName, userAddress) {
    const baseName = fileUtility.getFileName(fileName, true);
    const ext = fileUtility.getFileExtension(fileName);
    let name = baseName + ext;
    let index = 1;

    while (this.existsSync(docManager.storagePath(name, userAddress))) {
        name = baseName + " (" + index + ")" + ext;
        index++;
    }

    return name;
};

docManager.createDemo = function (isSample, fileExt, userid, username) {
    const demoName = (isSample ? "sample" : "new") + "." + fileExt;
    const fileName = docManager.getCorrectName(demoName);

    docManager.copyFile(path.join(__dirname, "..","public", "assets", isSample ? "sample" : "new", demoName), docManager.storagePath(fileName));

    docManager.saveFileData(fileName, userid, username);

    return fileName;
};

docManager.saveFileData = function (fileName, userid, username, userAddress) {
    if (!userAddress) {
        userAddress = docManager.curUserHostAddress();
    }
    const date_create = fileSystem.statSync(docManager.storagePath(fileName, userAddress)).mtime;
    const minutes = (date_create.getMinutes() < 10 ? '0' : '') + date_create.getMinutes().toString();
    const month = (date_create.getMonth() < 10 ? '0' : '') + (parseInt(date_create.getMonth().toString()) + 1);
    const sec = (date_create.getSeconds() < 10 ? '0' : '') + date_create.getSeconds().toString();
    const date_format = date_create.getFullYear() + "-" + month + "-" + date_create.getDate() + " " + date_create.getHours() + ":" + minutes + ":" + sec;

    const file_info = docManager.historyPath(fileName, userAddress, true);
    this.createDirectory(file_info);

    fileSystem.writeFileSync(path.join(file_info, fileName + ".txt"), date_format + "," + userid + "," + username);
};

docManager.getFileData = function (fileName, userAddress) {
    const history = path.join(docManager.historyPath(fileName, userAddress, true), fileName + ".txt");
    if (!this.existsSync(history)) {
        return ["2017-01-01", "uid-1", "John Smith"];
    }

    return ((fileSystem.readFileSync(history)).toString()).split(",");
};

docManager.getFileUri = function (fileName) {
    return docManager.getlocalFileUri(fileName, 0, true);
};

docManager.getlocalFileUri = function (fileName, version, forDocumentServer) {
    const serverPath = docManager.getServerUrl(forDocumentServer);
    const hostAddress = docManager.curUserHostAddress();
    const url = serverPath + configServer.get("storagePath") + "/" + hostAddress + "/" + encodeURIComponent(fileName);
    if (!version) {
        return url;
    }
    return url + "-history/" + version;
};

docManager.getServerUrl = function (forDocumentServer) {
    return (forDocumentServer && !!configServer.get("exampleUrl")) ? configServer.get("exampleUrl") : (docManager.getProtocol() + "://" + docManager.req.get("host"));
};

docManager.getCallback = function (fileName) {
    const server = docManager.getServerUrl(true);
    const hostAddress = docManager.curUserHostAddress();
    const handler = "/track?filename=" + encodeURIComponent(fileName) + "&useraddress=" + encodeURIComponent(hostAddress);

    return server + handler;
};

docManager.storagePath = function (fileName, userAddress) {
    fileName = fileUtility.getFileName(fileName);
    const directory = path.join(docManager.dir, docManager.curUserHostAddress(userAddress));
    this.createDirectory(directory);
    return path.join(directory, fileName);
};

docManager.forcesavePath = function (fileName, userAddress, create) {
    let directory = path.join(docManager.dir, docManager.curUserHostAddress(userAddress));
    if (!this.existsSync(directory)) {
        return "";
    }
    directory = path.join(directory, fileName + "-history");
    if (!create && !this.existsSync(directory)) {
        return "";
    }
    this.createDirectory(directory);
    directory = path.join(directory, fileName);
    if (!create && !this.existsSync(directory)) {
        return "";
    }
    return directory;
};

docManager.historyPath = function (fileName, userAddress, create) {
    let directory = path.join(docManager.dir, docManager.curUserHostAddress(userAddress));
    if (!this.existsSync(directory)) {
        return "";
    }
    directory = path.join(directory, fileName + "-history");
    if (!create && !this.existsSync(path.join(directory, "1"))) {
        return "";
    }
    return directory;
};

docManager.versionPath = function (fileName, userAddress, version) {
    const historyPath = docManager.historyPath(fileName, userAddress, true);
    return path.join(historyPath, "" + version);
};

docManager.prevFilePath = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "prev" + fileUtility.getFileExtension(fileName));
};

docManager.diffPath = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "diff.zip");
};

docManager.changesPath = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "changes.txt");
};

docManager.keyPath = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "key.txt");
};

docManager.changesUser = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "user.txt");
};

docManager.getStoredFiles = function () {
    const userAddress = docManager.curUserHostAddress();
    const directory = path.join(docManager.dir, userAddress);
    this.createDirectory(directory);
    const result = [];
    const storedFiles = fileSystem.readdirSync(directory);
    for (let i = 0; i < storedFiles.length; i++) {
        const stats = fileSystem.lstatSync(path.join(directory, storedFiles[i]));

        if (!stats.isDirectory()) {
            let historyPath = docManager.historyPath(storedFiles[i], userAddress);
            let version = 1;
            if (historyPath != "") {
                version = docManager.countVersion(historyPath);
            }

            const time = stats.mtime.getTime();
            const item = {
                time: time,
                name: storedFiles[i],
                documentType: fileUtility.getFileType(storedFiles[i]),
                canEdit: configServer.get("editedDocs").indexOf(fileUtility.getFileExtension(storedFiles[i])) != -1,
                version: version
            };

            if (!result.length) {
                result.push(item);
            } else {
                let j = 0;
                for (; j < result.length; j++) {
                    if (time > result[j].time) {
                        break;
                    }
                }
                result.splice(j, 0, item);
            }
        }
    }
    return result;
};

docManager.getProtocol = function () {
    return docManager.req.headers["x-forwarded-proto"] || docManager.req.protocol;
};

docManager.curUserHostAddress = function (userAddress) {
    if (!userAddress)
        userAddress = docManager.req.headers["x-forwarded-for"] || docManager.req.connection.remoteAddress;

    return userAddress.replace(new RegExp("[^0-9a-zA-Z.=]", "g"), "_");
};

docManager.copyFile = function (exist, target) {
    fileSystem.writeFileSync(target, fileSystem.readFileSync(exist));
};

docManager.getInternalExtension = function (fileType) {
    if (fileType == fileUtility.fileType.word)
        return ".docx";

    if (fileType == fileUtility.fileType.cell)
        return ".xlsx";

    if (fileType == fileUtility.fileType.slide)
        return ".pptx";

    return ".docx";
};

docManager.getKey = function (fileName) {
    const userAddress = docManager.curUserHostAddress();
    let key = userAddress + docManager.getlocalFileUri(fileName);

    let historyPath = docManager.historyPath(fileName, userAddress);
    if (historyPath != ""){
        key += docManager.countVersion(historyPath);
    }

    let storagePath = docManager.storagePath(fileName, userAddress);
    const stat = fileSystem.statSync(storagePath);
    key += stat.mtime.getTime();

    return documentService.generateRevisionId(key);
};

docManager.getDate = function (date) {
    const minutes = (date.getMinutes() < 10 ? '0' : '') + date.getMinutes().toString();
    return date.getMonth() + "/" + date.getDate() + "/" + date.getFullYear() + " " + date.getHours() + ":" + minutes;
};

docManager.getChanges = function (fileName) {
    if (this.existsSync(fileName)) {
        return JSON.parse(fileSystem.readFileSync(fileName));
    }
    return null;
};

docManager.countVersion = function(directory) {
    let i = 0;
    while (this.existsSync(path.join(directory, '' + (i + 1)))) {
        i++;
    }
    return i;
};

docManager.getHistory = function (fileName, content, keyVersion, version) {
    let oldVersion = false;
    let contentJson = null;
    if (content) {
        if (content.changes) {
            contentJson = content.changes[0];
        } else {
            contentJson = content[0];
            oldVersion = true;
        }
    }

    const userAddress = docManager.curUserHostAddress();
    const username = content ? (oldVersion ? contentJson.username : contentJson.user.name) : (docManager.getFileData(fileName, userAddress))[2];
    const userid = content ? (oldVersion ? contentJson.userid : contentJson.user.id) : (docManager.getFileData(fileName, userAddress))[1];
    const created = content ? (oldVersion ? contentJson.date : contentJson.created) : (docManager.getFileData(fileName, userAddress))[0];
    const res = (content && !oldVersion) ? content : {changes: content};
    res.key = keyVersion;
    res.version = version;
    res.created = created;
    res.user = {
        id: userid,
        name: username
    };

    return res;
};

docManager.cleanFolderRecursive = function (folder, me) {
    if (fileSystem.existsSync(folder)) {
        const files = fileSystem.readdirSync(folder);
        files.forEach((file) => {
            const curPath = path.join(folder, file);
            if (fileSystem.lstatSync(curPath).isDirectory()) {
                this.cleanFolderRecursive(curPath, true);
            } else {
                fileSystem.unlinkSync(curPath);
            }
        });
        if (me) {
            fileSystem.rmdirSync(folder);
        }
    }
};

docManager.getFilesInfo = function (fileId) {
    const userAddress = docManager.curUserHostAddress();
    const directory = path.join(docManager.dir, userAddress);
    const filesInDirectory = this.getStoredFiles();
    let responseArray = [];
    let responseObject;
    for (let currentFile = 0; currentFile < filesInDirectory.length; currentFile++) {
        const file = filesInDirectory[currentFile];
        const stats = fileSystem.lstatSync(path.join(directory, file.name));
        const fileObject = {
            version: file.version,
            id: this.getKey(file.name),
            contentLength: `${(stats.size/1024).toFixed(2)} KB`,
            pureContentLength: stats.size,
            title: file.name,
            updated: stats.mtime
        };
        if (fileId !== undefined) {
            if (this.getKey(file.name) == fileId) {
                responseObject = fileObject;
                break;
            }
        }
        else responseArray.push(fileObject);
    };
    if (fileId !== undefined) {
        if (responseObject !== undefined) return responseObject;
        else return "File not found";
    }
    else return responseArray;
};

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

const path = require("path");
const fileSystem = require("fs");
const fileUtility = require("./fileUtility");
const documentService = require("./documentService");
const cacheManager = require("./cacheManager");
const guidManager = require("./guidManager");
const configServer = require('config').get('server');
const os = require("os");

let docManager = {};

docManager.dir = null;
docManager.req = null;
docManager.res = null;

docManager.existsSync = function(path) {
    let res = true;
    try {
        fileSystem.accessSync(path, fileSystem.F_OK);
    } catch (e) {
        res = false;
    }
    return res;
};
docManager.createDirectory = function(path) {
    if (!this.existsSync(path)) {
        fileSystem.mkdirSync(path);
    }
};

docManager.init = function (dir, req, res) {
    docManager.dir = dir;
    docManager.req = req;
    docManager.res = res;
};

docManager.getLang = function () {
    if (docManager.req.query.lang) {
        return docManager.req.query.lang;
    } else {
        return "en"
    }
};

docManager.getCustomParams = function () {
    let params = "";

    const userid = docManager.req.query.userid;
    params += (userid ? "&userid=" + userid : "");

    const name = docManager.req.query.name;
    params += (name ? "&name=" + name : "");

    const lang = docManager.req.query.lang;
    params += (lang ? "&lang=" + docManager.getLang() : "");

    const fileName = docManager.req.query.fileName;
    params += (fileName ? "&fileName=" + fileName : "");

    const mode = docManager.req.query.mode;
    params += (mode ? "&mode=" + mode : "");

    const type = docManager.req.query.type;
    params += (type ? "&type=" + type : "");

    return params;
};

docManager.getCorrectName = function (fileName, userAddress) {
    const baseName = fileUtility.getFileName(fileName, true);
    const ext = fileUtility.getFileExtension(fileName);
    let name = baseName + ext;
    let index = 1;

    while (this.existsSync(docManager.storagePath(name, userAddress))) {
        name = baseName + " (" + index + ")" + ext;
        index++;
    }

    return name;
};

docManager.createDemo = function (isSample, fileExt, userid, username) {
    const demoName = (isSample ? "sample" : "new") + "." + fileExt;
    const fileName = docManager.getCorrectName(demoName);

    docManager.copyFile(path.join(__dirname, "..","public", "assets", isSample ? "sample" : "new", demoName), docManager.storagePath(fileName));

    docManager.saveFileData(fileName, userid, username);

    return fileName;
};

docManager.saveFileData = function (fileName, userid, username, userAddress) {
    if (!userAddress) {
        userAddress = docManager.curUserHostAddress();
    }
    const date_create = fileSystem.statSync(docManager.storagePath(fileName, userAddress)).mtime;
    const minutes = (date_create.getMinutes() < 10 ? '0' : '') + date_create.getMinutes().toString();
    const month = (date_create.getMonth() < 10 ? '0' : '') + (parseInt(date_create.getMonth().toString()) + 1);
    const sec = (date_create.getSeconds() < 10 ? '0' : '') + date_create.getSeconds().toString();
    const date_format = date_create.getFullYear() + "-" + month + "-" + date_create.getDate() + " " + date_create.getHours() + ":" + minutes + ":" + sec;

    const file_info = docManager.historyPath(fileName, userAddress, true);
    this.createDirectory(file_info);

    fileSystem.writeFileSync(path.join(file_info, fileName + ".txt"), date_format + "," + userid + "," + username);
};

docManager.getFileData = function (fileName, userAddress) {
    const history = path.join(docManager.historyPath(fileName, userAddress, true), fileName + ".txt");
    if (!this.existsSync(history)) {
        return ["2017-01-01", "uid-1", "John Smith"];
    }

    return ((fileSystem.readFileSync(history)).toString()).split(",");
};

docManager.getFileUri = function (fileName) {
    return docManager.getlocalFileUri(fileName, 0, true);
};

docManager.getlocalFileUri = function (fileName, version, forDocumentServer) {
    const serverPath = docManager.getServerUrl(forDocumentServer);
    const hostAddress = docManager.curUserHostAddress();
    const url = serverPath + configServer.get("storagePath") + "/" + hostAddress + "/" + encodeURIComponent(fileName);
    if (!version) {
        return url;
    }
    return url + "-history/" + version;
};

docManager.getServerUrl = function (forDocumentServer) {
    return (forDocumentServer && !!configServer.get("exampleUrl")) ? configServer.get("exampleUrl") : (docManager.getProtocol() + "://" + docManager.req.get("host"));
};

docManager.getCallback = function (fileName) {
    const server = docManager.getServerUrl(true);
    const hostAddress = docManager.curUserHostAddress();
    const handler = "/track?filename=" + encodeURIComponent(fileName) + "&useraddress=" + encodeURIComponent(hostAddress);

    return server + handler;
};

docManager.storagePath = function (fileName, userAddress) {
    fileName = fileUtility.getFileName(fileName);
    const directory = path.join(docManager.dir, docManager.curUserHostAddress(userAddress));
    this.createDirectory(directory);
    return path.join(directory, fileName);
};

docManager.forcesavePath = function (fileName, userAddress, create) {
    let directory = path.join(docManager.dir, docManager.curUserHostAddress(userAddress));
    if (!this.existsSync(directory)) {
        return "";
    }
    directory = path.join(directory, fileName + "-history");
    if (!create && !this.existsSync(directory)) {
        return "";
    }
    this.createDirectory(directory);
    directory = path.join(directory, fileName);
    if (!create && !this.existsSync(directory)) {
        return "";
    }
    return directory;
};

docManager.historyPath = function (fileName, userAddress, create) {
    let directory = path.join(docManager.dir, docManager.curUserHostAddress(userAddress));
    if (!this.existsSync(directory)) {
        return "";
    }
    directory = path.join(directory, fileName + "-history");
    if (!create && !this.existsSync(path.join(directory, "1"))) {
        return "";
    }
    return directory;
};

docManager.versionPath = function (fileName, userAddress, version) {
    const historyPath = docManager.historyPath(fileName, userAddress, true);
    return path.join(historyPath, "" + version);
};

docManager.prevFilePath = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "prev" + fileUtility.getFileExtension(fileName));
};

docManager.diffPath = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "diff.zip");
};

docManager.changesPath = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "changes.txt");
};

docManager.keyPath = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "key.txt");
};

docManager.changesUser = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "user.txt");
};

docManager.getStoredFiles = function () {
    const userAddress = docManager.curUserHostAddress();
    const directory = path.join(docManager.dir, userAddress);
    this.createDirectory(directory);
    const result = [];
    const storedFiles = fileSystem.readdirSync(directory);
    for (let i = 0; i < storedFiles.length; i++) {
        const stats = fileSystem.lstatSync(path.join(directory, storedFiles[i]));

        if (!stats.isDirectory()) {
            let historyPath = docManager.historyPath(storedFiles[i], userAddress);
            let version = 1;
            if (historyPath != "") {
                version = docManager.countVersion(historyPath);
            }

            const time = stats.mtime.getTime();
            const item = {
                time: time,
                name: storedFiles[i],
                documentType: fileUtility.getFileType(storedFiles[i]),
                canEdit: configServer.get("editedDocs").indexOf(fileUtility.getFileExtension(storedFiles[i])) != -1,
                version: version
            };

            if (!result.length) {
                result.push(item);
            } else {
                let j = 0;
                for (; j < result.length; j++) {
                    if (time > result[j].time) {
                        break;
                    }
                }
                result.splice(j, 0, item);
            }
        }
    }
    return result;
};

docManager.getProtocol = function () {
    return docManager.req.headers["x-forwarded-proto"] || docManager.req.protocol;
};

docManager.curUserHostAddress = function (userAddress) {
    if (!userAddress)
        userAddress = docManager.req.headers["x-forwarded-for"] || docManager.req.connection.remoteAddress;

    return userAddress.replace(new RegExp("[^0-9a-zA-Z.=]", "g"), "_");
};

docManager.copyFile = function (exist, target) {
    fileSystem.writeFileSync(target, fileSystem.readFileSync(exist));
};

docManager.getInternalExtension = function (fileType) {
    if (fileType == fileUtility.fileType.word)
        return ".docx";

    if (fileType == fileUtility.fileType.cell)
        return ".xlsx";

    if (fileType == fileUtility.fileType.slide)
        return ".pptx";

    return ".docx";
};

docManager.getKey = function (fileName) {
    const userAddress = docManager.curUserHostAddress();
    let key = userAddress + docManager.getlocalFileUri(fileName);

    let historyPath = docManager.historyPath(fileName, userAddress);
    if (historyPath != ""){
        key += docManager.countVersion(historyPath);
    }

    let storagePath = docManager.storagePath(fileName, userAddress);
    const stat = fileSystem.statSync(storagePath);
    key += stat.mtime.getTime();

    return documentService.generateRevisionId(key);
};

docManager.getDate = function (date) {
    const minutes = (date.getMinutes() < 10 ? '0' : '') + date.getMinutes().toString();
    return date.getMonth() + "/" + date.getDate() + "/" + date.getFullYear() + " " + date.getHours() + ":" + minutes;
};

docManager.getChanges = function (fileName) {
    if (this.existsSync(fileName)) {
        return JSON.parse(fileSystem.readFileSync(fileName));
    }
    return null;
};

docManager.countVersion = function(directory) {
    let i = 0;
    while (this.existsSync(path.join(directory, '' + (i + 1)))) {
        i++;
    }
    return i;
};

docManager.getHistory = function (fileName, content, keyVersion, version) {
    let oldVersion = false;
    let contentJson = null;
    if (content) {
        if (content.changes) {
            contentJson = content.changes[0];
        } else {
            contentJson = content[0];
            oldVersion = true;
        }
    }

    const userAddress = docManager.curUserHostAddress();
    const username = content ? (oldVersion ? contentJson.username : contentJson.user.name) : (docManager.getFileData(fileName, userAddress))[2];
    const userid = content ? (oldVersion ? contentJson.userid : contentJson.user.id) : (docManager.getFileData(fileName, userAddress))[1];
    const created = content ? (oldVersion ? contentJson.date : contentJson.created) : (docManager.getFileData(fileName, userAddress))[0];
    const res = (content && !oldVersion) ? content : {changes: content};
    res.key = keyVersion;
    res.version = version;
    res.created = created;
    res.user = {
        id: userid,
        name: username != "null" ? username : null
    };

    return res;
};

docManager.cleanFolderRecursive = function (folder, me) {
    if (fileSystem.existsSync(folder)) {
        const files = fileSystem.readdirSync(folder);
        files.forEach((file) => {
            const curPath = path.join(folder, file);
            if (fileSystem.lstatSync(curPath).isDirectory()) {
                this.cleanFolderRecursive(curPath, true);
            } else {
                fileSystem.unlinkSync(curPath);
            }
        });
        if (me) {
            fileSystem.rmdirSync(folder);
        }
    }
};

docManager.getFilesInfo = function (fileId) {
    const userAddress = docManager.curUserHostAddress();
    const directory = path.join(docManager.dir, userAddress);
    const filesInDirectory = this.getStoredFiles();
    let responseArray = [];
    let responseObject;
    for (let currentFile = 0; currentFile < filesInDirectory.length; currentFile++) {
        const file = filesInDirectory[currentFile];
        const stats = fileSystem.lstatSync(path.join(directory, file.name));
        const fileObject = {
            version: file.version,
            id: this.getKey(file.name),
            contentLength: `${(stats.size/1024).toFixed(2)} KB`,
            pureContentLength: stats.size,
            title: file.name,
            updated: stats.mtime
        };
        if (fileId !== undefined) {
            if (this.getKey(file.name) == fileId) {
                responseObject = fileObject;
                break;
            }
        }
        else responseArray.push(fileObject);
    };
    if (fileId !== undefined) {
        if (responseObject !== undefined) return responseObject;
        else return "File not found";
    }
    else return responseArray;
};

module.exports = docManager;
<|endoftext|>


<commit_before>sap.ui.define([
   'sap/ui/core/mvc/Controller',
   'sap/ui/model/json/JSONModel',
   "sap/ui/core/ResizeHandler"
], function (Controller, JSONModel, ResizeHandler) {

   "use strict";

   return Controller.extend("eve.GL", {

      onInit : function() {
         var id = this.getView().getId();
         console.log("eve.GL.onInit id = ", id);

         var data = this.getView().getViewData();
         // console.log("VIEW DATA", data);

         if (data.standalone && data.conn_handle) {
            this.mgr = new JSROOT.EVE.EveManager();
            this.mgr.UseConnection(data.conn_handle);
            this.standalone = data.standalone;
            this.mgr.RegisterUpdate(this, "onManagerUpdate");

         } else {
            this.mgr = data.mgr;
            this.elementid = data.elementid;
            this.kind = data.kind;
         }

         ResizeHandler.register(this.getView(), this.onResize.bind(this));
         this.fast_event = [];

         this._load_scripts = false;
         this._render_html = false;
         this.geo_painter = null;
         this.painter_ready = false;

         this.mgr.RegisterHighlight(this, "onElementHighlight");

         JSROOT.AssertPrerequisites("geom;user:evedir/EveElements.js", this.onLoadScripts.bind(this));

         // this.checkScences();
      },

      onLoadScripts: function() {
         this._load_scripts = true;
         // only when scripts loaded, one could create objects
         this.creator = new JSROOT.EVE.EveElements();
         this.checkScences();
      },

      onManagerUpdate: function() {
         // called when manager was updated, need only in standalone modes to detect own element id
         if (!this.standalone || this.elementid) return;

         var viewers = this.mgr.FindViewers();

         // first check number of views to create
         var found = null;
         for (var n=0;n<viewers.length;++n) {
            if (viewers[n].fName.indexOf(this.standalone) == 0) { found = viewers[n]; break; }
         }
         if (!found) return;

         this.elementid = found.fElementId;
         this.kind = (found.fName == "Default Viewer") ? "3D" : "2D";
         this.checkScences();

      },

      // function called from GuiPanelController
      onExit: function() {
         if (this.mgr) this.mgr.Unregister(this);
      },

      onElementChanged: function(id, element) {
         // console.log("!!!GL DETECT CHANGED", id);

         this.checkScences();
      },

      onAfterRendering: function() {

         this._render_html = true;

         // TODO: should be specified somehow in XML file
         this.getView().$().css("overflow", "hidden").css("width", "100%").css("height", "100%").parent().css("overflow", "hidden");

         this.checkScences();
      },

      checkScences: function() {

         if (!this._load_scripts || !this._render_html || !this.elementid) return;

         if (!this.register_for_change) {
            this.register_for_change = true;

            // only when rendering completed - register for modify events
            var element = this.mgr.GetElement(this.elementid);

            // loop over scene and add dependency
            for (var k=0;k<element.childs.length;++k) {
               var scene = element.childs[k];
               this.mgr.Register(scene.fSceneId, this, "onElementChanged");
            }
         }

         // start drawing only when all scenes has childs
         // this is configured view
         var element = this.mgr.GetElement(this.elementid), allok = true;

         // loop over scene and add dependency
         for (var k=0;k<element.childs.length;++k) {
            var scene = element.childs[k];
            if (!scene) { allok = false; break; }
            var realscene = this.mgr.GetElement(scene.fSceneId);
            if (!realscene || !realscene.childs) { continue; }
         }

         if (allok) this.drawGeometry();
      },

      drawGeometry: function() {

         // console.log("start geometry drawing", this.getView().getId());

 /*           var shape = {
      _typename: "TGeoBBox",
      fUniqueID: 0, fBits: 0x3000000, fName: "BOX", fTitle: "",
      fShapeId: 256, fShapeBits: 1024, fDX: 200, fDY: 300, fDZ: 400, fOrigin: [0,0,0]
      };

      var geom_obj = JSROOT.extend(JSROOT.Create("TEveGeoShapeExtract"),
                      { fTrans: null, fShape: shape, fRGBA: [0, 1, 0, 0.2], fElements: null, fRnrSelf: true });
 */
         var options = "", geom_obj = null;
         if (this.kind != "3D") options = "ortho_camera";

         if (this.geo_painter) {

            // when geo painter alreay exists - clear all our additional objects
            this.geo_painter.clearExtras();

            this.geo_painter.ResetReady();

         } else {

            // TODO: should be specified somehow in XML file
            this.getView().$().css("overflow", "hidden").css("width", "100%").css("height", "100%");

            this.geo_painter = JSROOT.Painter.CreateGeoPainter(this.getView().getDomRef(), null, options);
         }

         this.painter_ready = false;
         // assign callback function - when needed
         this.geo_painter.WhenReady(this.onGeomertyDrawn.bind(this));

         // now loop over all  scene and create three.js objects

         // top scene element
         var element = this.mgr.GetElement(this.elementid);

         // loop over scene and add dependency
         for (var k=0;k<element.childs.length;++k) {
            var scene = element.childs[k];
            if (!scene) continue;
            var realscene = this.mgr.GetElement(scene.fSceneId);

            if (realscene && realscene.childs)
               this.createExtras(realscene.childs);
         }

         // if geometry detected in the scenes, it will be used to display

         this.geo_painter.AssignObject(geom_obj);

         this.geo_painter.prepareObjectDraw(geom_obj); // and now start everything

         // AMT temporary here, should be set in camera instantiation time
         if (this.geo_painter._camera.type == "OrthographicCamera") {
            this.geo_painter._camera.left = -this.getView().$().width();
            this.geo_painter._camera.right = this.getView().$().width();
            this.geo_painter._camera.top = this.getView().$().height();
            this.geo_painter._camera.bottom = -this.getView().$().height();
            this.geo_painter._camera.updateProjectionMatrix();
            this.geo_painter.Render3D();
         }
         // JSROOT.draw(this.getView().getDomRef(), obj, "", this.onGeomertyDrawn.bind(this));
      },

      onGeomertyDrawn: function(painter) {
         this.painter_ready = true;
         this.geo_painter._highlight_handlers = [ this ]; // register ourself for highlight handling
         this.last_highlight = null;
      },

      /// function called by GeoPainter, when mesh is highlighted
      /// forward message to the EveManager to redistribute event to all other drawings
      HighlightMesh: function(mesh, color, geo_object) {
         if (this.last_highlight === geo_object) return;
         this.last_highlight = geo_object;
         this.mgr.ProcessHighlight(this, geo_object, geo_object ? 0 : 100);
      },

      /// invoked from the manager

      onElementHighlight: function(masterid) {
         if (!this.painter_ready || !this.geo_painter) return;

         // masterid used as identifier, no any recursions
         this.geo_painter.HighlightMesh(null, null, masterid, null, true);
      },

      makeGLRepresentation: function(elem) {
         var fname = elem.render_data.rnr_func;
         var obj3d = this.creator[fname](elem, elem.render_data);
         if (obj3d) {
            obj3d._typename = "THREE.Mesh";

            // SL: this is just identifier for highlight, required to show items on other places, set in creator
            // obj3d.geo_object = elem.fMasterId || elem.fElementId;
            // obj3d.geo_name = elem.fName; // used for highlight

            //AMT: reference needed in MIR callback
            obj3d.eveId = elem.fElementId;

            if (elem.render_data.matrix) {
               obj3d.matrixAutoUpdate = false;
               obj3d.matrix.fromArray( elem.render_data.matrix );
               obj3d.updateMatrixWorld(true);
            }
            return obj3d;
         }
      },
      createExtras: function(arr, toplevel) {
         if (!arr) return;
         for (var k=0;k<arr.length;++k) {
            var elem = arr[k];
            if (elem.render_data) {
               var fname = elem.render_data.rnr_func, obj3d = null;
               if (!this.creator[fname]) {
                  console.error("Function " +fname + " missing in creator");
               } else {
                  var obj3d =  this.makeGLRepresentation(elem);
                  if (obj3d)
                     this.geo_painter.addExtra(obj3d);
               }
            }
            this.createExtras(elem.childs);
         }
      },

      onResize: function(event) {
         // use timeout
         // console.log("resize painter")
         if (this.resize_tmout) clearTimeout(this.resize_tmout);
         this.resize_tmout = setTimeout(this.onResizeTimeout.bind(this), 300); // minimal latency
      },

      onResizeTimeout: function() {
         delete this.resize_tmout;

         // TODO: should be specified somehow in XML file
         this.getView().$().css("overflow", "hidden").css("width", "100%").css("height", "100%");
         if (this.geo_painter)
            this.geo_painter.CheckResize();
      },

      colorChanged: function(el) {
         this.replaceElement(el);
      },

      replaceElement: function(el) {
         if (!this.geo_painter) return;

         var mesh = this.getMesh(el.fElementId);

         var ex = this.geo_painter._extraObjects;
         for (var i=0; i < ex.arr.length; ++i) {
            if (ex.arr[i].geo_object == el.fElementId) {
               ex.RemoveAt(i);
            }
         }
         this.geo_painter.getExtrasContainer().remove(mesh);
         var obj3d =  this.makeGLRepresentation(el);
         if (obj3d) {
            this.geo_painter.addExtra(obj3d);
            this.geo_painter.getExtrasContainer().add(obj3d);
         }
         this.geo_painter.Render3D(-1);
      },

      getMesh : function(elementId) {
         if (this.geo_painter && this.geo_painter._extraObjects ) {
            var ex = this.geo_painter._extraObjects;
            for (var i=0; i < ex.arr.length; ++i) {
               if (ex.arr[i].eveId == elementId)
                  return ex.arr[i];
            }
         }
         return null;
      },

      visibilityChanged: function(el, msg) {
         console.log("visibilit element changed ", this, msg);
         var mesh = this.getMesh(el.fElementId);
         console.log("MESH visibility change ", mesh , el.fRnrSelf);
         mesh.visible = el.fRnrSelf;
         this.geo_painter.Render3D(-1);
      },

      visibilityChildrenChanged: function(el, msg) {
         console.log("visibilit children changed ", this.mgr, el);
         el.fRnrChildren = msg.fRnrChildren;
         if (el.childs) {
            for ( var i = 0; i < el.childs.length; ++i)
            {
               // console.log("visChildren", el.fElementId, "loop child ", el.childs[i] )
               var mesh = this.getMesh(el.childs[i].fElementId);
               el.childs[i].fRnrSelf =  msg.fRnrChildren;;
               mesh.visible = msg.fRnrChildren;
               this.visibilityChildrenChanged(el.childs[i], msg);
               this.geo_painter.Render3D(-1);
            }
         }
      },
      elementAdded: function(em) {
      },
      elementRemoved: function() {
      },
      beginChanges: function() {
      },
      endChanges: function() {
      }
   });

});
<commit_msg>eve7: fix in GL view update<commit_after>sap.ui.define([
   'sap/ui/core/mvc/Controller',
   'sap/ui/model/json/JSONModel',
   "sap/ui/core/ResizeHandler"
], function (Controller, JSONModel, ResizeHandler) {

   "use strict";

   return Controller.extend("eve.GL", {

      onInit : function() {
         var id = this.getView().getId();
         console.log("eve.GL.onInit id = ", id);

         var data = this.getView().getViewData();
         // console.log("VIEW DATA", data);

         if (data.standalone && data.conn_handle) {
            this.mgr = new JSROOT.EVE.EveManager();
            this.mgr.UseConnection(data.conn_handle);
            this.standalone = data.standalone;
            this.mgr.RegisterUpdate(this, "onManagerUpdate");

         } else {
            this.mgr = data.mgr;
            this.elementid = data.elementid;
            this.kind = data.kind;
         }

         ResizeHandler.register(this.getView(), this.onResize.bind(this));
         this.fast_event = [];

         this._load_scripts = false;
         this._render_html = false;
         this.geo_painter = null;
         this.painter_ready = false;

         this.mgr.RegisterHighlight(this, "onElementHighlight");

         JSROOT.AssertPrerequisites("geom;user:evedir/EveElements.js", this.onLoadScripts.bind(this));

         // this.checkScences();
      },

      onLoadScripts: function() {
         this._load_scripts = true;
         // only when scripts loaded, one could create objects
         this.creator = new JSROOT.EVE.EveElements();
         this.checkScences();
      },

      onManagerUpdate: function() {
         // called when manager was updated, need only in standalone modes to detect own element id
         if (!this.standalone || this.elementid) return;

         var viewers = this.mgr.FindViewers();

         // first check number of views to create
         var found = null;
         for (var n=0;n<viewers.length;++n) {
            if (viewers[n].fName.indexOf(this.standalone) == 0) { found = viewers[n]; break; }
         }
         if (!found) return;

         this.elementid = found.fElementId;
         this.kind = (found.fName == "Default Viewer") ? "3D" : "2D";
         this.checkScences();

      },

      // function called from GuiPanelController
      onExit: function() {
         if (this.mgr) this.mgr.Unregister(this);
      },

      onElementChanged: function(id, element) {
         // console.log("!!!GL DETECT CHANGED", id);

         this.checkScences();
      },

      onAfterRendering: function() {

         this._render_html = true;

         // TODO: should be specified somehow in XML file
         this.getView().$().css("overflow", "hidden").css("width", "100%").css("height", "100%").parent().css("overflow", "hidden");

         this.checkScences();
      },

      checkScences: function() {

         if (!this._load_scripts || !this._render_html || !this.elementid) return;

         if (!this.register_for_change) {
            this.register_for_change = true;

            // only when rendering completed - register for modify events
            var element = this.mgr.GetElement(this.elementid);

            // loop over scene and add dependency
            for (var k=0;k<element.childs.length;++k) {
               var scene = element.childs[k];
               this.mgr.Register(scene.fSceneId, this, "onElementChanged");
            }
         }

         // start drawing only when all scenes has childs
         // this is configured view
         var element = this.mgr.GetElement(this.elementid), allok = true;

         // loop over scene and add dependency
         for (var k=0;k<element.childs.length;++k) {
            var scene = element.childs[k];
            if (!scene) { allok = false; break; }
            var realscene = this.mgr.GetElement(scene.fSceneId);
            if (!realscene || !realscene.childs) { allok = false; break; }
         }

         if (allok) this.drawGeometry();
      },

      drawGeometry: function() {

         // console.log("start geometry drawing", this.getView().getId());

 /*           var shape = {
      _typename: "TGeoBBox",
      fUniqueID: 0, fBits: 0x3000000, fName: "BOX", fTitle: "",
      fShapeId: 256, fShapeBits: 1024, fDX: 200, fDY: 300, fDZ: 400, fOrigin: [0,0,0]
      };

      var geom_obj = JSROOT.extend(JSROOT.Create("TEveGeoShapeExtract"),
                      { fTrans: null, fShape: shape, fRGBA: [0, 1, 0, 0.2], fElements: null, fRnrSelf: true });
 */
         var options = "", geom_obj = null;
         if (this.kind != "3D") options = "ortho_camera";

         if (this.geo_painter) {

            // when geo painter alreay exists - clear all our additional objects
            this.geo_painter.clearExtras();

            this.geo_painter.ResetReady();

         } else {

            // TODO: should be specified somehow in XML file
            this.getView().$().css("overflow", "hidden").css("width", "100%").css("height", "100%");

            this.geo_painter = JSROOT.Painter.CreateGeoPainter(this.getView().getDomRef(), null, options);
         }

         this.painter_ready = false;
         // assign callback function - when needed
         this.geo_painter.WhenReady(this.onGeomertyDrawn.bind(this));

         // now loop over all  scene and create three.js objects

         // top scene element
         var element = this.mgr.GetElement(this.elementid);

         // loop over scene and add dependency
         for (var k=0;k<element.childs.length;++k) {
            var scene = element.childs[k];
            if (!scene) continue;
            var realscene = this.mgr.GetElement(scene.fSceneId);

            if (realscene && realscene.childs)
               this.createExtras(realscene.childs);
         }

         // if geometry detected in the scenes, it will be used to display

         this.geo_painter.AssignObject(geom_obj);

         this.geo_painter.prepareObjectDraw(geom_obj); // and now start everything

         // AMT temporary here, should be set in camera instantiation time
         if (this.geo_painter._camera.type == "OrthographicCamera") {
            this.geo_painter._camera.left = -this.getView().$().width();
            this.geo_painter._camera.right = this.getView().$().width();
            this.geo_painter._camera.top = this.getView().$().height();
            this.geo_painter._camera.bottom = -this.getView().$().height();
            this.geo_painter._camera.updateProjectionMatrix();
            this.geo_painter.Render3D();
         }
         // JSROOT.draw(this.getView().getDomRef(), obj, "", this.onGeomertyDrawn.bind(this));
      },

      onGeomertyDrawn: function(painter) {
         this.painter_ready = true;
         this.geo_painter._highlight_handlers = [ this ]; // register ourself for highlight handling
         this.last_highlight = null;
      },

      /// function called by GeoPainter, when mesh is highlighted
      /// forward message to the EveManager to redistribute event to all other drawings
      HighlightMesh: function(mesh, color, geo_object) {
         if (this.last_highlight === geo_object) return;
         this.last_highlight = geo_object;
         this.mgr.ProcessHighlight(this, geo_object, geo_object ? 0 : 100);
      },

      /// invoked from the manager

      onElementHighlight: function(masterid) {
         if (!this.painter_ready || !this.geo_painter) return;

         // masterid used as identifier, no any recursions
         this.geo_painter.HighlightMesh(null, null, masterid, null, true);
      },

      makeGLRepresentation: function(elem) {
         var fname = elem.render_data.rnr_func;
         var obj3d = this.creator[fname](elem, elem.render_data);
         if (obj3d) {
            obj3d._typename = "THREE.Mesh";

            // SL: this is just identifier for highlight, required to show items on other places, set in creator
            // obj3d.geo_object = elem.fMasterId || elem.fElementId;
            // obj3d.geo_name = elem.fName; // used for highlight

            //AMT: reference needed in MIR callback
            obj3d.eveId = elem.fElementId;

            if (elem.render_data.matrix) {
               obj3d.matrixAutoUpdate = false;
               obj3d.matrix.fromArray( elem.render_data.matrix );
               obj3d.updateMatrixWorld(true);
            }
            return obj3d;
         }
      },
      createExtras: function(arr, toplevel) {
         if (!arr) return;
         for (var k=0;k<arr.length;++k) {
            var elem = arr[k];
            if (elem.render_data) {
               var fname = elem.render_data.rnr_func, obj3d = null;
               if (!this.creator[fname]) {
                  console.error("Function " +fname + " missing in creator");
               } else {
                  var obj3d =  this.makeGLRepresentation(elem);
                  if (obj3d)
                     this.geo_painter.addExtra(obj3d);
               }
            }
            this.createExtras(elem.childs);
         }
      },

      onResize: function(event) {
         // use timeout
         // console.log("resize painter")
         if (this.resize_tmout) clearTimeout(this.resize_tmout);
         this.resize_tmout = setTimeout(this.onResizeTimeout.bind(this), 300); // minimal latency
      },

      onResizeTimeout: function() {
         delete this.resize_tmout;

         // TODO: should be specified somehow in XML file
         this.getView().$().css("overflow", "hidden").css("width", "100%").css("height", "100%");
         if (this.geo_painter)
            this.geo_painter.CheckResize();
      },

      colorChanged: function(el) {
         this.replaceElement(el);
      },

      replaceElement: function(el) {
         if (!this.geo_painter) return;

         var mesh = this.getMesh(el.fElementId);

         var ex = this.geo_painter._extraObjects;
         for (var i=0; i < ex.arr.length; ++i) {
            if (ex.arr[i].geo_object == el.fElementId) {
               ex.RemoveAt(i);
            }
         }
         this.geo_painter.getExtrasContainer().remove(mesh);
         var obj3d =  this.makeGLRepresentation(el);
         if (obj3d) {
            this.geo_painter.addExtra(obj3d);
            this.geo_painter.getExtrasContainer().add(obj3d);
         }
         this.geo_painter.Render3D(-1);
      },

      getMesh : function(elementId) {
         if (this.geo_painter && this.geo_painter._extraObjects ) {
            var ex = this.geo_painter._extraObjects;
            for (var i=0; i < ex.arr.length; ++i) {
               if (ex.arr[i].eveId == elementId)
                  return ex.arr[i];
            }
         }
         return null;
      },

      visibilityChanged: function(el, msg) {
         console.log("visibilit element changed ", this, msg);
         var mesh = this.getMesh(el.fElementId);
         console.log("MESH visibility change ", mesh , el.fRnrSelf);
         mesh.visible = el.fRnrSelf;
         this.geo_painter.Render3D(-1);
      },

      visibilityChildrenChanged: function(el, msg) {
         console.log("visibilit children changed ", this.mgr, el);
         el.fRnrChildren = msg.fRnrChildren;
         if (el.childs) {
            for ( var i = 0; i < el.childs.length; ++i)
            {
               // console.log("visChildren", el.fElementId, "loop child ", el.childs[i] )
               var mesh = this.getMesh(el.childs[i].fElementId);
               el.childs[i].fRnrSelf =  msg.fRnrChildren;;
               mesh.visible = msg.fRnrChildren;
               this.visibilityChildrenChanged(el.childs[i], msg);
               this.geo_painter.Render3D(-1);
            }
         }
      },
      elementAdded: function(em) {
      },
      elementRemoved: function() {
      },
      beginChanges: function() {
      },
      endChanges: function() {
      }
   });

});
<|endoftext|>