<commit_before>async function copyAppshareApp(args) {
/*
description("copyAppshareApp function")
base_component_id("copyApp")
load_once_from_file(true)
only_run_on_server(true)
*/

    async function asdf(argsBaseComponentId, newBaseid, parentHashId, code, returnfn, newDisplayName) {
        dbsearch.all(
            "SELECT    child_component_id    FROM    component_usage    where    base_component_id = ? ;  "
            ,
            argsBaseComponentId
            ,

            async function(err, listOfSubComponentsRes)
            {
                var listOfSubComponents = []
                for (var yuy = 0; yuy < listOfSubComponentsRes.length ; yuy++ ) {

                    listOfSubComponents.push( listOfSubComponentsRes[yuy].child_component_id )

                }
                await saveCodeV2( newBaseid, parentHashId, code ,
                            {
                                sub_components:         listOfSubComponents,
                                copy_db_from:           argsBaseComponentId,
                                save_html:              true
                            })

                returnfn({
                            new_display_name:   newDisplayName,
                            base_component_id:  newBaseid
                            })

            })
    }

    var promise = new Promise(async function(returnfn) {

        var argsBaseComponentId = args.base_component_id
        var argsNewAppId        = args.new_app_id

        dbsearch.serialize(
            async function() {
                dbsearch.all(
                    "SELECT    id, code, display_name    FROM    system_code    where    " +
                        " base_component_id = ? and code_tag = 'LATEST';  "
                    ,
                    argsBaseComponentId
                    ,

                    async function(err, results)
                    {
                        if (results.length > 0) {
                            var code = results[0].code
                            if (code) {
                                code = code.toString()
                            }
                            var oldDisplayName = results[0].display_name
                            var parentHashId = results[0].id
                            var newDisplayName = "Copy of " + oldDisplayName
                            code = saveHelper.deleteCodeString(code, "load_once_from_file")
                            code = saveHelper.deleteCodeString(code, "read_only")
                            code = saveHelper.deleteCodeString(code, "visibility")
                            code = saveHelper.deleteCodeString(code, "display_name")
                            code = saveHelper.insertCodeString(code, "display_name", newDisplayName)
                            code = saveHelper.insertCodeString(code, "visibility", "PUBLIC")

                            var newBaseid = argsBaseComponentId + "_" + uuidv1().replace(/\-/g, '');
                            if (argsNewAppId) {
                                newBaseid = argsNewAppId
                            }

                            //hack city - Vue and component strings are separated as otherwise they mark the
                            // code as UI code
                            var vueIndex = code.indexOf("Vue" + ".component")
                            if (vueIndex != -1) {
                                var vueIndexEnd = code.substring(vueIndex).indexOf(",")
                                if (vueIndexEnd) {
                                    code = code.substring(0,vueIndex + 14) + "'" + newBaseid + "'" + code.substring(vueIndex + vueIndexEnd )
                                }
                            }

                            //zzz
                            await asdf(argsBaseComponentId, newBaseid, parentHashId, code, returnfn,newDisplayName)

                        }

                    })
        }, sqlite3.OPEN_READONLY)

    })
    var ret = await promise

    return ret
}
<commit_msg>Trying to update the app ID correctly<commit_after>async function copyAppshareApp(args) {
/*
description("copyAppshareApp function")
base_component_id("copyApp")
load_once_from_file(true)
only_run_on_server(true)
*/

    async function asdf(argsBaseComponentId, newBaseid, parentHashId, code, returnfn, newDisplayName) {
        dbsearch.all(
            "SELECT    child_component_id    FROM    component_usage    where    base_component_id = ? ;  "
            ,
            argsBaseComponentId
            ,

            async function(err, listOfSubComponentsRes)
            {
                var listOfSubComponents = []
                for (var yuy = 0; yuy < listOfSubComponentsRes.length ; yuy++ ) {

                    listOfSubComponents.push( listOfSubComponentsRes[yuy].child_component_id )

                }
                await saveCodeV2( newBaseid, parentHashId, code ,
                            {
                                sub_components:         listOfSubComponents,
                                copy_db_from:           argsBaseComponentId,
                                save_html:              true
                            })

                returnfn({
                            new_display_name:   newDisplayName,
                            base_component_id:  newBaseid
                            })

            })
    }

    var promise = new Promise(async function(returnfn) {

        var argsBaseComponentId = args.base_component_id
        var argsNewAppId        = args.new_app_id

        dbsearch.serialize(
            async function() {
                dbsearch.all(
                    "SELECT    id, code, display_name    FROM    system_code    where    " +
                        " base_component_id = ? and code_tag = 'LATEST';  "
                    ,
                    argsBaseComponentId
                    ,

                    async function(err, results)
                    {
                        if (results.length > 0) {
                            var code = results[0].code
                            if (code) {
                                code = code.toString()
                            }
                            var newBaseid = argsBaseComponentId + "_" + uuidv1().replace(/\-/g, '');

                            var oldDisplayName = results[0].display_name
                            var parentHashId = results[0].id
                            var newDisplayName = "Copy of " + oldDisplayName
                            code = saveHelper.deleteCodeString(code, "load_once_from_file")
                            code = saveHelper.deleteCodeString(code, "read_only")
                            code = saveHelper.deleteCodeString(code, "visibility")

                            var formEditor = saveHelper.getValueOfCodeString(code, "formEditor",")//formEditor")
                            formEditor.id = newBaseid
                            code = saveHelper.deleteCodeString(code, "formEditor",")//formEditor")
                            code = saveHelper.insertCodeString(code, "formEditor", formEditor,")//formEditor")

                            code = saveHelper.deleteCodeString(code, "display_name")
                            code = saveHelper.insertCodeString(code, "display_name", newDisplayName)
                            code = saveHelper.insertCodeString(code, "visibility", "PUBLIC")

                            if (argsNewAppId) {
                                newBaseid = argsNewAppId
                            }

                            //hack city - Vue and component strings are separated as otherwise they mark the
                            // code as UI code
                            var vueIndex = code.indexOf("Vue" + ".component")
                            if (vueIndex != -1) {
                                var vueIndexEnd = code.substring(vueIndex).indexOf(",")
                                if (vueIndexEnd) {
                                    code = code.substring(0,vueIndex + 14) + "'" + newBaseid + "'" + code.substring(vueIndex + vueIndexEnd )
                                }
                            }

                            //zzz
                            await asdf(argsBaseComponentId, newBaseid, parentHashId, code, returnfn,newDisplayName)

                        }

                    })
        }, sqlite3.OPEN_READONLY)

    })
    var ret = await promise

    return ret
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 Internet of Protocols Alliance (IOPA)
 *
 * 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.
 */

// DEPENDENCIES
var iopa = require('iopa');
var dgram = require('dgram');
var util = require('util');
var events = require('events');
var iopaStream = require('iopa-common-stream');
var net = require('net');

const IOPA = iopa.constants.IOPA,
  SERVER = iopa.constants.SERVER

const packageVersion = require('../../package.json').version;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/* ***********************************************************************
 * IOPA UDP SIMPLEX SERVER AND CLIENT ON SAME PORT
 * Unicast or Multicast+Unicast
 * *********************************************************************** */
var seq = 0;

/**
 * Representes UDP Server
 *
 * @class UdpSimple
 * @param options (object)  {currently unusued}
 * @param appFunc (function(context))   delegate to which to call with all new inbound requests
 * @event request function(context)    alternative way to get inbound requests
 * @event error function(err, args)
 * @constructor
 * @public
 */
function UdpSimplex(options, appFunc) {
  _classCallCheck(this, UdpSimplex);

  if (typeof options === 'function') {
    appFunc = options;
    options = {};
  }

  events.EventEmitter.call(this);

  if (typeof options == 'string'){
    this._id = options;
    options = {};
    options[SERVER.Id] = this._id
  } else
  {
     options = options || {};
     this._id = options[SERVER.Id] || (seq++).toString();
  }

  this._options = options;
  this._factory = new iopa.Factory(options);

  this._appFunc = appFunc;
  this._connect = this._appFunc.connect || function (context) { return Promise.resolve(context) };
  this._dispatch = this._appFunc.dispatch || function (context) { return Promise.resolve(context) };

  this._udp = null;

  this._connections = {};
}

util.inherits(UdpSimplex, events.EventEmitter)

/**
 * @method listen
 * Create socket and bind to local port to listen for incoming requests
 *
 * @param {Integer} [port] Port on which to listen
 * @param {String} [address] Local host address on which to listen
 * @returns {Promise}
 * @public
 */
UdpSimplex.prototype.listen = function UdpSimplex_listen(port, address, options) {
  options = options || {};
  iopa.util.shallow.merge(options, this._options);

  if (port == undefined) {
    address = 0;
  }

  if (this._udp)
    return new Promise(function (resolve, reject) {
      reject("Already listening");
    });

  if (address && net.isIPv6(address))
    options[SERVER.LocalPortType] = 'udp6';

  if (!options[SERVER.LocalPortType])
    options[SERVER.LocalPortType] = 'udp4'

  if (!options[SERVER.LocalPortReuse])
    options[SERVER.LocalPortReuse] = true;

  if (Number(process.version.match(/^v(\d+\.\d+)/)[1]) > 0.11) {
    //RE-USE ADDRESS IF NODE 0.12 OR LATER
    this._udp = dgram.createSocket({ type: options[SERVER.LocalPortType], "reuseAddr": options[SERVER.LocalPortReuse] })
  }
  else {
    this._udp = dgram.createSocket(this._options[SERVER.LocalPortType]);
  }

  this._udp.on("message", this._onMessage.bind(this));
  var that = this;

  return new Promise(function (resolve, reject) {
    that._udp.bind(port, address || null,
      function () {
        that._linfo = that._udp.address();
        that._port = that._linfo.port;
        that._address = that._linfo.address;

        var el;
        if (typeof options[SERVER.MulticastAddress] == 'object' && util.isArray(options[SERVER.MulticastAddress])) {
            for (var n = 0; n < options[SERVER.MulticastAddress].length; n++) {
              el = options[SERVER.MulticastAddress][n];
              that._udp.setBroadcast(true);
              that._udp.setMulticastTTL(128);
              // that._multicastUDP.setMulticastLoopback(true);
              if (typeof el == 'string') {
                that._udp.addMembership(el);
                that._multicastAddress = el;
              }
              else if (typeof el == 'object' && util.isArray(el)) {
                that._udp.addMembership(el[0], el[1]);
                    that._multicastAddress = el[0];
              }
            }
          }
          else if (typeof options[SERVER.MulticastAddress] == 'string') {
            el = options[SERVER.MulticastAddress];
                that._udp.addMembership(el);
                that._multicastAddress = el;
          }

        resolve(that._linfo);
      });
  });
};

Object.defineProperty(UdpSimplex.prototype, SERVER.LocalPort, { get: function () { return this._port; } });
Object.defineProperty(UdpSimplex.prototype, SERVER.LocalAddress, { get: function () { return this._address; } });
Object.defineProperty(UdpSimplex.prototype, SERVER.MulticastAddress, { get: function () { return this._multicastAddress; } });
Object.defineProperty(UdpSimplex.prototype, "port", { get: function () { return this._port; } });
Object.defineProperty(UdpSimplex.prototype, "address", { get: function () { return this._address; } });
Object.defineProperty(UdpSimplex.prototype, SERVER.RawTransport, {
  get: function () { return this; },
  set: function(value) {
    this._write = value._write.bind(value);
    this.connect = value.connect.bind(value);
    this._fetch = value._fetch.bind(value);
     } });

UdpSimplex.prototype._onMessage = function UdpSimplex_onMessage(msg, rinfo) {
  var context = this._factory.createContext();
  context[IOPA.Method] = IOPA.METHODS.data;
  context[SERVER.Id] = this._id;
  context[SERVER.TLS] = false;
  context[SERVER.RemoteAddress] = rinfo.address;
  context[SERVER.RemotePort] = rinfo.port;
  context[SERVER.LocalAddress] = this._address;
  context[SERVER.LocalPort] = this._port;
  context[SERVER.RawStream] =  new iopaStream.IncomingStream();
  context[SERVER.RawStream].append(msg);
  context[SERVER.IsLocalOrigin] = false;
  context[SERVER.IsRequest] = true;
  context[SERVER.SessionId] = context[SERVER.LocalAddress] + ":" + context[SERVER.LocalPort] + "-" + context[SERVER.RemoteAddress] + ":" + context[SERVER.RemotePort];

  var response = context.response;
   response[SERVER.Id] = this._id;

  response[SERVER.TLS] = context[SERVER.TLS];
  response[SERVER.RemoteAddress] = context[SERVER.RemoteAddress];
  response[SERVER.RemotePort] = context[SERVER.RemotePort];
  response[SERVER.LocalAddress] = context[SERVER.LocalAddress];
  response[SERVER.LocalPort] = context[SERVER.LocalPort];
  response[SERVER.RawStream] = new iopaStream.OutgoingStreamTransform(this._write.bind(this, context.response));
  response[SERVER.IsLocalOrigin] = true;
  response[SERVER.IsRequest] = false;

  context[SERVER.Fetch] = this._fetch.bind(this, context, response);
  context[SERVER.Dispatch] = this._dispatch;

  context.using(this._appFunc);
}

/**
 * Creates a new IOPA Request using a UDP Url including host and port name
 *
 * @method connect

 * @parm {object} options not used
 * @parm {string} urlStr url representation of ://127.0.0.1:8200
 * @public
 * @constructor
 */
UdpSimplex.prototype.connect = function UdpSimplex_connect(urlStr, defaults) {
  defaults = defaults || {};
  defaults[IOPA.Method] = defaults[IOPA.Method] || IOPA.METHODS.connect;
  var channelContext = this._factory.createRequest(urlStr, defaults);
  channelContext[SERVER.Id] = this._id;

  channelContext[SERVER.LocalPort] = this._port;
  channelContext[SERVER.LocalAddress] = this._address;

  channelContext[SERVER.OriginalUrl] = urlStr;

  channelContext[SERVER.Fetch] = this._fetch.bind(this, channelContext, channelContext);
  channelContext[SERVER.Dispatch] = this._dispatch;
  channelContext[SERVER.Disconnect] = this._disconnect.bind(this, channelContext);

  channelContext[SERVER.RawStream] = new iopaStream.OutgoingStreamTransform(this._write.bind(this, channelContext));
  channelContext[SERVER.RawStream].on('finish', this._disconnect.bind(this, channelContext, null));

  channelContext[SERVER.SessionId] = channelContext[SERVER.LocalAddress] + ":" + channelContext[SERVER.LocalPort] + "-" + channelContext[SERVER.RemoteAddress] + ":" + channelContext[SERVER.RemotePort];
  this._connections[channelContext[SERVER.SessionId]] = channelContext;

  var that = this;
  return new Promise(function (resolve, reject) {resolve(that._connect(channelContext));});
};

UdpSimplex.prototype._write = function UdpSimplex_write(context, chunk, encoding, done) {
  if (typeof chunk === "string" || chunk instanceof String) {
    chunk = new Buffer(chunk, encoding);
  }
  this._udp.send(chunk, 0, chunk.length, context[SERVER.RemotePort], context[SERVER.RemoteAddress], done);
}

/**
* Fetches a new IOPA Request using a UDP Url including host and port name
*
* @method fetch

* @param path string representation of ://127.0.0.1/hello
* @param options object dictionary to override defaults
* @param pipeline function(context):Promise  to call with context record
* @returns Promise<null>
* @public
*/
UdpSimplex.prototype._fetch = function UdpSimplex_Fetch(channelContext, transportContext, path, options, pipeline) {
  if (typeof options === 'function') {
    pipeline = options;
    options = {};
  }

  var urlStr = channelContext[IOPA.Scheme] +
    "//" +
    channelContext[SERVER.RemoteAddress] + ":" + channelContext[SERVER.RemotePort] +
    channelContext[IOPA.PathBase] +
    channelContext[IOPA.Path] + path;

  var context = channelContext[SERVER.Factory].createRequest(urlStr, options);
  channelContext[SERVER.Id] = this._id;

  channelContext[SERVER.Factory].mergeCapabilities(context, channelContext);
  context[SERVER.SessionId] = channelContext[SERVER.SessionId];

  context[SERVER.LocalAddress] = transportContext[SERVER.LocalAddress];
  context[SERVER.LocalPort] = transportContext[SERVER.LocalPort];
  context[SERVER.RawStream] = transportContext[SERVER.RawStream];

  return context.using(function () {
    var value = channelContext[SERVER.Dispatch](context);
    pipeline(context);
    return value;
  });
};

/**
 * @method _disconnect
 * Close the  channel context
 *
 * @public
 */
UdpSimplex.prototype._disconnect = function UdpSimplex_disconnect(channelContext, err) {
  if (channelContext[IOPA.CancelToken].isCancelled)
     return;

   channelContext[IOPA.Events] = null;
   channelContext[SERVER.CancelTokenSource].cancel(IOPA.EVENTS.Disconnect);
   delete this._connections[channelContext[SERVER.SessionId]];
   channelContext.dispose();
}

/**
 * @method close
 * Close the underlying socket and stop listening for data on it.
 *
 * @returns {Promise()}
 * @public
 */
UdpSimplex.prototype.close = function UdpSimplex_close() {

    for (var key in this._connections)
      this._disconnect(this._connections[key], null);

   this._connections = {};

   this._udp.close();
   this.emit("close");

   this._udp = undefined;
   return Promise.resolve(null);
};

module.exports = UdpSimplex;<commit_msg>dev test<commit_after>/*
 * Copyright (c) 2015 Internet of Protocols Alliance (IOPA)
 *
 * 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.
 */

// DEPENDENCIES
var iopa = require('iopa');
var dgram = require('dgram');
var util = require('util');
var events = require('events');
var iopaStream = require('iopa-common-stream');
var net = require('net');

const IOPA = iopa.constants.IOPA,
  SERVER = iopa.constants.SERVER

const packageVersion = require('../../package.json').version;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/* ***********************************************************************
 * IOPA UDP SIMPLEX SERVER AND CLIENT ON SAME PORT
 * Unicast or Multicast+Unicast
 * *********************************************************************** */
var seq = 0;

/**
 * Representes UDP Server
 *
 * @class UdpSimple
 * @param options (object)  {currently unusued}
 * @param appFunc (function(context))   delegate to which to call with all new inbound requests
 * @event request function(context)    alternative way to get inbound requests
 * @event error function(err, args)
 * @constructor
 * @public
 */
function UdpSimplex(options, appFunc) {
  _classCallCheck(this, UdpSimplex);

  if (typeof options === 'function') {
    appFunc = options;
    options = {};
  }

  events.EventEmitter.call(this);

  if (typeof options == 'string'){
    this._id = options;
    options = {};
    options[SERVER.Id] = this._id
  } else
  {
     options = options || {};
     this._id = options[SERVER.Id] || (seq++).toString();
  }

  this._options = options;
  this._factory = new iopa.Factory(options);

  this._appFunc = appFunc;
  this._connect = this._appFunc.connect || function (context) { return Promise.resolve(context) };
  this._dispatch = this._appFunc.dispatch || function (context) { return Promise.resolve(context) };

  this._udp = null;

  this._connections = {};
}

util.inherits(UdpSimplex, events.EventEmitter)

/**
 * @method listen
 * Create socket and bind to local port to listen for incoming requests
 *
 * @param {Integer} [port] Port on which to listen
 * @param {String} [address] Local host address on which to listen
 * @returns {Promise}
 * @public
 */
UdpSimplex.prototype.listen = function UdpSimplex_listen(port, address, options) {
  options = options || {};
  iopa.util.shallow.merge(options, this._options);

  if (port == undefined) {
    address = 0;
  }

  if (this._udp)
    return new Promise(function (resolve, reject) {
      reject("Already listening");
    });

  if (address && net.isIPv6(address))
    options[SERVER.LocalPortType] = 'udp6';

  if (!options[SERVER.LocalPortType])
    options[SERVER.LocalPortType] = 'udp4'

  if (!options[SERVER.LocalPortReuse])
    options[SERVER.LocalPortReuse] = true;

  if (Number(process.version.match(/^v(\d+\.\d+)/)[1]) > 0.11) {
    //RE-USE ADDRESS IF NODE 0.12 OR LATER
    this._udp = dgram.createSocket({ type: options[SERVER.LocalPortType], "reuseAddr": options[SERVER.LocalPortReuse] })
  }
  else {
    this._udp = dgram.createSocket(this._options[SERVER.LocalPortType]);
  }

  this._udp.on("message", this._onMessage.bind(this));
  var that = this;

  return new Promise(function (resolve, reject) {
    that._udp.bind(port, address || null,
      function () {
        that._linfo = that._udp.address();
        that._port = that._linfo.port;
        that._address = that._linfo.address;

        var el;
        if (typeof options[SERVER.MulticastAddress] == 'object' && util.isArray(options[SERVER.MulticastAddress])) {
            for (var n = 0; n < options[SERVER.MulticastAddress].length; n++) {
              el = options[SERVER.MulticastAddress][n];
              that._udp.setBroadcast(true);
              that._udp.setMulticastTTL(128);
              // that._multicastUDP.setMulticastLoopback(true);
              if (typeof el == 'string') {
                that._udp.addMembership(el);
                that._multicastAddress = el;
              }
              else if (typeof el == 'object' && util.isArray(el)) {
                that._udp.addMembership(el[0], el[1]);
                    that._multicastAddress = el[0];
              }
            }
          }
          else if (typeof options[SERVER.MulticastAddress] == 'string') {
            el = options[SERVER.MulticastAddress];
                that._udp.addMembership(el);
                that._multicastAddress = el;
          }

        resolve(that._linfo);
      });
  });
};

Object.defineProperty(UdpSimplex.prototype, SERVER.LocalPort, { get: function () { return this._port; } });
Object.defineProperty(UdpSimplex.prototype, SERVER.LocalAddress, { get: function () { return this._address; } });
Object.defineProperty(UdpSimplex.prototype, SERVER.MulticastAddress, { get: function () { return this._multicastAddress; } });
Object.defineProperty(UdpSimplex.prototype, "port", { get: function () { return this._port; } });
Object.defineProperty(UdpSimplex.prototype, "address", { get: function () { return this._address; } });
Object.defineProperty(UdpSimplex.prototype, SERVER.RawTransport, {
  get: function () { return this; },
  set: function(value) {
    this._write = value._write.bind(value);
    this.connect = value.connect.bind(value);
    this._fetch = value._fetch.bind(value);
     } });

UdpSimplex.prototype._onMessage = function UdpSimplex_onMessage(msg, rinfo) {
  var context = this._factory.createContext();
  context[IOPA.Method] = IOPA.METHODS.data;
  context[SERVER.Id] = this._id;
  context[SERVER.TLS] = false;
  context[SERVER.RemoteAddress] = rinfo.address;
  context[SERVER.RemotePort] = rinfo.port;
  context[SERVER.LocalAddress] = this._address;
  context[SERVER.LocalPort] = this._port;
  context[SERVER.RawStream] =  new iopaStream.IncomingStream();
  context[SERVER.RawStream].append(msg);
  context[SERVER.IsLocalOrigin] = false;
  context[SERVER.IsRequest] = true;
  context[SERVER.SessionId] = context[SERVER.LocalAddress] + ":" + context[SERVER.LocalPort] + "-" + context[SERVER.RemoteAddress] + ":" + context[SERVER.RemotePort];

  var response = context.response;
   response[SERVER.Id] = this._id;

  response[SERVER.TLS] = context[SERVER.TLS];
  response[SERVER.RemoteAddress] = context[SERVER.RemoteAddress];
  response[SERVER.RemotePort] = context[SERVER.RemotePort];
  response[SERVER.LocalAddress] = context[SERVER.LocalAddress];
  response[SERVER.LocalPort] = context[SERVER.LocalPort];
  response[SERVER.RawStream] = new iopaStream.OutgoingStreamTransform(this._write.bind(this, context.response));
  response[SERVER.IsLocalOrigin] = true;
  response[SERVER.IsRequest] = false;

  context[SERVER.Fetch] = this._fetch.bind(this, context, response);
  context[SERVER.Dispatch] = this._dispatch;

  context.using(this._appFunc);
}

/**
 * Creates a new IOPA Request using a UDP Url including host and port name
 *
 * @method connect

 * @parm {object} options not used
 * @parm {string} urlStr url representation of ://127.0.0.1:8200
 * @public
 * @constructor
 */
UdpSimplex.prototype.connect = function UdpSimplex_connect(urlStr, defaults) {
  defaults = defaults || {};
  defaults[IOPA.Method] = defaults[IOPA.Method] || IOPA.METHODS.connect;
  var channelContext = this._factory.createRequest(urlStr, defaults);
  channelContext[SERVER.Id] = this._id;

  channelContext[SERVER.LocalPort] = this._port;
  channelContext[SERVER.LocalAddress] = this._address;

  channelContext[SERVER.OriginalUrl] = urlStr;

  channelContext[SERVER.Fetch] = this._fetch.bind(this, channelContext, channelContext);
  channelContext[SERVER.Dispatch] = this._dispatch;
  channelContext[SERVER.Disconnect] = this._disconnect.bind(this, channelContext);

  channelContext[SERVER.RawStream] = new iopaStream.OutgoingStreamTransform(this._write.bind(this, channelContext));
  channelContext[SERVER.RawStream].on('finish', this._disconnect.bind(this, channelContext, null));

  channelContext[SERVER.SessionId] = channelContext[SERVER.LocalAddress] + ":" + channelContext[SERVER.LocalPort] + "-" + channelContext[SERVER.RemoteAddress] + ":" + channelContext[SERVER.RemotePort];
  this._connections[channelContext[SERVER.SessionId]] = channelContext;

  var that = this;
  return new Promise(function (resolve, reject) {resolve(that._connect(channelContext));});
};

UdpSimplex.prototype._write = function UdpSimplex_write(context, chunk, encoding, done) {
  if (typeof chunk === "string" || chunk instanceof String) {
    chunk = new Buffer(chunk, encoding);
  }
  this._udp.send(chunk, 0, chunk.length, context[SERVER.RemotePort], context[SERVER.RemoteAddress], done);
}

/**
* Fetches a new IOPA Request using a UDP Url including host and port name
*
* @method fetch

* @param path string representation of /hello
* @param options object dictionary to override defaults
* @param pipeline function(context):Promise  to call with context record
* @returns Promise<null>
* @public
*/
UdpSimplex.prototype._fetch = function UdpSimplex_Fetch(channelContext, transportContext, path, options, prePipeline, postPipeline) {
  if (typeof options === 'function') {
    postPipeline = prePipeline;
    prePipeline = options;
    options = {};
  }

  var urlStr = channelContext[IOPA.Scheme] +
    "//" +
    channelContext[SERVER.RemoteAddress] + ":" + channelContext[SERVER.RemotePort] +
    channelContext[IOPA.PathBase] +
    channelContext[IOPA.Path] + path;

  var context = channelContext[SERVER.Factory].createRequest(urlStr, options);
  channelContext[SERVER.Id] = this._id;

  channelContext[SERVER.Factory].mergeCapabilities(context, channelContext);
  context[SERVER.SessionId] = channelContext[SERVER.SessionId];

  context[SERVER.LocalAddress] = transportContext[SERVER.LocalAddress];
  context[SERVER.LocalPort] = transportContext[SERVER.LocalPort];
  context[SERVER.RawStream] = transportContext[SERVER.RawStream];

  return context.using(function () {
    if (prePipeline)
       prePipeline(context);

    var value = channelContext[SERVER.Dispatch](context);

    if (postPipeline)
       postPipeline(context);

    return value;
  });
};

/**
 * @method _disconnect
 * Close the  channel context
 *
 * @public
 */
UdpSimplex.prototype._disconnect = function UdpSimplex_disconnect(channelContext, err) {
  if (channelContext[IOPA.CancelToken].isCancelled)
     return;

   channelContext[IOPA.Events] = null;
   channelContext[SERVER.CancelTokenSource].cancel(IOPA.EVENTS.Disconnect);
   delete this._connections[channelContext[SERVER.SessionId]];
   channelContext.dispose();
}

/**
 * @method close
 * Close the underlying socket and stop listening for data on it.
 *
 * @returns {Promise()}
 * @public
 */
UdpSimplex.prototype.close = function UdpSimplex_close() {

    for (var key in this._connections)
      this._disconnect(this._connections[key], null);

   this._connections = {};

   this._udp.close();
   this.emit("close");

   this._udp = undefined;
   return Promise.resolve(null);
};

module.exports = UdpSimplex;<|endoftext|>


<commit_before>import * as THREE from 'three';
import { Animation } from '../Animation';
import { EVENTS, SPHERE_RADIUS } from '../data/constants';
import { SYSTEM } from '../data/system';
import { each, isExtendedPosition, isNil } from '../utils';
import { AbstractService } from './AbstractService';

/**
 * @summary Viewer and renderer
 * @extends PSV.services.AbstractService
 * @memberof PSV.services
 */
export class Renderer extends AbstractService {

  /**
   * @param {PSV.Viewer} psv
   */
  constructor(psv) {
    super(psv);

    /**
     * @member {external:THREE.WebGLRenderer}
     * @readonly
     * @protected
     */
    this.renderer = new THREE.WebGLRenderer({ alpha: true });
    this.renderer.setPixelRatio(SYSTEM.pixelRatio);
    this.renderer.domElement.className = 'psv-canvas';

    /**
     * @member {external:THREE.Scene}
     * @readonly
     * @protected
     */
    this.scene = new THREE.Scene();

    /**
     * @member {external:THREE.PerspectiveCamera}
     * @readonly
     * @protected
     */
    this.camera = new THREE.PerspectiveCamera(50, 16 / 9, 1, 2 * SPHERE_RADIUS);

    /**
     * @member {external:THREE.Mesh}
     * @readonly
     * @protected
     */
    this.mesh = this.psv.adapter.createMesh();
    this.mesh.userData = { psvSphere: true };

    /**
     * @member {external:THREE.Group}
     * @readonly
     * @private
     */
    this.meshContainer = new THREE.Group();
    this.meshContainer.add(this.mesh);
    this.scene.add(this.meshContainer);

    /**
     * @member {external:THREE.Raycaster}
     * @readonly
     * @protected
     */
    this.raycaster = new THREE.Raycaster();

    /**
     * @member {number}
     * @private
     */
    this.timestamp = null;

    /**
     * @member {boolean}
     * @private
     */
    this.ready = false;

    /**
     * @member {HTMLElement}
     * @readonly
     * @package
     */
    this.canvasContainer = document.createElement('div');
    this.canvasContainer.className = 'psv-canvas-container';
    this.canvasContainer.style.background = this.psv.config.canvasBackground;
    this.canvasContainer.style.cursor = this.psv.config.mousemove ? 'move' : 'default';
    this.canvasContainer.appendChild(this.renderer.domElement);
    this.psv.container.appendChild(this.canvasContainer);

    psv.on(EVENTS.SIZE_UPDATED, this);
    psv.on(EVENTS.ZOOM_UPDATED, this);
    psv.on(EVENTS.POSITION_UPDATED, this);

    psv.on(EVENTS.CONFIG_CHANGED, () => {
      this.canvasContainer.style.cursor = this.psv.config.mousemove ? 'move' : 'default';
    });

    this.hide();
  }

  /**
   * @override
   */
  destroy() {
    // cancel render loop
    this.renderer.setAnimationLoop(null);

    // destroy ThreeJS view
    this.__cleanTHREEScene(this.scene);

    // remove container
    this.psv.container.removeChild(this.canvasContainer);

    delete this.canvasContainer;
    delete this.renderer;
    delete this.scene;
    delete this.camera;
    delete this.mesh;
    delete this.meshContainer;
    delete this.raycaster;

    super.destroy();
  }

  /**
   * @summary Handles events
   * @param {Event} evt
   * @private
   */
  handleEvent(evt) {
    /* eslint-disable */
    switch (evt.type) {
      // @formatter:off
      case EVENTS.SIZE_UPDATED:     this.__onSizeUpdated(); break;
      case EVENTS.ZOOM_UPDATED:     this.__onZoomUpdated(); break;
      case EVENTS.POSITION_UPDATED: this.__onPositionUpdated(); break;
      // @formatter:on
    }
    /* eslint-enable */
  }

  /**
   * @summary Hides the viewer
   */
  hide() {
    this.canvasContainer.style.opacity = 0;
  }

  /**
   * @summary Shows the viewer
   */
  show() {
    this.canvasContainer.style.opacity = 1;
  }

  /**
   * @summary Updates the size of the renderer and the aspect of the camera
   * @private
   */
  __onSizeUpdated() {
    this.renderer.setSize(this.prop.size.width, this.prop.size.height);
    this.camera.aspect = this.prop.aspect;
    this.camera.updateProjectionMatrix();
    this.prop.needsUpdate = true;
  }

  /**
   * @summary Updates the fov of the camera
   * @private
   */
  __onZoomUpdated() {
    this.camera.fov = this.prop.vFov;
    this.camera.updateProjectionMatrix();
    this.prop.needsUpdate = true;
  }

  /**
   * @summary Updates the position of the camera
   * @private
   */
  __onPositionUpdated() {
    this.camera.position.set(0, 0, 0);
    this.camera.lookAt(this.prop.direction);
    if (this.config.fisheye) {
      this.camera.position.copy(this.prop.direction).multiplyScalar(this.config.fisheye / 2).negate();
    }
    this.prop.needsUpdate = true;
  }

  /**
   * @summary Main event loop, calls {@link render} if `prop.needsUpdate` is true
   * @param {number} timestamp
   * @fires PSV.before-render
   * @private
   */
  __renderLoop(timestamp) {
    const elapsed = this.timestamp !== null ? timestamp - this.timestamp : 0;
    this.timestamp = timestamp;

    this.psv.trigger(EVENTS.BEFORE_RENDER, timestamp, elapsed);
    each(this.psv.dynamics, d => d.update(elapsed));

    if (this.prop.needsUpdate) {
      this.render();
      this.prop.needsUpdate = false;
    }
  }

  /**
   * @summary Performs a render
   * @description Do not call this method directly, instead call
   * {@link PSV.Viewer#needsUpdate} on {@link PSV.event:before-render}.
   * @fires PSV.render
   */
  render() {
    this.renderer.render(this.scene, this.camera);
    this.psv.trigger(EVENTS.RENDER);
  }

  /**
   * @summary Applies the texture to the scene, creates the scene if needed
   * @param {PSV.TextureData} textureData
   * @fires PSV.panorama-loaded
   * @package
   */
  setTexture(textureData) {
    this.prop.panoData = textureData.panoData;

    this.psv.adapter.setTexture(this.mesh, textureData);

    if (!this.ready) {
      this.renderer.setAnimationLoop(t => this.__renderLoop(t));
      this.ready = true;
    }

    this.psv.needsUpdate();

    this.psv.trigger(EVENTS.PANORAMA_LOADED);
  }

  /**
   * @summary Apply a panorama data pose to a Mesh
   * @param {PSV.PanoData} [panoData]
   * @param {external:THREE.Mesh} [mesh=this.mesh]
   * @package
   */
  setPanoramaPose(panoData, mesh = this.mesh) {
    if (!isNil(panoData?.poseHeading) || !isNil(panoData?.posePitch) || !isNil(panoData?.poseRoll)) {
      // By Google documentation the angles are applied on the camera in order : heading, pitch, roll
      // here we apply the reverse transformation on the sphere
      mesh.rotation.set(
        -THREE.Math.degToRad(panoData?.posePitch || 0),
        -THREE.Math.degToRad(panoData?.poseHeading || 0),
        -THREE.Math.degToRad(panoData?.poseRoll || 0),
        'ZXY'
      );
    }
    else {
      mesh.rotation.set(0, 0, 0);
    }
  }

  /**
   * @summary Apply a SphereCorrection to a Mesh
   * @param {PSV.SphereCorrection} [sphereCorrection]
   * @param {external:THREE.Mesh} [mesh=this.meshContainer]
   * @package
   */
  setSphereCorrection(sphereCorrection, mesh = this.meshContainer) {
    if (sphereCorrection) {
      const cleanCorrection = this.psv.dataHelper.cleanSphereCorrection(sphereCorrection);

      mesh.rotation.set(
        cleanCorrection.tilt,
        cleanCorrection.pan,
        cleanCorrection.roll,
        'ZXY'
      );
    }
    else {
      mesh.rotation.set(0, 0, 0);
    }
  }

  /**
   * @summary Performs transition between the current and a new texture
   * @param {PSV.TextureData} textureData
   * @param {PSV.PanoramaOptions} options
   * @returns {PSV.Animation}
   * @package
   */
  transition(textureData, options) {
    const positionProvided = isExtendedPosition(options);
    const zoomProvided = 'zoom' in options;

    const group = new THREE.Group();

    const mesh = this.psv.adapter.createMesh(0.5);
    this.psv.adapter.setTexture(mesh, textureData);
    this.psv.adapter.setTextureOpacity(mesh, 0);
    this.setPanoramaPose(options.panoData, mesh);
    this.setSphereCorrection(options.sphereCorrection, group);

    // rotate the new sphere to make the target position face the camera
    if (positionProvided) {
      const cleanPosition = this.psv.dataHelper.cleanPosition(options);
      const currentPosition = this.psv.getPosition();

      // Longitude rotation along the vertical axis
      const verticalAxis = new THREE.Vector3(0, 1, 0);
      group.rotateOnWorldAxis(verticalAxis, cleanPosition.longitude - currentPosition.longitude);

      // Latitude rotation along the camera horizontal axis
      const horizontalAxis = new THREE.Vector3(0, 1, 0).cross(this.camera.getWorldDirection(new THREE.Vector3())).normalize();
      group.rotateOnWorldAxis(horizontalAxis, cleanPosition.latitude - currentPosition.latitude);
    }

    group.add(mesh);
    this.scene.add(group);
    this.psv.needsUpdate();

    return new Animation({
      properties: {
        opacity: { start: 0.0, end: 1.0 },
        zoom   : zoomProvided ? { start: this.psv.getZoomLevel(), end: options.zoom } : undefined,
      },
      duration  : options.transition,
      easing    : 'outCubic',
      onTick    : (properties) => {
        this.psv.adapter.setTextureOpacity(mesh, properties.opacity);

        if (zoomProvided) {
          this.psv.zoom(properties.zoom);
        }

        this.psv.needsUpdate();
      },
    })
      .then(() => {
        // remove temp sphere and transfer the texture to the main sphere
        this.setTexture(textureData);
        this.setPanoramaPose(options.panoData);
        this.setSphereCorrection(options.sphereCorrection);

        this.scene.remove(group);
        mesh.geometry.dispose();
        mesh.geometry = null;

        // actually rotate the camera
        if (positionProvided) {
          this.psv.rotate(options);
        }
      });
  }

  /**
   * @summary Calls `dispose` on all objects and textures
   * @param {external:THREE.Object3D} object
   * @private
   */
  __cleanTHREEScene(object) {
    object.traverse((item) => {
      if (item.geometry) {
        item.geometry.dispose();
      }

      if (item.material) {
        if (Array.isArray(item.material)) {
          item.material.forEach((material) => {
            if (material.map) {
              material.map.dispose();
            }

            material.dispose();
          });
        }
        else {
          if (item.material.map) {
            item.material.map.dispose();
          }

          item.material.dispose();
        }
      }

      if (item.dispose && !(item instanceof THREE.Scene)) {
        item.dispose();
      }

      if (item !== object) {
        this.__cleanTHREEScene(item);
      }
    });
  }

}
<commit_msg>Fix #618 force update when changing fisheye option<commit_after>import * as THREE from 'three';
import { Animation } from '../Animation';
import { EVENTS, SPHERE_RADIUS } from '../data/constants';
import { SYSTEM } from '../data/system';
import { each, isExtendedPosition, isNil } from '../utils';
import { AbstractService } from './AbstractService';

/**
 * @summary Viewer and renderer
 * @extends PSV.services.AbstractService
 * @memberof PSV.services
 */
export class Renderer extends AbstractService {

  /**
   * @param {PSV.Viewer} psv
   */
  constructor(psv) {
    super(psv);

    /**
     * @member {external:THREE.WebGLRenderer}
     * @readonly
     * @protected
     */
    this.renderer = new THREE.WebGLRenderer({ alpha: true });
    this.renderer.setPixelRatio(SYSTEM.pixelRatio);
    this.renderer.domElement.className = 'psv-canvas';

    /**
     * @member {external:THREE.Scene}
     * @readonly
     * @protected
     */
    this.scene = new THREE.Scene();

    /**
     * @member {external:THREE.PerspectiveCamera}
     * @readonly
     * @protected
     */
    this.camera = new THREE.PerspectiveCamera(50, 16 / 9, 1, 2 * SPHERE_RADIUS);

    /**
     * @member {external:THREE.Mesh}
     * @readonly
     * @protected
     */
    this.mesh = this.psv.adapter.createMesh();
    this.mesh.userData = { psvSphere: true };

    /**
     * @member {external:THREE.Group}
     * @readonly
     * @private
     */
    this.meshContainer = new THREE.Group();
    this.meshContainer.add(this.mesh);
    this.scene.add(this.meshContainer);

    /**
     * @member {external:THREE.Raycaster}
     * @readonly
     * @protected
     */
    this.raycaster = new THREE.Raycaster();

    /**
     * @member {number}
     * @private
     */
    this.timestamp = null;

    /**
     * @member {boolean}
     * @private
     */
    this.ready = false;

    /**
     * @member {HTMLElement}
     * @readonly
     * @package
     */
    this.canvasContainer = document.createElement('div');
    this.canvasContainer.className = 'psv-canvas-container';
    this.canvasContainer.style.background = this.psv.config.canvasBackground;
    this.canvasContainer.style.cursor = this.psv.config.mousemove ? 'move' : 'default';
    this.canvasContainer.appendChild(this.renderer.domElement);
    this.psv.container.appendChild(this.canvasContainer);

    psv.on(EVENTS.SIZE_UPDATED, this);
    psv.on(EVENTS.ZOOM_UPDATED, this);
    psv.on(EVENTS.POSITION_UPDATED, this);
    psv.on(EVENTS.CONFIG_CHANGED, this);

    this.hide();
  }

  /**
   * @override
   */
  destroy() {
    // cancel render loop
    this.renderer.setAnimationLoop(null);

    // destroy ThreeJS view
    this.__cleanTHREEScene(this.scene);

    // remove container
    this.psv.container.removeChild(this.canvasContainer);

    delete this.canvasContainer;
    delete this.renderer;
    delete this.scene;
    delete this.camera;
    delete this.mesh;
    delete this.meshContainer;
    delete this.raycaster;

    super.destroy();
  }

  /**
   * @summary Handles events
   * @param {Event} evt
   * @private
   */
  handleEvent(evt) {
    /* eslint-disable */
    switch (evt.type) {
      // @formatter:off
      case EVENTS.SIZE_UPDATED:     this.__onSizeUpdated(); break;
      case EVENTS.ZOOM_UPDATED:     this.__onZoomUpdated(); break;
      case EVENTS.POSITION_UPDATED: this.__onPositionUpdated(); break;
      case EVENTS.CONFIG_CHANGED:
        if (evt.args[0].indexOf('fisheye') !== -1) {
          this.__onPositionUpdated();
        }
        if (evt.args[0].indexOf('mousemove') !== -1) {
          this.canvasContainer.style.cursor = this.psv.config.mousemove ? 'move' : 'default';
        }
        break;
      // @formatter:on
    }
    /* eslint-enable */
  }

  /**
   * @summary Hides the viewer
   */
  hide() {
    this.canvasContainer.style.opacity = 0;
  }

  /**
   * @summary Shows the viewer
   */
  show() {
    this.canvasContainer.style.opacity = 1;
  }

  /**
   * @summary Updates the size of the renderer and the aspect of the camera
   * @private
   */
  __onSizeUpdated() {
    this.renderer.setSize(this.prop.size.width, this.prop.size.height);
    this.camera.aspect = this.prop.aspect;
    this.camera.updateProjectionMatrix();
    this.prop.needsUpdate = true;
  }

  /**
   * @summary Updates the fov of the camera
   * @private
   */
  __onZoomUpdated() {
    this.camera.fov = this.prop.vFov;
    this.camera.updateProjectionMatrix();
    this.prop.needsUpdate = true;
  }

  /**
   * @summary Updates the position of the camera
   * @private
   */
  __onPositionUpdated() {
    this.camera.position.set(0, 0, 0);
    this.camera.lookAt(this.prop.direction);
    if (this.config.fisheye) {
      this.camera.position.copy(this.prop.direction).multiplyScalar(this.config.fisheye / 2).negate();
    }
    this.prop.needsUpdate = true;
  }

  /**
   * @summary Main event loop, calls {@link render} if `prop.needsUpdate` is true
   * @param {number} timestamp
   * @fires PSV.before-render
   * @private
   */
  __renderLoop(timestamp) {
    const elapsed = this.timestamp !== null ? timestamp - this.timestamp : 0;
    this.timestamp = timestamp;

    this.psv.trigger(EVENTS.BEFORE_RENDER, timestamp, elapsed);
    each(this.psv.dynamics, d => d.update(elapsed));

    if (this.prop.needsUpdate) {
      this.render();
      this.prop.needsUpdate = false;
    }
  }

  /**
   * @summary Performs a render
   * @description Do not call this method directly, instead call
   * {@link PSV.Viewer#needsUpdate} on {@link PSV.event:before-render}.
   * @fires PSV.render
   */
  render() {
    this.renderer.render(this.scene, this.camera);
    this.psv.trigger(EVENTS.RENDER);
  }

  /**
   * @summary Applies the texture to the scene, creates the scene if needed
   * @param {PSV.TextureData} textureData
   * @fires PSV.panorama-loaded
   * @package
   */
  setTexture(textureData) {
    this.prop.panoData = textureData.panoData;

    this.psv.adapter.setTexture(this.mesh, textureData);

    if (!this.ready) {
      this.renderer.setAnimationLoop(t => this.__renderLoop(t));
      this.ready = true;
    }

    this.psv.needsUpdate();

    this.psv.trigger(EVENTS.PANORAMA_LOADED);
  }

  /**
   * @summary Apply a panorama data pose to a Mesh
   * @param {PSV.PanoData} [panoData]
   * @param {external:THREE.Mesh} [mesh=this.mesh]
   * @package
   */
  setPanoramaPose(panoData, mesh = this.mesh) {
    if (!isNil(panoData?.poseHeading) || !isNil(panoData?.posePitch) || !isNil(panoData?.poseRoll)) {
      // By Google documentation the angles are applied on the camera in order : heading, pitch, roll
      // here we apply the reverse transformation on the sphere
      mesh.rotation.set(
        -THREE.Math.degToRad(panoData?.posePitch || 0),
        -THREE.Math.degToRad(panoData?.poseHeading || 0),
        -THREE.Math.degToRad(panoData?.poseRoll || 0),
        'ZXY'
      );
    }
    else {
      mesh.rotation.set(0, 0, 0);
    }
  }

  /**
   * @summary Apply a SphereCorrection to a Mesh
   * @param {PSV.SphereCorrection} [sphereCorrection]
   * @param {external:THREE.Mesh} [mesh=this.meshContainer]
   * @package
   */
  setSphereCorrection(sphereCorrection, mesh = this.meshContainer) {
    if (sphereCorrection) {
      const cleanCorrection = this.psv.dataHelper.cleanSphereCorrection(sphereCorrection);

      mesh.rotation.set(
        cleanCorrection.tilt,
        cleanCorrection.pan,
        cleanCorrection.roll,
        'ZXY'
      );
    }
    else {
      mesh.rotation.set(0, 0, 0);
    }
  }

  /**
   * @summary Performs transition between the current and a new texture
   * @param {PSV.TextureData} textureData
   * @param {PSV.PanoramaOptions} options
   * @returns {PSV.Animation}
   * @package
   */
  transition(textureData, options) {
    const positionProvided = isExtendedPosition(options);
    const zoomProvided = 'zoom' in options;

    const group = new THREE.Group();

    const mesh = this.psv.adapter.createMesh(0.5);
    this.psv.adapter.setTexture(mesh, textureData);
    this.psv.adapter.setTextureOpacity(mesh, 0);
    this.setPanoramaPose(options.panoData, mesh);
    this.setSphereCorrection(options.sphereCorrection, group);

    // rotate the new sphere to make the target position face the camera
    if (positionProvided) {
      const cleanPosition = this.psv.dataHelper.cleanPosition(options);
      const currentPosition = this.psv.getPosition();

      // Longitude rotation along the vertical axis
      const verticalAxis = new THREE.Vector3(0, 1, 0);
      group.rotateOnWorldAxis(verticalAxis, cleanPosition.longitude - currentPosition.longitude);

      // Latitude rotation along the camera horizontal axis
      const horizontalAxis = new THREE.Vector3(0, 1, 0).cross(this.camera.getWorldDirection(new THREE.Vector3())).normalize();
      group.rotateOnWorldAxis(horizontalAxis, cleanPosition.latitude - currentPosition.latitude);
    }

    group.add(mesh);
    this.scene.add(group);
    this.psv.needsUpdate();

    return new Animation({
      properties: {
        opacity: { start: 0.0, end: 1.0 },
        zoom   : zoomProvided ? { start: this.psv.getZoomLevel(), end: options.zoom } : undefined,
      },
      duration  : options.transition,
      easing    : 'outCubic',
      onTick    : (properties) => {
        this.psv.adapter.setTextureOpacity(mesh, properties.opacity);

        if (zoomProvided) {
          this.psv.zoom(properties.zoom);
        }

        this.psv.needsUpdate();
      },
    })
      .then(() => {
        // remove temp sphere and transfer the texture to the main sphere
        this.setTexture(textureData);
        this.setPanoramaPose(options.panoData);
        this.setSphereCorrection(options.sphereCorrection);

        this.scene.remove(group);
        mesh.geometry.dispose();
        mesh.geometry = null;

        // actually rotate the camera
        if (positionProvided) {
          this.psv.rotate(options);
        }
      });
  }

  /**
   * @summary Calls `dispose` on all objects and textures
   * @param {external:THREE.Object3D} object
   * @private
   */
  __cleanTHREEScene(object) {
    object.traverse((item) => {
      if (item.geometry) {
        item.geometry.dispose();
      }

      if (item.material) {
        if (Array.isArray(item.material)) {
          item.material.forEach((material) => {
            if (material.map) {
              material.map.dispose();
            }

            material.dispose();
          });
        }
        else {
          if (item.material.map) {
            item.material.map.dispose();
          }

          item.material.dispose();
        }
      }

      if (item.dispose && !(item instanceof THREE.Scene)) {
        item.dispose();
      }

      if (item !== object) {
        this.__cleanTHREEScene(item);
      }
    });
  }

}
<|endoftext|>


<commit_before>/*
 * Copyright 2013 Amadeus s.a.s.
 * 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.
 */

Aria.classDefinition({
    $classpath : "test.aria.widgets.form.autocomplete.expandbutton.test3.ExpandButtonCheck",
    $extends : "aria.jsunit.TemplateTestCase",
    $dependencies : ["aria.core.Timer"],
    $constructor : function () {
        this.$TemplateTestCase.constructor.call(this);
        this.dataModel = {
            value1 : ""
        };
        this.setTestEnv({
            data : this.dataModel
        });
        // this.defaultTestTimeout = 2000;
    },
    $prototype : {

        /**
         * This method is always the first entry point to a template test Start the test by focusing the first field
         */
        runTemplateTest : function () {
            var field = this.getInputField("ac1");
            field.focus();
            aria.core.Timer.addCallback({
                fn : this._downArrow,
                scope : this,
                delay : 25
            });
        },
        _downArrow : function () {
            this.synEvent.type(this.getInputField("ac1"), "[down]", {
                fn : this._addDelay,
                scope : this
            });
        },

        _addDelay : function () {
            aria.core.Timer.addCallback({
                fn : this._checkSelected,
                scope : this,
                delay : 1000
            });
        },

        _checkSelected : function () {
            this.synEvent.type(this.getInputField("ac1"), "[down][down][enter]", {
                fn : this._checkFinalVal,
                scope : this
            });
        },

        _checkFinalVal : function () {
            this.assertTrue(this.getInputField("ac1").value == "Finnair");
            this._finishTest();
        },

        _finishTest : function () {
            this.getInputField("ac1").blur();
            var data = aria.utils.Json.getValue(this.dataModel, "value1");
            this.assertTrue(data.label == "Finnair");
            this.notifyTemplateTestEnd();
        }

    }
});
<commit_msg>fix test.aria.widgets.form.autocomplete.expandbutton.test3.ExpandButtonCheck fails in IE11, mentioned in #950<commit_after>/*
 * Copyright 2013 Amadeus s.a.s.
 * 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.
 */

Aria.classDefinition({
    $classpath : "test.aria.widgets.form.autocomplete.expandbutton.test3.ExpandButtonCheck",
    $extends : "aria.jsunit.RobotTestCase",
    $dependencies : ["aria.core.Timer"],
    $constructor : function () {
        this.$RobotTestCase.constructor.call(this);
        this.dataModel = {
            value1 : ""
        };
        this.setTestEnv({
            data : this.dataModel
        });
        // this.defaultTestTimeout = 2000;
    },
    $prototype : {

        /**
         * This method is always the first entry point to a template test Start the test by focusing the first field
         */
        runTemplateTest : function () {
            var field = this.getInputField("ac1");
            field.focus();
            aria.core.Timer.addCallback({
                fn : this._downArrow,
                scope : this,
                delay : 25
            });
        },

        _downArrow : function () {
            var field = this.getInputField("ac1");
            this.synEvent.execute([["click", field], ["type", field, "[down]"], ["pause", 500],
                    ["type", field, "[down][down]\r"], ["pause", 500]], {
                fn : this._checkFinalVal,
                scope : this
            });
        },

        _checkFinalVal : function () {
            this.assertTrue(this.getInputField("ac1").value == "Finnair");
            this._finishTest();
        },

        _finishTest : function () {
            this.getInputField("ac1").blur();
            var data = aria.utils.Json.getValue(this.dataModel, "value1");
            this.assertTrue(data.label == "Finnair");
            this.notifyTemplateTestEnd();
        }

    }
});
<|endoftext|>


<commit_before>/*global Arenite:true*/
/*jshint evil:true*/
Arenite.DI = function (arenite) {

  var registry = {};
  var factories = {};

  var _resolveFunc = function (execution) {
    var resolvedFunc = execution.func;
    if (typeof execution.func === 'function') {
      resolvedFunc = execution.func;
    } else {
      if (execution.extension) {
        resolvedFunc = arenite.object.get(arenite[execution.instance], execution.func);
      } else {
        resolvedFunc = arenite.object.get(_getInstance(execution.instance), execution.func);
      }
    }
    return resolvedFunc;
  };

  var _resolveArgs = function (execution, done) {
    if (!execution.args) {
      return [];
    }
    var failure = false;
    var resolved = [];
    execution.args.forEach(function (arg) {
      if (typeof arg.value !== 'undefined') {
        resolved.push(arg.value);
      } else if (typeof arg.ref !== 'undefined') {
        var ref = _getInstance(arg.ref);
        if (ref) {
          resolved.push(ref);
        } else {
          failure = true;
        }
      } else if (typeof arg.func !== 'undefined') {
        resolved.push(arg.func);
      } else if (typeof arg.exec !== 'undefined') {
        resolved.push(arg.exec(arenite));
      } else if (typeof arg.instance !== 'undefined') {
        var anonymousContext = {instances: {'__anonymous_temp_instance__': arg.instance}};
        _loadContext(anonymousContext);
        resolved.push(arenite.di.getInstance('__anonymous_temp_instance__'));
        _removeInstance('__anonymous_temp_instance__');
      }
    });

    if (execution.wait && typeof done === 'function') {
      resolved.push(done);
    }
    return failure ? null : resolved;
  };

  var _execFunction = function (execution, before, done) {
    var resolvedFunc = _resolveFunc(execution);
    if (resolvedFunc) {
      var resolvedArgs = _resolveArgs(execution, done);
      if (resolvedArgs) {
        if (execution.wait && typeof before === 'function') {
          before();
        }
        resolvedFunc.apply(resolvedFunc, resolvedArgs);
      } else {
        throw 'Unable to resolve arguments for "' + execution.func + '" of instance "' + execution.instance + '"';
      }
    } else {
      throw 'Unknown function "' + execution.func + '" for instance "' + execution.instance + '"';
    }
  };

  var _addInstance = function (name, instance, factory, args) {
    registry[name] = instance;
    if (factory) {
      factories[name] = args || [];
    }
  };

  var _removeInstance = function (name) {
    arenite.object.delete(registry, name);
  };

  var _getInstance = function (name) {
    if (factories.hasOwnProperty(name)) {
      var args = _resolveArgs({args: factories[name]});
      if (args) {
        return registry[name].apply(registry[name], args);
      } else {
        throw 'Unable to resolve arguments for "' + name + '"';
      }
    } else {
      return registry[name];
    }
  };

  var _wire = function (instances, type) {
    if (!instances) {
      return;
    }

    var instanceKeys = arenite.object.keys(instances);
    var unresolved = {};

    instanceKeys.forEach(function (instance) {
      var func = arenite.object.get(window, instances[instance].namespace);
      if (func) {
        var args = _resolveArgs(instances[instance]);
        if (args) {
          window.console.log('Arenite:', instance, 'wired');
          var actualInstance = instances[instance].factory ? func : func.apply(func, args);
          if (type === 'extension') {
            var wrappedInstance = {};
            wrappedInstance[instance] = actualInstance;
            arenite = arenite.object.extend(arenite, wrappedInstance);
          } else {
            _addInstance(instance, actualInstance, instances[instance].factory, instances[instance].args || []);
          }
        } else {
          unresolved[instance] = instances[instance];
        }
      } else {
        throw 'Unknown function "' + instances[instance].namespace + '"';
      }
    });

    var unresolvedKeys = arenite.object.keys(unresolved);
    if (unresolvedKeys.length !== arenite.object.keys(instances).length && unresolvedKeys.length > 0) {
      _wire(unresolved);
    } else {
      if (unresolvedKeys.length !== 0) {
        throw 'Make sure you don\'t have circular dependencies, Unable to resolve the following instances: ' + unresolvedKeys.join(", ");
      }
    }
  };

  var _init = function (instances, latch, extension) {
    arenite.object.keys(instances).forEach(function (instance) {
      if (instances[instance].init) {
        if (typeof instances[instance].init === 'string') {
          instances[instance].init = {func: instances[instance].init};
        }
        _execFunction(arenite.object.extend({
          instance: instance,
          extension: extension
        }, instances[instance].init), function () {
          latch.countUp();
        }, function () {
          window.console.log('Arenite:', instance, 'initialized');
          latch.countDown();
        });
      }
    });
  };

  var _start = function (starts) {
    if (!starts) {
      return;
    }
    if (document.readyState !== 'complete') {
      window.setTimeout(function () {
        _start(starts);
      }, 100);
    } else {
      starts.forEach(function (start) {
        _execFunction(start);
      });
    }
  };

  var _loadContext = function (context) {
    if (context) {
      //Starting must wait for the wiring
      var wireLatch = arenite.async.latch(1, function () {
        window.console.log('Arenite: start instances');
        _start(context.start);
      }, "instances");

      //wiring of instances must wait for the extensions
      var extensionsLatch = arenite.async.latch(1, function () {
        window.console.log('Arenite: wire instances');
        _wire(context.instances);
        window.console.log('Arenite: init instances');
        _init(context.instances, wireLatch);
        wireLatch.countDown();
      }, "extensions");

      window.console.log('Arenite: wire extensions');
      _wire(context.extensions, 'extension');
      window.console.log('Arenite: init extensions');
      _init(context.extensions, extensionsLatch, true);
      extensionsLatch.countDown();
    }
  };

  var _loadAsyncDependencies = function (dependencies) {
    var latch = arenite.async.latch(dependencies.async ? dependencies.async.length : 0, function () {
      _loadContext(arenite.config.context);
    }, 'dependencies');
    dependencies.async.forEach(function (dep) {
      arenite.loader.loadScript(dep, latch.countDown);
    });
  };

  var _loadSyncDependencies = function () {
    if (!arenite.config.context || !arenite.config.context.dependencies) {
      return _loadContext();
    }

    var dependencies;
    if (!arenite.config.context.dependencies[arenite.config.mode]) {
      dependencies = {sync: [], async: []};
    } else {
      dependencies = arenite.config.context.dependencies[arenite.config.mode];
    }

    var seqLatch = arenite.async.seqLatch(dependencies.sync || [], function (url) {
      arenite.loader.loadScript(url, seqLatch.next);
    }, function () {
      _loadAsyncDependencies(dependencies);
    });
    seqLatch.next();
  };

  var _mergeImports = function (imports) {
    var imp = imports.pop();
    var unloadedImports = [];

    while (imp) {
      if (!arenite.object.get(window, imp.namespace)) {
        unloadedImports.push(imp);
      } else {
        arenite.config = arenite.object.extend(arenite.config, arenite.object.get(window, imp.namespace)());
      }
      imp = imports.pop();
    }

    if (unloadedImports.length !== 0) {
      var latch = arenite.async.latch(unloadedImports.length, function () {
        _mergeImports(unloadedImports);
      }, 'imports');
      unloadedImports.forEach(function (subImp) {
        arenite.loader.loadScript(subImp.url, latch.countDown);
      });
    } else {
      _loadSyncDependencies();
    }
  };

  var _loadConfig = function (config) {
    _addInstance('arenite', arenite);
    arenite.config = config;
    arenite.config.mode = arenite.url.query().env || 'default';
    window.console.log('Arenite: Starting in mode', arenite.config.mode);
    if (config.expose) {
      window.arenite = arenite;
    }

    if (arenite.config.imports) {
      _mergeImports(JSON.parse(JSON.stringify(arenite.config.imports)));
    } else {
      _loadSyncDependencies();
    }
  };

  var _processAnnotations = function (text) {
    var regex = /@arenite-instance\s+["']([^"']+)["']\s*(.*);\s*(@arenite-init\s+["']([^"']+)["']\s*(.*);)*\s*(@arenite-start\s+["']([^"']+)["']\s*(.*);)*\s*\*\/\s*([\w.]+)/g;
    var match;
    while ((match = regex.exec(text))) {
      _processAnnotation(match);
    }
  };

  var _processArgAnnotation = function (match) {
    var args = [];
    var split = match.split(',');
    split.forEach(function (arg) {
      var argPair = arg.split(":");
      var argObj = {};
      argObj[argPair[0].trim()] = argPair[0].trim() === 'ref' ? argPair[1].trim() : eval(argPair[1].trim());
      args.push(argObj);
    });
    return args;
  };

  var _processAnnotation = function (match) {
    var instanceName = match[1];
    var namespace = match[9];

    if (!instanceName) {
      return;
    }
    if (!arenite.config.context) {
      arenite.config.context = {instances: {}};
    }

    //instance
    arenite.config.context.instances[instanceName] = {namespace: namespace};
    if (match[2]) {
      arenite.config.context.instances[instanceName].args = _processArgAnnotation(match[2]);
    }

    // init
    if (match[4]) {
      arenite.config.context.instances[instanceName].init = {func: match[4]};
      if (match[5]) {
        arenite.config.context.instances[instanceName].init.args = _processArgAnnotation(match[5]);
      }
    }

    // start
    if (match[7]) {
      var start = {instance: instanceName, func: match[7]};
      if (match[8]) {
        start.args = _processArgAnnotation(match[8]);
      }
      if (!arenite.config.context.start) {
        arenite.config.context.start = [];
      }
      arenite.config.context.start.push(start);
    }
  };

  return {
    di: {
      loadConfig: _loadConfig,
      getInstance: _getInstance,
      addInstance: _addInstance,
      processAnnotations: _processAnnotations
    }
  };
};<commit_msg>made the anonymous temp id unique so that nested anonymous instances don't override the first one.<commit_after>/*global Arenite:true*/
/*jshint evil:true*/
Arenite.DI = function (arenite) {

  var registry = {};
  var factories = {};

  var _resolveFunc = function (execution) {
    var resolvedFunc = execution.func;
    if (typeof execution.func === 'function') {
      resolvedFunc = execution.func;
    } else {
      if (execution.extension) {
        resolvedFunc = arenite.object.get(arenite[execution.instance], execution.func);
      } else {
        resolvedFunc = arenite.object.get(_getInstance(execution.instance), execution.func);
      }
    }
    return resolvedFunc;
  };

  var _resolveArgs = function (execution, done) {
    if (!execution.args) {
      return [];
    }
    var failure = false;
    var resolved = [];
    execution.args.forEach(function (arg) {
      if (typeof arg.value !== 'undefined') {
        resolved.push(arg.value);
      } else if (typeof arg.ref !== 'undefined') {
        var ref = _getInstance(arg.ref);
        if (ref) {
          resolved.push(ref);
        } else {
          failure = true;
        }
      } else if (typeof arg.func !== 'undefined') {
        resolved.push(arg.func);
      } else if (typeof arg.exec !== 'undefined') {
        resolved.push(arg.exec(arenite));
      } else if (typeof arg.instance !== 'undefined') {
        var anonymousContext = {instances: {}};
        var tempId = '__anonymous_temp_instance__' + new Date().getTime();
        anonymousContext.instances[tempId] = arg.instance;
        _loadContext(anonymousContext);
        resolved.push(arenite.di.getInstance(tempId));
        _removeInstance(tempId);
      }
    });

    if (execution.wait && typeof done === 'function') {
      resolved.push(done);
    }
    return failure ? null : resolved;
  };

  var _execFunction = function (execution, before, done) {
    var resolvedFunc = _resolveFunc(execution);
    if (resolvedFunc) {
      var resolvedArgs = _resolveArgs(execution, done);
      if (resolvedArgs) {
        if (execution.wait && typeof before === 'function') {
          before();
        }
        resolvedFunc.apply(resolvedFunc, resolvedArgs);
      } else {
        throw 'Unable to resolve arguments for "' + execution.func + '" of instance "' + execution.instance + '"';
      }
    } else {
      throw 'Unknown function "' + execution.func + '" for instance "' + execution.instance + '"';
    }
  };

  var _addInstance = function (name, instance, factory, args) {
    registry[name] = instance;
    if (factory) {
      factories[name] = args || [];
    }
  };

  var _removeInstance = function (name) {
    arenite.object.delete(registry, name);
  };

  var _getInstance = function (name) {
    if (factories.hasOwnProperty(name)) {
      var args = _resolveArgs({args: factories[name]});
      if (args) {
        return registry[name].apply(registry[name], args);
      } else {
        throw 'Unable to resolve arguments for "' + name + '"';
      }
    } else {
      return registry[name];
    }
  };

  var _wire = function (instances, type) {
    if (!instances) {
      return;
    }

    var instanceKeys = arenite.object.keys(instances);
    var unresolved = {};

    instanceKeys.forEach(function (instance) {
      var func = arenite.object.get(window, instances[instance].namespace);
      if (func) {
        var args = _resolveArgs(instances[instance]);
        if (args) {
          window.console.log('Arenite:', instance, 'wired');
          var actualInstance = instances[instance].factory ? func : func.apply(func, args);
          if (type === 'extension') {
            var wrappedInstance = {};
            wrappedInstance[instance] = actualInstance;
            arenite = arenite.object.extend(arenite, wrappedInstance);
          } else {
            _addInstance(instance, actualInstance, instances[instance].factory, instances[instance].args || []);
          }
        } else {
          unresolved[instance] = instances[instance];
        }
      } else {
        throw 'Unknown function "' + instances[instance].namespace + '"';
      }
    });

    var unresolvedKeys = arenite.object.keys(unresolved);
    if (unresolvedKeys.length !== arenite.object.keys(instances).length && unresolvedKeys.length > 0) {
      _wire(unresolved);
    } else {
      if (unresolvedKeys.length !== 0) {
        throw 'Make sure you don\'t have circular dependencies, Unable to resolve the following instances: ' + unresolvedKeys.join(", ");
      }
    }
  };

  var _init = function (instances, latch, extension) {
    arenite.object.keys(instances).forEach(function (instance) {
      if (instances[instance].init) {
        if (typeof instances[instance].init === 'string') {
          instances[instance].init = {func: instances[instance].init};
        }
        _execFunction(arenite.object.extend({
          instance: instance,
          extension: extension
        }, instances[instance].init), function () {
          latch.countUp();
        }, function () {
          window.console.log('Arenite:', instance, 'initialized');
          latch.countDown();
        });
      }
    });
  };

  var _start = function (starts) {
    if (!starts) {
      return;
    }
    if (document.readyState !== 'complete') {
      window.setTimeout(function () {
        _start(starts);
      }, 100);
    } else {
      starts.forEach(function (start) {
        _execFunction(start);
      });
    }
  };

  var _loadContext = function (context) {
    if (context) {
      //Starting must wait for the wiring
      var wireLatch = arenite.async.latch(1, function () {
        window.console.log('Arenite: start instances');
        _start(context.start);
      }, "instances");

      //wiring of instances must wait for the extensions
      var extensionsLatch = arenite.async.latch(1, function () {
        window.console.log('Arenite: wire instances');
        _wire(context.instances);
        window.console.log('Arenite: init instances');
        _init(context.instances, wireLatch);
        wireLatch.countDown();
      }, "extensions");

      window.console.log('Arenite: wire extensions');
      _wire(context.extensions, 'extension');
      window.console.log('Arenite: init extensions');
      _init(context.extensions, extensionsLatch, true);
      extensionsLatch.countDown();
    }
  };

  var _loadAsyncDependencies = function (dependencies) {
    var latch = arenite.async.latch(dependencies.async ? dependencies.async.length : 0, function () {
      _loadContext(arenite.config.context);
    }, 'dependencies');
    dependencies.async.forEach(function (dep) {
      arenite.loader.loadScript(dep, latch.countDown);
    });
  };

  var _loadSyncDependencies = function () {
    if (!arenite.config.context || !arenite.config.context.dependencies) {
      return _loadContext();
    }

    var dependencies;
    if (!arenite.config.context.dependencies[arenite.config.mode]) {
      dependencies = {sync: [], async: []};
    } else {
      dependencies = arenite.config.context.dependencies[arenite.config.mode];
    }

    var seqLatch = arenite.async.seqLatch(dependencies.sync || [], function (url) {
      arenite.loader.loadScript(url, seqLatch.next);
    }, function () {
      _loadAsyncDependencies(dependencies);
    });
    seqLatch.next();
  };

  var _mergeImports = function (imports) {
    var imp = imports.pop();
    var unloadedImports = [];

    while (imp) {
      if (!arenite.object.get(window, imp.namespace)) {
        unloadedImports.push(imp);
      } else {
        arenite.config = arenite.object.extend(arenite.config, arenite.object.get(window, imp.namespace)());
      }
      imp = imports.pop();
    }

    if (unloadedImports.length !== 0) {
      var latch = arenite.async.latch(unloadedImports.length, function () {
        _mergeImports(unloadedImports);
      }, 'imports');
      unloadedImports.forEach(function (subImp) {
        arenite.loader.loadScript(subImp.url, latch.countDown);
      });
    } else {
      _loadSyncDependencies();
    }
  };

  var _loadConfig = function (config) {
    _addInstance('arenite', arenite);
    arenite.config = config;
    arenite.config.mode = arenite.url.query().env || 'default';
    window.console.log('Arenite: Starting in mode', arenite.config.mode);
    if (config.expose) {
      window.arenite = arenite;
    }

    if (arenite.config.imports) {
      _mergeImports(JSON.parse(JSON.stringify(arenite.config.imports)));
    } else {
      _loadSyncDependencies();
    }
  };

  var _processAnnotations = function (text) {
    var regex = /@arenite-instance\s+["']([^"']+)["']\s*(.*);\s*(@arenite-init\s+["']([^"']+)["']\s*(.*);)*\s*(@arenite-start\s+["']([^"']+)["']\s*(.*);)*\s*\*\/\s*([\w.]+)/g;
    var match;
    while ((match = regex.exec(text))) {
      _processAnnotation(match);
    }
  };

  var _processArgAnnotation = function (match) {
    var args = [];
    var split = match.split(',');
    split.forEach(function (arg) {
      var argPair = arg.split(":");
      var argObj = {};
      argObj[argPair[0].trim()] = argPair[0].trim() === 'ref' ? argPair[1].trim() : eval(argPair[1].trim());
      args.push(argObj);
    });
    return args;
  };

  var _processAnnotation = function (match) {
    var instanceName = match[1];
    var namespace = match[9];

    if (!instanceName) {
      return;
    }
    if (!arenite.config.context) {
      arenite.config.context = {instances: {}};
    }

    //instance
    arenite.config.context.instances[instanceName] = {namespace: namespace};
    if (match[2]) {
      arenite.config.context.instances[instanceName].args = _processArgAnnotation(match[2]);
    }

    // init
    if (match[4]) {
      arenite.config.context.instances[instanceName].init = {func: match[4]};
      if (match[5]) {
        arenite.config.context.instances[instanceName].init.args = _processArgAnnotation(match[5]);
      }
    }

    // start
    if (match[7]) {
      var start = {instance: instanceName, func: match[7]};
      if (match[8]) {
        start.args = _processArgAnnotation(match[8]);
      }
      if (!arenite.config.context.start) {
        arenite.config.context.start = [];
      }
      arenite.config.context.start.push(start);
    }
  };

  return {
    di: {
      loadConfig: _loadConfig,
      getInstance: _getInstance,
      addInstance: _addInstance,
      processAnnotations: _processAnnotations
    }
  };
};<|endoftext|>


<commit_before>Parse.initialize("7YyZO6oZNVongKR6pluyULEkMEmvLVRtVZvd6OXn", "JTOrsTnWqTBhxqxFMEvPdOUzDd9Ro01JqpiAF003");
window.fbAsyncInit = function() {
      Parse.FacebookUtils.init({ // this line replaces FB.init({
            appId      : '971388552927772', // Facebook App ID
            status     : true,  // check Facebook Login status
            cookie     : true,  // enable cookies to allow Parse to access the session
            xfbml      : true,  // initialize Facebook social plugins on the page
            version    : 'v2.5' // point to the latest Facebook Graph API version
      });

  // Run code after the Facebook SDK is loaded
  FB.getLoginStatus(function(response) {
    if (response.status === 'connected') {
            getUserName()
            document.getElementById("lgn-btn").style.display="none";
            document.getElementById("lgot-btn").style.display="block";
    }
    else if (response.status === 'not_authorized') {
            getUserName()
            document.getElementById("lgn-btn").style.display="none";
            document.getElementById("lgot-btn").style.display="block";
    }
});
};

function checkLoginState() {
      if (typeof FB !== 'undefined') {
            Parse.FacebookUtils.logIn("email", {
                  success: function(user) {
                        if (!user.existed()) {
                              //alert("User signed up and logged in through Facebook!");
                              getUserName()
                              document.getElementById("lgn-btn").style.display="none";
                              document.getElementById("lgot-btn").style.display="block";
                        } else {
                              //alert("User logged in through Facebook!");
                              getUserName()
                              document.getElementById("lgn-btn").style.display="none";
                              document.getElementById("lgot-btn").style.display="block";
                        }
                  },
                  error: function(user, error) {
                        alert("Please login to access the Locaholic services!!");
                  }
            },{scope:"email"});
      }
      else{
            alert("Your network does not support FaceBook Login!!")
      }
}

function getUserName() {
	FB.api('/me?fields=id,first_name,last_name,email,gender,picture', function(response) {
		document.getElementById('usrname').innerHTML = '';
		//document.getElementById('usrname').innerHTML = Parse.User.current().id + response.id + "A";
		var user = Parse.User.current();
		var firstName = user.get('firstName');
		if(typeof firsttName === 'undefined')
	    	{
	    		alert("user undefined adding him!!!");
			var usr       = Parse.Object.extend("User");
			var query     = new Parse.Query(usr);
			var uid       = Parse.User.current().id;
			var firstname = response.first_name;
			var lastname  = response.last_name;
			var gender    = response.gender;
			var email     = response.email;
			var fbid      = response.id;
			var pic       = "http://graph.facebook.com/" + response.id + "/picture";
			query.equalTo("objectId", uid);
			query.first({
				success: function(Usrobj){
				//	alert (uid+" "+firstname+" "+lastname+" "+gender+" "+email+" "+fbid+" "+pic);
					Usrobj.set("fbId", fbid);
					Usrobj.set("firstName", firstname);
					Usrobj.set("lastName", lastname);
					if(gender)
					{
						Usrobj.set("gender", gender);
					}
					if(pic)
					{
						Usrobj.set("userImg", pic);
					}
					if(email)
					{
						Usrobj.set("email", email);
					}
					Usrobj.save({
						success: function(){
							alert("success saved");
						},error: function(error){
							alert("saving failed error " + error.message);
						}
					});
				},
				error: function(error){
					alert("query first error " +error.message);
				}

			});
		}
	});
}
function lgOut(){
      //alert(Parse.User.current().id);
      Parse.User.logOut();
      FB.logout();
      window.location.href = "http://www.locaholic.co/";
}

(function(d, s, id){
      var js, fjs = d.getElementsByTagName(s)[0];
      if (d.getElementById(id)) {return;}
      js = d.createElement(s); js.id = id;
      js.src = "//connect.facebook.net/en_US/sdk.js";
      fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
<commit_msg>Update fb.js<commit_after>Parse.initialize("7YyZO6oZNVongKR6pluyULEkMEmvLVRtVZvd6OXn", "JTOrsTnWqTBhxqxFMEvPdOUzDd9Ro01JqpiAF003");
window.fbAsyncInit = function() {
      Parse.FacebookUtils.init({ // this line replaces FB.init({
            appId      : '971388552927772', // Facebook App ID
            status     : true,  // check Facebook Login status
            cookie     : true,  // enable cookies to allow Parse to access the session
            xfbml      : true,  // initialize Facebook social plugins on the page
            version    : 'v2.5' // point to the latest Facebook Graph API version
      });

  // Run code after the Facebook SDK is loaded
  FB.getLoginStatus(function(response) {
    if (response.status === 'connected') {
            getUserName()
            document.getElementById("lgn-btn").style.display="none";
            document.getElementById("lgot-btn").style.display="block";
    }
    else if (response.status === 'not_authorized') {
            getUserName()
            document.getElementById("lgn-btn").style.display="none";
            document.getElementById("lgot-btn").style.display="block";
    }
});
};

function checkLoginState() {
      if (typeof FB !== 'undefined') {
            Parse.FacebookUtils.logIn("email", {
                  success: function(user) {
                        if (!user.existed()) {
                              //alert("User signed up and logged in through Facebook!");
                              getUserName()
                              document.getElementById("lgn-btn").style.display="none";
                              document.getElementById("lgot-btn").style.display="block";
                        } else {
                              //alert("User logged in through Facebook!");
                              getUserName()
                              document.getElementById("lgn-btn").style.display="none";
                              document.getElementById("lgot-btn").style.display="block";
                        }
                  },
                  error: function(user, error) {
                        alert("Please login to access the Locaholic services!!");
                  }
            },{scope:"email"});
      }
      else{
            alert("Your network does not support FaceBook Login!!")
      }
}

function getUserName() {
	FB.api('/me?fields=id,first_name,last_name,email,gender,picture', function(response) {
		document.getElementById('usrname').innerHTML = '';
		//document.getElementById('usrname').innerHTML = Parse.User.current().id + response.id + "A";
		var user = Parse.User.current();
		var firstName = user.get('firstName');
		if(typeof firstName === 'undefined')
	    	{
	    		alert("user undefined adding him!!!");
			var usr       = Parse.Object.extend("User");
			var query     = new Parse.Query(usr);
			var uid       = Parse.User.current().id;
			var firstname = response.first_name;
			var lastname  = response.last_name;
			var gender    = response.gender;
			var email     = response.email;
			var fbid      = response.id;
			var pic       = "http://graph.facebook.com/" + response.id + "/picture";
			query.equalTo("objectId", uid);
			query.first({
				success: function(Usrobj){
				//	alert (uid+" "+firstname+" "+lastname+" "+gender+" "+email+" "+fbid+" "+pic);
					Usrobj.set("fbId", fbid);
					Usrobj.set("firstName", firstname);
					Usrobj.set("lastName", lastname);
					if(gender)
					{
						Usrobj.set("gender", gender);
					}
					if(pic)
					{
						Usrobj.set("userImg", pic);
					}
					if(email)
					{
						Usrobj.set("email", email);
					}
					Usrobj.save({
						success: function(){
							alert("success saved");
						},error: function(error){
							alert("saving failed error " + error.message);
						}
					});
				},
				error: function(error){
					alert("query first error " +error.message);
				}

			});
		}
	});
}
function lgOut(){
      //alert(Parse.User.current().id);
      Parse.User.logOut();
      FB.logout();
      window.location.href = "http://www.locaholic.co/";
}

(function(d, s, id){
      var js, fjs = d.getElementsByTagName(s)[0];
      if (d.getElementById(id)) {return;}
      js = d.createElement(s); js.id = id;
      js.src = "//connect.facebook.net/en_US/sdk.js";
      fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
<|endoftext|>