<commit_before>/* ========================================================================
 * Bootstrap: collapse.js v3.0.0
 * http://twbs.github.com/bootstrap/javascript.html#collapse
 * ========================================================================
 * Copyright 2012 Twitter, Inc.
 *
 * 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.
 * ======================================================================== */

+function ($) { "use strict";

  // COLLAPSE PUBLIC CLASS DEFINITION
  // ================================

  var Collapse = function (element, options) {
    this.$element      = $(element)
    this.options       = $.extend({}, Collapse.DEFAULTS, options)
    this.transitioning = null

    if (this.options.parent) this.$parent = $(this.options.parent)
    if (this.options.toggle) this.toggle()
  }

  Collapse.DEFAULTS = {
    toggle: true
  }

  Collapse.prototype.dimension = function () {
    var hasWidth = this.$element.hasClass('width')
    return hasWidth ? 'width' : 'height'
  }

  Collapse.prototype.show = function () {
    if (this.transitioning || this.$element.hasClass('in')) return

    var startEvent = $.Event('show.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return

    var actives = this.$parent && this.$parent.find('> .accordion-group > .in')

    if (actives && actives.length) {
      var hasData = actives.data('bs.collapse')
      if (hasData && hasData.transitioning) return
      actives.collapse('hide')
      hasData || actives.data('bs.collapse', null)
    }

    var dimension = this.dimension()

    this.$element
      .removeClass('collapse')
      .addClass('collapsing')
      [dimension](0)

    this.transitioning = 1

    var complete = function () {
      this.$element
        .removeClass('collapsing')
        .addClass('in')
        [dimension]('auto')
      this.transitioning = 0
      this.$element.trigger('shown.bs.collapse')
    }

    if (!$.support.transition) return complete.call(this)

    var scrollSize = $.camelCase(['scroll', dimension].join('-'))

    this.$element
      .one($.support.transition.end, $.proxy(complete, this))
      .emulateTransitionEnd(350)
      [dimension](this.$element[0][scrollSize])
  }

  Collapse.prototype.hide = function () {
    if (this.transitioning || !this.$element.hasClass('in')) return

    var startEvent = $.Event('hide.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return

    var dimension = this.dimension()

    this.$element
      [dimension](this.$element[dimension]())
      [0].offsetHeight

    this.$element
      .addClass('collapsing')
      .removeClass('collapse')
      .removeClass('in')

    this.transitioning = 1

    var complete = function () {
      this.transitioning = 0
      this.$element
        .trigger('hidden.bs.collapse')
        .removeClass('collapsing')
        .addClass('collapse')
    }

    if (!$.support.transition) return complete.call(this)

    this.$element
      [dimension](0)
      .one($.support.transition.end, $.proxy(complete, this))
      .emulateTransitionEnd(350)
  }

  Collapse.prototype.toggle = function () {
    this[this.$element.hasClass('in') ? 'hide' : 'show']()
  }

  // COLLAPSE PLUGIN DEFINITION
  // ==========================

  var old = $.fn.collapse

  $.fn.collapse = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.collapse')
      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)

      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.collapse.Constructor = Collapse

  // COLLAPSE NO CONFLICT
  // ====================

  $.fn.collapse.noConflict = function () {
    $.fn.collapse = old
    return this
  }

  // COLLAPSE DATA-API
  // =================

  $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {
    var $this   = $(this), href
    var target  = $this.attr('data-target')
        || e.preventDefault()
        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
    var $target = $(target)
    var data    = $target.data('bs.collapse')
    var option  = data ? 'toggle' : $this.data()
    var parent  = $this.attr('data-parent')
    var $parent = parent && $(parent)

    if (!data || !data.transitioning) {
      if ($parent) $parent.find('[data-toggle=collapse][data-parent=' + parent + ']').not($this).addClass('collapsed')
      $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
    }

    $target.collapse(option)
  })

}(window.jQuery);
<commit_msg>use quotes to allow dots in data-parent<commit_after>/* ========================================================================
 * Bootstrap: collapse.js v3.0.0
 * http://twbs.github.com/bootstrap/javascript.html#collapse
 * ========================================================================
 * Copyright 2012 Twitter, Inc.
 *
 * 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.
 * ======================================================================== */

+function ($) { "use strict";

  // COLLAPSE PUBLIC CLASS DEFINITION
  // ================================

  var Collapse = function (element, options) {
    this.$element      = $(element)
    this.options       = $.extend({}, Collapse.DEFAULTS, options)
    this.transitioning = null

    if (this.options.parent) this.$parent = $(this.options.parent)
    if (this.options.toggle) this.toggle()
  }

  Collapse.DEFAULTS = {
    toggle: true
  }

  Collapse.prototype.dimension = function () {
    var hasWidth = this.$element.hasClass('width')
    return hasWidth ? 'width' : 'height'
  }

  Collapse.prototype.show = function () {
    if (this.transitioning || this.$element.hasClass('in')) return

    var startEvent = $.Event('show.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return

    var actives = this.$parent && this.$parent.find('> .accordion-group > .in')

    if (actives && actives.length) {
      var hasData = actives.data('bs.collapse')
      if (hasData && hasData.transitioning) return
      actives.collapse('hide')
      hasData || actives.data('bs.collapse', null)
    }

    var dimension = this.dimension()

    this.$element
      .removeClass('collapse')
      .addClass('collapsing')
      [dimension](0)

    this.transitioning = 1

    var complete = function () {
      this.$element
        .removeClass('collapsing')
        .addClass('in')
        [dimension]('auto')
      this.transitioning = 0
      this.$element.trigger('shown.bs.collapse')
    }

    if (!$.support.transition) return complete.call(this)

    var scrollSize = $.camelCase(['scroll', dimension].join('-'))

    this.$element
      .one($.support.transition.end, $.proxy(complete, this))
      .emulateTransitionEnd(350)
      [dimension](this.$element[0][scrollSize])
  }

  Collapse.prototype.hide = function () {
    if (this.transitioning || !this.$element.hasClass('in')) return

    var startEvent = $.Event('hide.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return

    var dimension = this.dimension()

    this.$element
      [dimension](this.$element[dimension]())
      [0].offsetHeight

    this.$element
      .addClass('collapsing')
      .removeClass('collapse')
      .removeClass('in')

    this.transitioning = 1

    var complete = function () {
      this.transitioning = 0
      this.$element
        .trigger('hidden.bs.collapse')
        .removeClass('collapsing')
        .addClass('collapse')
    }

    if (!$.support.transition) return complete.call(this)

    this.$element
      [dimension](0)
      .one($.support.transition.end, $.proxy(complete, this))
      .emulateTransitionEnd(350)
  }

  Collapse.prototype.toggle = function () {
    this[this.$element.hasClass('in') ? 'hide' : 'show']()
  }

  // COLLAPSE PLUGIN DEFINITION
  // ==========================

  var old = $.fn.collapse

  $.fn.collapse = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.collapse')
      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)

      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.collapse.Constructor = Collapse

  // COLLAPSE NO CONFLICT
  // ====================

  $.fn.collapse.noConflict = function () {
    $.fn.collapse = old
    return this
  }

  // COLLAPSE DATA-API
  // =================

  $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {
    var $this   = $(this), href
    var target  = $this.attr('data-target')
        || e.preventDefault()
        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
    var $target = $(target)
    var data    = $target.data('bs.collapse')
    var option  = data ? 'toggle' : $this.data()
    var parent  = $this.attr('data-parent')
    var $parent = parent && $(parent)

    if (!data || !data.transitioning) {
      if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed')
      $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
    }

    $target.collapse(option)
  })

}(window.jQuery);
<|endoftext|>


<commit_before>module.exports = function() {

  var Leap = require('leapjs');
  var sphero = require("sphero");

  // Set this to the device Sphero connects as on your computer.
  var device = sphero("/dev/tty.Sphero-RBR-AMP-SPP");

  var safeMode = true; //Turn this off if Sphero is in water or you like to live dangerously!

  var controlSphero = function(spheroBall) {

      var controller = Leap.loop({frameEventName:'deviceFrame', enableGestures:true});

      controller.on('connect', function() {
      	console.log('connected to leap motion');
      });
      controller.on('ready', function() {
          console.log('ready');
      });
      controller.on('focus', function() {
          console.log('focus?');
      });
      controller.on('deviceStreaming', function() {
          console.log('device connected');
      });
      controller.on('deviceStopped', function() {
          console.log('device disconnected');
      });
      controller.on('frame', function(frame) {
        // if(frame.valid && frame.gestures.length > 0){
          // frame.gestures.forEach(function(gesture){
            // if(gesture.type == 'swipe'){
              if(frame.hands[0]){
                var g = frame.hands[0];
                handleSwipe(g);
              }
            // }
          // });
        // }
      });

      var handleSwipe = function(g) {
        // var g = frame.hands[0];
            var previousFrame = controller.frame(1);
            var movement = g.translation(previousFrame);
            var direction = '?';

            if(movement[0] > 4){
              direction = 'RIGHT'
            } else if(movement[0] < -4){
               direction = 'LEFT'
            }

            if(movement[1] > 4){
              direction = 'UP'
            } else if(movement[1] < -4){
              direction = 'DOWN'
            }

            if(movement[2] > 4){
              direction = 'REVERSE'
            } else if(movement[2] < -4){
              direction = 'FORWARD'
            }

          switch (direction) {
            // Original settings included: 'sphero.heading = (heading value)';
            // Original speed for all of them: 128.
            case 'LEFT':
              console.log('left')
              //sphero.roll(speed, heading, state, option)
              spheroBall.roll(70, 270, 1); //Heading is expressed in degrees so 270 will make the ball move to the left.
              break;
            case 'RIGHT':
              spheroBall.heading = 90;
              spheroBall.roll(70, 90, 1);
              break;
            case 'UP':
              stopSphero(spheroBall);
              console.log('up')
              //Make the ball turn blue when users move their hand up.
              // ball.setRGB(spheron.toolbelt.COLORS.BLUE).setBackLED(255);
              break;
            case 'DOWN':
              stopSphero(spheroBall);
              //Make the ball turn white when users move their hand down.
               // ball.setRGB(spheron.toolbelt.COLORS.WHITE).setBackLED(255);
              break;
            case 'FORWARD':
               spheroBall.roll(70, 0, 1);
              break;
            case 'REVERSE':
              spheroBall.heading = 180;
              spheroBall.roll(70, 180, 1);
              break;

              /*--------------
                If you want to add a delay between each action, add this in each case,
                just before the break to add a 2s delay.

                if (safeMode) {
                 setTimeout(function() {
                   stopSphero(sphero);
                 }, 2000);
              }
              ---------------*/
          }
      	console.log('Direction: %s', direction);
      }

        controller.connect();
        console.log('waiting for Leap Motion connection...');
      };

  // Stops the Sphero from rolling.
  var stopSphero = function(spheroBall) {
      spheroBall.roll(0,spheroBall.heading||0,0);
  };

  console.log("waiting for Sphero connection...");

  device.connect(function() {
  	console.log('connected to Sphero');
      // ball.setRGB(spheron.toolbelt.COLORS.PURPLE).setBackLED(255);
      controlSphero(device);
  });

};
<commit_msg>Refactor sphero module<commit_after>module.exports = function() {

  var Leap = require('leapjs');
  var sphero = require("sphero");

  // Set this to the port the Sphero uses on your computer.
  var device = sphero("/dev/tty.Sphero-RBR-AMP-SPP");

  var safeMode = true; //Turn this off if Sphero is in water or you like to live dangerously!

  var controlSphero = function(spheroBall) {

      var controller = Leap.loop({frameEventName:'deviceFrame', enableGestures:true});

      controller.on('connect', function() {
      	console.log('connected to leap motion');
      });
      controller.on('ready', function() {
          console.log('ready');
      });
      controller.on('deviceStreaming', function() {
          console.log('device connected');
      });
      controller.on('deviceStopped', function() {
          console.log('device disconnected');
      });
      controller.on('frame', function(frame) {
        if(frame.hands[0]){
          var gesture = frame.hands[0];
          handleSwipe(gesture);
        }
      });

      var handleSwipe = function(gesture) {
        var previousFrame = controller.frame(1);
        var movement = gesture.translation(previousFrame);
        var direction = '?';

        if(movement[0] > 4){
          direction = 'RIGHT'
        } else if(movement[0] < -4){
          direction = 'LEFT'
        }

        if(movement[1] > 4){
          direction = 'UP'
        } else if(movement[1] < -4){
          direction = 'DOWN'
        }

        if(movement[2] > 4){
          direction = 'REVERSE'
        } else if(movement[2] < -4){
          direction = 'FORWARD'
        }

        switch (direction) {
          case 'LEFT':
            //sphero.roll(speed, heading, state, option). Heading is expressed in degrees.
            spheroBall.roll(70, 270, 1);
            break;
          case 'RIGHT':
            spheroBall.heading = 90;
            spheroBall.roll(70, 90, 1);
            break;
          case 'UP':
            stopSphero(spheroBall);
            break;
          case 'DOWN':
            stopSphero(spheroBall);
            break;
          case 'FORWARD':
             spheroBall.roll(70, 0, 1);
            break;
          case 'REVERSE':
            spheroBall.heading = 180;
            spheroBall.roll(70, 180, 1);
            break;
        }
      	console.log('Direction: ', direction);
      }

      controller.connect();
      console.log('waiting for Leap Motion connection...');
      };

  var stopSphero = function(spheroBall) {
    spheroBall.roll(0,spheroBall.heading||0,0);
  };

  console.log("waiting for Sphero connection...");

  device.connect(function() {
  	console.log('connected to Sphero');
    device.setRGB(spheron.toolbelt.COLORS.PURPLE).setBackLED(255);
    controlSphero(device);
  });

};
<|endoftext|>


<commit_before>import canParse from "./canParse";
import Class from "../Class";
import create from "./create";
import del from "./delete";
import fetch from "./fetch";
import Metadata from "../metadata/Metadata";
import read from "./read";
import update from "./update";
import WebAPI from "../webapi/WebAPI";

class Entity extends canParse(create(del(fetch(read(update(Class)))))) {
    constructor(data, logicalName) {
        super(...arguments);
        this.data = data;
        this.logicalName = logicalName || this.getClass().logicalName;
    }

    get logicalName() {
        return this.logicName;
    }

    set logicalName(logicalName) {
        this.logicName = logicalName;
    }

    get data() {
        return this.dat;
    }

    set data(data) {
        this.dat = data;
    }

    get isNew() {
        return !this.data.hasOwnProperty("@odata.etag");
    }

    async getEntityMetadata() {
        return await Metadata.getEntityDefinitions(this.logicalName);
    }

    async getPrimaryIdAttribute() {
        const entityMetadata = await this.getEntityMetadata();
        return entityMetadata.PrimaryIdAttribute;
    }

    async getPrimaryId() {
        const primaryIdAttribute = await this.getPrimaryIdAttribute();
        return this.data[primaryIdAttribute];
    }

    static async getEntityAttributes(logicalName = this.logicalName) {
        if (!this.cachedEntityAttributes) {
            this.cachedEntityAttributes = {};
        }
        if (this.cachedEntityAttributes[logicalName]) {
            return this.cachedEntityAttributes[logicalName];
        } else {
            try {
                const entityDefinitionAttributes = await Metadata.getEntityDefinitionAttributes(logicalName),
                    value = entityDefinitionAttributes.value,
                    entityAttributes = {};
                for (const entityDefinitionAttribute of value) {
                    entityAttributes[entityDefinitionAttribute.LogicalName] = entityDefinitionAttribute;
                }
                this.cachedEntityAttributes[logicalName] = entityAttributes;
                return entityAttributes;
            } catch (e) {
                throw e;
            }
        }
    }

    static getCachedEntityAttributes(logicalName = this.logicalName) {
        if (!this.cachedEntityAttributes) {
            this.cachedEntityAttributes = {};
        }
        return this.cachedEntityAttributes[logicalName];
    }

    get changes() {
        if (!this.chngs) {
            this.chngs = {};
        }
        return this.chngs;
    }

    set changes(changes) {
        this.chngs = changes || {};
    }

    getAttribute(name, navigationProperty) {
        const data = this.data[navigationProperty || name];
        if (data) {
            if (navigationProperty) {
                const entityAttributes = this.getClass().getCachedEntityAttributes(this.logicalName),
                    entityAttribute = entityAttributes[name],
                    entityDefinitions = Metadata.getCachedEntityDefinitions(entityAttribute.Targets[0]);
                if (entityDefinitions) {
                    const {SchemaName, PrimaryIdAttribute, PrimaryNameAttribute} = entityDefinitions;
                    data.LogicalName = SchemaName;
                    data.Id = data[PrimaryIdAttribute];
                    data.Name = data[PrimaryNameAttribute];
                }
            }
        } else {
            const logicalName = this.logicalName;
            console.log(`${logicalName} has no attribute '${name}'`);
        }
        return data;
    }

    setAttribute(name, value) {
        if (this.data.hasOwnProperty(name) || name.endsWith("@odata.bind")) {
            if (typeof this.data[name] !== "object") {
                const currentValue = this.data[name];
                if (currentValue !== value) {
                    this.data[name] = value;
                    this.changes[name] = value;
                }
            } else {
                const logicalName = this.logicalName;
                console.log(`${logicalName} attribute ${name} is a Lookup. Use systemuser.bind(${name}, ${value}) instead.`);
            }
        } else {
            const logicalName = this.logicalName;
            console.log(`${logicalName} has no attribute '${name}'`);
        }
    }

    //account.setAttribute("primarycontactid@odata.bind", "https://dys001.crm4.dynamics.com/api/data/v8.0/contacts(465b158c-541c-e511-80d3-3863bb347ba8)");
    async bind(name, value) {
        if (this.data.hasOwnProperty(name)) {
            const entityDefinitionAttributes = await this.getClass().getEntityAttributes(this.logicalName),
                baseURL = WebAPI.webAPIPath,
                target = entityDefinitionAttributes[name].Targets[0],
                entityMetadata = await Metadata.getEntityDefinitions(target),
                entitySetName = entityMetadata.EntitySetName,
                url = `${baseURL}/${entitySetName}(${value})`;
            this.setAttribute(`${name}@odata.bind`, url);
            await this.updateBinding(name, target, value);
        }
    }

    /**
     * @private
     * @param name
     * @param bindingName
     * @param value
     * @returns {Promise.<void>}
     */
    async updateBinding(name, bindingName, value) {
        const dataAttribute = this.getAttribute(name),
            attributes = [];
        for (const key of Object.keys(dataAttribute)) {
            attributes.push(key);
        }
        await Entity.get(bindingName, value, {
            select: attributes
        }).then(bindingEntity => {
            for (const key of attributes) {
                dataAttribute[key] = bindingEntity[key];
            }
            this.setAttribute(name, dataAttribute);
        });
    }
}
export default Entity;
<commit_msg>Remove confusing console.log.<commit_after>import canParse from "./canParse";
import Class from "../Class";
import create from "./create";
import del from "./delete";
import fetch from "./fetch";
import Metadata from "../metadata/Metadata";
import read from "./read";
import update from "./update";
import WebAPI from "../webapi/WebAPI";

class Entity extends canParse(create(del(fetch(read(update(Class)))))) {
    constructor(data, logicalName) {
        super(...arguments);
        this.data = data;
        this.logicalName = logicalName || this.getClass().logicalName;
    }

    get logicalName() {
        return this.logicName;
    }

    set logicalName(logicalName) {
        this.logicName = logicalName;
    }

    get data() {
        return this.dat;
    }

    set data(data) {
        this.dat = data;
    }

    get isNew() {
        return !this.data.hasOwnProperty("@odata.etag");
    }

    async getEntityMetadata() {
        return await Metadata.getEntityDefinitions(this.logicalName);
    }

    async getPrimaryIdAttribute() {
        const entityMetadata = await this.getEntityMetadata();
        return entityMetadata.PrimaryIdAttribute;
    }

    async getPrimaryId() {
        const primaryIdAttribute = await this.getPrimaryIdAttribute();
        return this.data[primaryIdAttribute];
    }

    static async getEntityAttributes(logicalName = this.logicalName) {
        if (!this.cachedEntityAttributes) {
            this.cachedEntityAttributes = {};
        }
        if (this.cachedEntityAttributes[logicalName]) {
            return this.cachedEntityAttributes[logicalName];
        } else {
            try {
                const entityDefinitionAttributes = await Metadata.getEntityDefinitionAttributes(logicalName),
                    value = entityDefinitionAttributes.value,
                    entityAttributes = {};
                for (const entityDefinitionAttribute of value) {
                    entityAttributes[entityDefinitionAttribute.LogicalName] = entityDefinitionAttribute;
                }
                this.cachedEntityAttributes[logicalName] = entityAttributes;
                return entityAttributes;
            } catch (e) {
                throw e;
            }
        }
    }

    static getCachedEntityAttributes(logicalName = this.logicalName) {
        if (!this.cachedEntityAttributes) {
            this.cachedEntityAttributes = {};
        }
        return this.cachedEntityAttributes[logicalName];
    }

    get changes() {
        if (!this.chngs) {
            this.chngs = {};
        }
        return this.chngs;
    }

    set changes(changes) {
        this.chngs = changes || {};
    }

    getAttribute(name, navigationProperty) {
        const data = this.data[navigationProperty || name];
        if (data) {
            if (navigationProperty) {
                const entityAttributes = this.getClass().getCachedEntityAttributes(this.logicalName),
                    entityAttribute = entityAttributes[name],
                    entityDefinitions = Metadata.getCachedEntityDefinitions(entityAttribute.Targets[0]);
                if (entityDefinitions) {
                    const {SchemaName, PrimaryIdAttribute, PrimaryNameAttribute} = entityDefinitions;
                    data.LogicalName = SchemaName;
                    data.Id = data[PrimaryIdAttribute];
                    data.Name = data[PrimaryNameAttribute];
                }
            }
        }
        return data;
    }

    setAttribute(name, value) {
        if (this.data.hasOwnProperty(name) || name.endsWith("@odata.bind")) {
            if (typeof this.data[name] !== "object") {
                const currentValue = this.data[name];
                if (currentValue !== value) {
                    this.data[name] = value;
                    this.changes[name] = value;
                }
            } else {
                const logicalName = this.logicalName;
                console.log(`${logicalName} attribute ${name} is a Lookup. Use systemuser.bind(${name}, ${value}) instead.`);
            }
        } else {
            const logicalName = this.logicalName;
            console.log(`${logicalName} has no attribute '${name}'`);
        }
    }

    //account.setAttribute("primarycontactid@odata.bind", "https://dys001.crm4.dynamics.com/api/data/v8.0/contacts(465b158c-541c-e511-80d3-3863bb347ba8)");
    async bind(name, value) {
        if (this.data.hasOwnProperty(name)) {
            const entityDefinitionAttributes = await this.getClass().getEntityAttributes(this.logicalName),
                baseURL = WebAPI.webAPIPath,
                target = entityDefinitionAttributes[name].Targets[0],
                entityMetadata = await Metadata.getEntityDefinitions(target),
                entitySetName = entityMetadata.EntitySetName,
                url = `${baseURL}/${entitySetName}(${value})`;
            this.setAttribute(`${name}@odata.bind`, url);
            await this.updateBinding(name, target, value);
        }
    }

    /**
     * @private
     * @param name
     * @param bindingName
     * @param value
     * @returns {Promise.<void>}
     */
    async updateBinding(name, bindingName, value) {
        const dataAttribute = this.getAttribute(name),
            attributes = [];
        for (const key of Object.keys(dataAttribute)) {
            attributes.push(key);
        }
        await Entity.get(bindingName, value, {
            select: attributes
        }).then(bindingEntity => {
            for (const key of attributes) {
                dataAttribute[key] = bindingEntity[key];
            }
            this.setAttribute(name, dataAttribute);
        });
    }
}
export default Entity;
<|endoftext|>


<commit_before>function MyuwLog()  {
    var myuwlog = this;

    this.link_logger = undefined;
    this.card_logger = undefined;
    this.appender = undefined;

    this.init = function() {
        this.link_logger = this.get_logger('link');
        this.card_logger = this.get_logger('card');

        $(window).unload(function() {
            window.myuw_log.send_links();
        });
    };

    this.log_card = function(card, action, extra_args) {
        var message = "",
            key;
        if (typeof(card.element)=== "object"){
            extra_args = extra_args || {};
            message = {card_name: LogUtils.get_card_name(card),
                       card_info: $(card.element).attr('data-identifier'),
                       card_position: card.pos,
                       action: action};

            for (key in extra_args) {
                if (extra_args.hasOwnProperty(key)) {
                    message[key] = extra_args[key];
                }
            }
        }else if (typeof(card) === "string"){
            message = {card_name: card,
                       action: action};
        }

        message.screen_width = $(window).width();
        message.screen_height = $(window).height();

        this.card_logger.info(JSON.stringify(message));
    };
    this.log_link = function(link, action) {
        var parent_cards = $(link).closest('.card, .myuw-card');
        var card_name;
        var card_info;
        if (parent_cards.length > 0){
            card_info = $(parent_cards[0]).attr('data-identifier');
            card_name = $(parent_cards[0]).attr('data-name');
        }

        var href = $(link).attr('href');
        if (href && href !== "#") {
            var message = {href: $(link).attr('href'),
                           action: action,
                           source_card: card_name,
                           card_info: card_info};
            if (window.location.href.indexOf("notices") > -1) {
                message.unread_notice_count = Notices.get_total_unread();
            }
            this.link_logger.info(JSON.stringify(message));
        }
    };
    this.send_links = function() {
        if (this.appender.sendAllRemaining) {
            this.appender.sendAllRemaining();
        }
    };

    this.get_logger = function(name) {
        if (this.appender === undefined) {
            this.appender = this.get_appender();
        }
        var log = log4javascript.getLogger(name);
        log.addAppender(this.appender);

        //ensure all error messages are suppressed
        log4javascript.logLog.setQuietMode(true);

        //ensure logs are sent if a user doesn't navigate away
        if (!LogUtils.send_remaining_interval) {
            LogUtils.send_remaining_interval = window.setInterval(function() {
                window.myuw_log.send_links();
            }, LogUtils.PERIODIC_SEND_INTERVAL);
        }

        // Periodically log how long cards have been on screen
        // Disabled due to MUWM-3384
        //if (!LogUtils.on_screen_interval_check) {
        //    LogUtils.on_screen_interval_check = window.setInterval(function() {
        //        LogUtils.periodicVisibilityLogging();
        //    }, LogUtils.PERIODIC_ONSCREEN_INTERVAL);
        //}
        return log;
    };

    this.get_appender = function() {
        var json_layout = new log4javascript.JsonLayout(true);
        var append;
        if (window.location.hash === "#console") {
            append = new log4javascript.BrowserConsoleAppender('/logging/log');
        }
        else {
            append = new log4javascript.AjaxAppender('/logging/log');
            append.setBatchSize(20);
            append.addHeader("X-CSRFToken", csrf_token);
        }
        append.setLayout(json_layout);
        return append;
    };
}

var LogUtils = {
    PERCENTAGE_VISIBLE_THRESHOLD: 0.50,
    PERCENTAGE_OFFSCREEN_THRESHOLD: 0.05,
    PERIODIC_ONSCREEN_INTERVAL: 1000,
    PERIODIC_SEND_INTERVAL: 2000,
    current_visible_cards: {},

    get_new_visible_cards: function(){
        var cards = LogUtils.get_all_cards(),
            card_id,
            visible_cards = [],
            offscreen = [];

        $(cards).each(function(i, card){
            if(LogUtils.isScrolledIntoView(card.element)){
                visible_cards.push(card);
            }

            else if(LogUtils.isOffViewport(card.element)){
                offscreen.push(card);
            }
        });

        var log_values = LogUtils.evaluateCurrentlyVisibleCards(visible_cards, offscreen);
        LogUtils.logCardOnscreenChanges(log_values);
    },

    isScrolledIntoView: function(elem) {
        var docViewTop = $(window).scrollTop();
        var docViewBottom = docViewTop + $(window).height();

        if($(elem).length === 0) {
            // return false when card isn't attached to the page
            return false;
        }

        try {
            var elmHeight = $(elem).height();
            var offset = $(elem).offset();
            var elemTop = $(elem).offset().top;
            var elemBottom = elemTop + elmHeight;
            return LogUtils.isInViewport(docViewTop, docViewBottom, elemTop, elemBottom);
        }
        catch(TypeError){
            return false;
        }
    },

    isInViewport: function(viewport_top, viewport_bottom, elem_top, elem_bottom) {
        // 2 cases of completely off-screen
        if (elem_bottom < viewport_top) {
            return false;
        }
        if (elem_top > viewport_bottom) {
            return false;
        }

        // If it's fully on-screen...
        if ((elem_bottom <= viewport_bottom) && (elem_top >= viewport_top)) {
            return true;
        }

        var visible_height;
        // If we're above the viewport:
        if (elem_top < viewport_top) {
            visible_height = elem_bottom - viewport_top;
        }
        else {
            visible_height = viewport_bottom - elem_top;
        }
        var actual_height = elem_bottom - elem_top;
        var viewport_size = viewport_bottom - viewport_top;

        // If the top or bottom of the element is off-screen...
        // it can be on-screen if 80% of the card is visible
        if (visible_height >= actual_height * LogUtils.PERCENTAGE_VISIBLE_THRESHOLD) {
            return true;
        }

        // or if the card takes up 80% of the screen
        if (visible_height >= viewport_size * LogUtils.PERCENTAGE_VISIBLE_THRESHOLD) {
            return true;
        }

        return false;
    },

    // Only used on elements that have been on-viewport
    isOffViewport: function(viewport_top, viewport_bottom, elem_top, elem_bottom) {
        // 2 cases of completely off-screen
        if (elem_bottom < viewport_top) {
            return true;
        }
        if (elem_top > viewport_bottom) {
            return true;
        }

        // If it's fully on-screen...
        if ((elem_bottom <= viewport_bottom) && (elem_top >= viewport_top)) {
            return false;
        }

        var visible_height;
        // If we're above the viewport:
        if (elem_top < viewport_top) {
            visible_height = elem_bottom - viewport_top;
        }
        else {
            visible_height = viewport_bottom - elem_top;
        }
        var actual_height = elem_bottom - elem_top;
        var viewport_size = viewport_bottom - viewport_top;

        // If the top or bottom of the element is off-screen...
        // it's offscreen if 5% or less is visible
        if (visible_height > actual_height * LogUtils.PERCENTAGE_OFFSCREEN_THRESHOLD) {
            return false;
        }

        // or if the card takes up 5% or less of the screen
        if (visible_height > viewport_size * LogUtils.PERCENTAGE_OFFSCREEN_THRESHOLD) {
            return false;
        }

        return true;
    },

    get_new_visible_links: function () {
        var links = LogUtils.get_links_in_view();
        $(links).each(function(i, link) {
            var href = $(link).attr('href');
            if(!window.viewed_links.hasOwnProperty(href)){
                window.viewed_links[href] = link;
                window.myuw_log.log_link(link, "view");
            }

        });
    },

    get_links_in_view: function(){
       var links = [];
       $("a").each(function (i, link_elm) {
           var href = $(link_elm).attr('href');
           if (href !== "#"){
               if(LogUtils.isScrolledIntoView(link_elm)){
                   //Ensure link or parents aren't hidden
                   if(LogUtils.is_link_disclosed(link_elm)){
                       links.push(link_elm);
                   }
               }
           }
       });
       return links;
    },

    is_link_disclosed: function(elm) {
        return $(elm).attr("aria-hidden") !== true &&
               $(elm).parents('[aria-hidden="true"]').length === 0;

    },

    get_all_cards: function(){
       var cards = [],
           pos = 0;
       $("div").find("[data-type='card']").each(function (i, card) {
           pos++;
           cards.push({element: card, pos: pos});
       });
       return cards;
    },

    _init_link_logging: function() {
       $(document).on("click", "a", function () {
           window.myuw_log.log_link(this, "click");
           window.myuw_log.send_links();
       });
       LogUtils.de_bouncer(jQuery,'smartscroll', 'scroll', 100);
       window.viewed_links = {};
       $(window).smartscroll(function(e) {
           LogUtils.get_new_visible_links();
       });
    },

    _init_card_logging: function() {
        LogUtils.registerCardLoadEvents();
        LogUtils.de_bouncer(jQuery,'smartscroll', 'scroll', 100);
        $(window).smartscroll(function(e) {
            LogUtils.get_new_visible_cards();
        });
    },

    de_bouncer: function($,cf,of, interval){
       var debounce = function (func, threshold, execAsap) {
           var timeout;
           return function debounced () {
               var obj = this, args = arguments;
               function delayed () {
                   if (!execAsap){
                       func.apply(obj, args);
                   }
                   timeout = null;
               }
               if (timeout) {
                   clearTimeout(timeout);
               }
               else if (execAsap) {
                   func.apply(obj, args);
               }
               timeout = setTimeout(delayed, threshold || interval);
           };
       };
       jQuery.fn[cf] = function(fn){  return fn ? this.bind(of, debounce(fn)) : this.trigger(cf); };
    },

    init_logging: function () {
       myuwlog = new MyuwLog();

       myuwlog.init();
       window.myuw_log = myuwlog;
       LogUtils._init_link_logging();
       LogUtils._init_card_logging();
    },

    get_card_name: function(card) {
        var name = $(card.element).attr('data-name');
        var identifier = $(card.element).attr('data-identifier');

        if (identifier) {
            return name + "-" + identifier;
        }
        return name;
    },

    evaluateCurrentlyVisibleCards: function(cards, offscreen) {
        var values = {
            scrolled_out: [],
            scrolled_in: []
        };

        var new_visible_cards = {};
        var i, len;

        for (i = 0, len = cards.length; i < len; i++) {
            var card = cards[i];
            var card_name = LogUtils.get_card_name(card);

            if (LogUtils.current_visible_cards[card_name]) {
                new_visible_cards[card_name] = LogUtils.current_visible_cards[card_name];
                delete LogUtils.current_visible_cards[card_name];
            }
            else {
                new_visible_cards[card_name] = {
                    card: card,
                    first_onscreen: new Date().getTime(),
                    is_newly_read: false,
                    has_been_read: false,
                    rand: Math.random().toString(36).substring(2)
                };

                values.scrolled_in.push(new_visible_cards[card_name]);
            }
        }

        var newly_offscreen_keys = {};
        var key;
        for (i = 0, len = offscreen.length; i < len; i++) {
            key = LogUtils.get_card_name(offscreen[i]);
            newly_offscreen_keys[key] = true;
        }
        for (key in LogUtils.current_visible_cards) {
            if (LogUtils.current_visible_cards.hasOwnProperty(key)) {
                if (newly_offscreen_keys[key]) {
                    values.scrolled_out.push(LogUtils.current_visible_cards[key]);
                    delete LogUtils.current_visible_cards[key];
                }
                else {
                    new_visible_cards[key] = LogUtils.current_visible_cards[key];
                }
            }
        }

        LogUtils.current_visible_cards = new_visible_cards;
        return values;
    },

    logCardOnscreenChanges: function(changes) {
        var i,
            len,
            card;
        for (i = 0, len = changes.scrolled_in.length; i < len; i++) {
            window.myuw_log.log_card(changes.scrolled_in[i].card, "view", {
                rand: changes.scrolled_in[i].rand
            });
        }
        for (i = 0, len = changes.scrolled_out.length; i < len; i++) {
            card = changes.scrolled_out[i].card;
            window.myuw_log.log_card(card, "time_viewed", {
                time_visible: ((new Date().getTime()) - changes.scrolled_out[i].first_onscreen) / 1000,
                final: true,
                rand: changes.scrolled_out[i].rand
            });
        }
    },

    periodicVisibilityLogging: function() {
        var cards = LogUtils.getCurrentlyVisibleCards();
        for (var i = 0, len = cards.length; i < len; i++) {
            var card = cards[i];
            if (card.is_newly_read) {
                window.myuw_log.log_card(card.card, "read", {
                    rand: card.rand
                });
            }

            window.myuw_log.log_card(card.card, "time_viewed", {
                time_visible: ((new Date().getTime()) - card.first_onscreen) / 1000,
                final: false,
                rand: card.rand
            });
        }
    },

    getCurrentlyVisibleCards: function() {
        var list = [],
            key;
        for (key in LogUtils.current_visible_cards) {
            if (LogUtils.current_visible_cards.hasOwnProperty(key)) {
                var card = LogUtils.current_visible_cards[key];
                card.time_visible = ((new Date().getTime()) - card.first_onscreen) / 1000;

                if (card.time_visible >= 1.0) {
                    if (!card.has_been_read) {
                        card.is_newly_read = true;
                    }
                    else {
                        card.is_newly_read = false;
                    }
                    card.has_been_read = true;
                }
                list.push(card);
            }
        }
        return list;
    },

    // This should only be used in the test harness.
    _resetVisibleCards: function() {
        LogUtils.current_visible_cards = {};
    },

    registerCardLoadEvents: function() {
        $(window).on("myuw:card_load", LogUtils._logCardLoaded);
    },

    _logCardLoaded: function(ev, name, el) {
        var message = {
            action: "loaded",
            card_name: name,
            on_screen: LogUtils.isScrolledIntoView(el),
            screen_width: $(window).width(),
            screen_height: $(window).height()
        };
        window.myuw_log.card_logger.info(JSON.stringify(message));
        LogUtils.get_new_visible_cards();
        LogUtils.get_new_visible_links();
    },

    cardLoaded: function(name, el) {
        $(window).trigger("myuw:card_load", [ name, el ]);
    }
};

/* node.js exports */
if (typeof exports === "undefined") {
    var exports = {};
}
exports.LogUtils = LogUtils;
exports.MyuwLog = MyuwLog;
<commit_msg>fixing logged URLs<commit_after>function MyuwLog()  {
    var myuwlog = this;

    this.link_logger = undefined;
    this.card_logger = undefined;
    this.appender = undefined;

    this.init = function() {
        this.link_logger = this.get_logger('link');
        this.card_logger = this.get_logger('card');

        $(window).unload(function() {
            window.myuw_log.send_links();
        });
    };

    this.log_card = function(card, action, extra_args) {
        var message = "",
            key;
        if (typeof(card.element)=== "object"){
            extra_args = extra_args || {};
            message = {card_name: LogUtils.get_card_name(card),
                       card_info: $(card.element).attr('data-identifier'),
                       card_position: card.pos,
                       action: action};

            for (key in extra_args) {
                if (extra_args.hasOwnProperty(key)) {
                    message[key] = extra_args[key];
                }
            }
        }else if (typeof(card) === "string"){
            message = {card_name: card,
                       action: action};
        }

        message.screen_width = $(window).width();
        message.screen_height = $(window).height();

        this.card_logger.info(JSON.stringify(message));
    };
    this.log_link = function(link, action) {
        var parent_cards = $(link).closest('.card, .myuw-card');
        var card_name;
        var card_info;
        if (parent_cards.length > 0){
            card_info = $(parent_cards[0]).attr('data-identifier');
            card_name = $(parent_cards[0]).attr('data-name');
        }

        var href = $(link).attr('href');
        if (href && href !== "#") {
            if(href.indexOf("/out?u=") !== -1){
                href = href.replace("/out?u=", "");
                var parts = href.split("&");
                href = decodeURIComponent(parts[0]);
            }

            var message = {href: href,
                           action: action,
                           source_card: card_name,
                           card_info: card_info};
            if (window.location.href.indexOf("notices") > -1) {
                message.unread_notice_count = Notices.get_total_unread();
            }
            this.link_logger.info(JSON.stringify(message));
        }
    };
    this.send_links = function() {
        if (this.appender.sendAllRemaining) {
            this.appender.sendAllRemaining();
        }
    };

    this.get_logger = function(name) {
        if (this.appender === undefined) {
            this.appender = this.get_appender();
        }
        var log = log4javascript.getLogger(name);
        log.addAppender(this.appender);

        //ensure all error messages are suppressed
        log4javascript.logLog.setQuietMode(true);

        //ensure logs are sent if a user doesn't navigate away
        if (!LogUtils.send_remaining_interval) {
            LogUtils.send_remaining_interval = window.setInterval(function() {
                window.myuw_log.send_links();
            }, LogUtils.PERIODIC_SEND_INTERVAL);
        }

        // Periodically log how long cards have been on screen
        // Disabled due to MUWM-3384
        //if (!LogUtils.on_screen_interval_check) {
        //    LogUtils.on_screen_interval_check = window.setInterval(function() {
        //        LogUtils.periodicVisibilityLogging();
        //    }, LogUtils.PERIODIC_ONSCREEN_INTERVAL);
        //}
        return log;
    };

    this.get_appender = function() {
        var json_layout = new log4javascript.JsonLayout(true);
        var append;
        if (window.location.hash === "#console") {
            append = new log4javascript.BrowserConsoleAppender('/logging/log');
        }
        else {
            append = new log4javascript.AjaxAppender('/logging/log');
            append.setBatchSize(20);
            append.addHeader("X-CSRFToken", csrf_token);
        }
        append.setLayout(json_layout);
        return append;
    };
}

var LogUtils = {
    PERCENTAGE_VISIBLE_THRESHOLD: 0.50,
    PERCENTAGE_OFFSCREEN_THRESHOLD: 0.05,
    PERIODIC_ONSCREEN_INTERVAL: 1000,
    PERIODIC_SEND_INTERVAL: 2000,
    current_visible_cards: {},

    get_new_visible_cards: function(){
        var cards = LogUtils.get_all_cards(),
            card_id,
            visible_cards = [],
            offscreen = [];

        $(cards).each(function(i, card){
            if(LogUtils.isScrolledIntoView(card.element)){
                visible_cards.push(card);
            }

            else if(LogUtils.isOffViewport(card.element)){
                offscreen.push(card);
            }
        });

        var log_values = LogUtils.evaluateCurrentlyVisibleCards(visible_cards, offscreen);
        LogUtils.logCardOnscreenChanges(log_values);
    },

    isScrolledIntoView: function(elem) {
        var docViewTop = $(window).scrollTop();
        var docViewBottom = docViewTop + $(window).height();

        if($(elem).length === 0) {
            // return false when card isn't attached to the page
            return false;
        }

        try {
            var elmHeight = $(elem).height();
            var offset = $(elem).offset();
            var elemTop = $(elem).offset().top;
            var elemBottom = elemTop + elmHeight;
            return LogUtils.isInViewport(docViewTop, docViewBottom, elemTop, elemBottom);
        }
        catch(TypeError){
            return false;
        }
    },

    isInViewport: function(viewport_top, viewport_bottom, elem_top, elem_bottom) {
        // 2 cases of completely off-screen
        if (elem_bottom < viewport_top) {
            return false;
        }
        if (elem_top > viewport_bottom) {
            return false;
        }

        // If it's fully on-screen...
        if ((elem_bottom <= viewport_bottom) && (elem_top >= viewport_top)) {
            return true;
        }

        var visible_height;
        // If we're above the viewport:
        if (elem_top < viewport_top) {
            visible_height = elem_bottom - viewport_top;
        }
        else {
            visible_height = viewport_bottom - elem_top;
        }
        var actual_height = elem_bottom - elem_top;
        var viewport_size = viewport_bottom - viewport_top;

        // If the top or bottom of the element is off-screen...
        // it can be on-screen if 80% of the card is visible
        if (visible_height >= actual_height * LogUtils.PERCENTAGE_VISIBLE_THRESHOLD) {
            return true;
        }

        // or if the card takes up 80% of the screen
        if (visible_height >= viewport_size * LogUtils.PERCENTAGE_VISIBLE_THRESHOLD) {
            return true;
        }

        return false;
    },

    // Only used on elements that have been on-viewport
    isOffViewport: function(viewport_top, viewport_bottom, elem_top, elem_bottom) {
        // 2 cases of completely off-screen
        if (elem_bottom < viewport_top) {
            return true;
        }
        if (elem_top > viewport_bottom) {
            return true;
        }

        // If it's fully on-screen...
        if ((elem_bottom <= viewport_bottom) && (elem_top >= viewport_top)) {
            return false;
        }

        var visible_height;
        // If we're above the viewport:
        if (elem_top < viewport_top) {
            visible_height = elem_bottom - viewport_top;
        }
        else {
            visible_height = viewport_bottom - elem_top;
        }
        var actual_height = elem_bottom - elem_top;
        var viewport_size = viewport_bottom - viewport_top;

        // If the top or bottom of the element is off-screen...
        // it's offscreen if 5% or less is visible
        if (visible_height > actual_height * LogUtils.PERCENTAGE_OFFSCREEN_THRESHOLD) {
            return false;
        }

        // or if the card takes up 5% or less of the screen
        if (visible_height > viewport_size * LogUtils.PERCENTAGE_OFFSCREEN_THRESHOLD) {
            return false;
        }

        return true;
    },

    get_new_visible_links: function () {
        var links = LogUtils.get_links_in_view();
        $(links).each(function(i, link) {
            var href = $(link).attr('href');
            if(!window.viewed_links.hasOwnProperty(href)){
                window.viewed_links[href] = link;
                window.myuw_log.log_link(link, "view");
            }

        });
    },

    get_links_in_view: function(){
       var links = [];
       $("a").each(function (i, link_elm) {
           var href = $(link_elm).attr('href');
           if (href !== "#"){
               if(LogUtils.isScrolledIntoView(link_elm)){
                   //Ensure link or parents aren't hidden
                   if(LogUtils.is_link_disclosed(link_elm)){
                       links.push(link_elm);
                   }
               }
           }
       });
       return links;
    },

    is_link_disclosed: function(elm) {
        return $(elm).attr("aria-hidden") !== true &&
               $(elm).parents('[aria-hidden="true"]').length === 0;

    },

    get_all_cards: function(){
       var cards = [],
           pos = 0;
       $("div").find("[data-type='card']").each(function (i, card) {
           pos++;
           cards.push({element: card, pos: pos});
       });
       return cards;
    },

    _init_link_logging: function() {
       $(document).on("click", "a", function () {
           window.myuw_log.log_link(this, "click");
           window.myuw_log.send_links();
       });
       LogUtils.de_bouncer(jQuery,'smartscroll', 'scroll', 100);
       window.viewed_links = {};
       $(window).smartscroll(function(e) {
           LogUtils.get_new_visible_links();
       });
    },

    _init_card_logging: function() {
        LogUtils.registerCardLoadEvents();
        LogUtils.de_bouncer(jQuery,'smartscroll', 'scroll', 100);
        $(window).smartscroll(function(e) {
            LogUtils.get_new_visible_cards();
        });
    },

    de_bouncer: function($,cf,of, interval){
       var debounce = function (func, threshold, execAsap) {
           var timeout;
           return function debounced () {
               var obj = this, args = arguments;
               function delayed () {
                   if (!execAsap){
                       func.apply(obj, args);
                   }
                   timeout = null;
               }
               if (timeout) {
                   clearTimeout(timeout);
               }
               else if (execAsap) {
                   func.apply(obj, args);
               }
               timeout = setTimeout(delayed, threshold || interval);
           };
       };
       jQuery.fn[cf] = function(fn){  return fn ? this.bind(of, debounce(fn)) : this.trigger(cf); };
    },

    init_logging: function () {
       myuwlog = new MyuwLog();

       myuwlog.init();
       window.myuw_log = myuwlog;
       LogUtils._init_link_logging();
       LogUtils._init_card_logging();
    },

    get_card_name: function(card) {
        var name = $(card.element).attr('data-name');
        var identifier = $(card.element).attr('data-identifier');

        if (identifier) {
            return name + "-" + identifier;
        }
        return name;
    },

    evaluateCurrentlyVisibleCards: function(cards, offscreen) {
        var values = {
            scrolled_out: [],
            scrolled_in: []
        };

        var new_visible_cards = {};
        var i, len;

        for (i = 0, len = cards.length; i < len; i++) {
            var card = cards[i];
            var card_name = LogUtils.get_card_name(card);

            if (LogUtils.current_visible_cards[card_name]) {
                new_visible_cards[card_name] = LogUtils.current_visible_cards[card_name];
                delete LogUtils.current_visible_cards[card_name];
            }
            else {
                new_visible_cards[card_name] = {
                    card: card,
                    first_onscreen: new Date().getTime(),
                    is_newly_read: false,
                    has_been_read: false,
                    rand: Math.random().toString(36).substring(2)
                };

                values.scrolled_in.push(new_visible_cards[card_name]);
            }
        }

        var newly_offscreen_keys = {};
        var key;
        for (i = 0, len = offscreen.length; i < len; i++) {
            key = LogUtils.get_card_name(offscreen[i]);
            newly_offscreen_keys[key] = true;
        }
        for (key in LogUtils.current_visible_cards) {
            if (LogUtils.current_visible_cards.hasOwnProperty(key)) {
                if (newly_offscreen_keys[key]) {
                    values.scrolled_out.push(LogUtils.current_visible_cards[key]);
                    delete LogUtils.current_visible_cards[key];
                }
                else {
                    new_visible_cards[key] = LogUtils.current_visible_cards[key];
                }
            }
        }

        LogUtils.current_visible_cards = new_visible_cards;
        return values;
    },

    logCardOnscreenChanges: function(changes) {
        var i,
            len,
            card;
        for (i = 0, len = changes.scrolled_in.length; i < len; i++) {
            window.myuw_log.log_card(changes.scrolled_in[i].card, "view", {
                rand: changes.scrolled_in[i].rand
            });
        }
        for (i = 0, len = changes.scrolled_out.length; i < len; i++) {
            card = changes.scrolled_out[i].card;
            window.myuw_log.log_card(card, "time_viewed", {
                time_visible: ((new Date().getTime()) - changes.scrolled_out[i].first_onscreen) / 1000,
                final: true,
                rand: changes.scrolled_out[i].rand
            });
        }
    },

    periodicVisibilityLogging: function() {
        var cards = LogUtils.getCurrentlyVisibleCards();
        for (var i = 0, len = cards.length; i < len; i++) {
            var card = cards[i];
            if (card.is_newly_read) {
                window.myuw_log.log_card(card.card, "read", {
                    rand: card.rand
                });
            }

            window.myuw_log.log_card(card.card, "time_viewed", {
                time_visible: ((new Date().getTime()) - card.first_onscreen) / 1000,
                final: false,
                rand: card.rand
            });
        }
    },

    getCurrentlyVisibleCards: function() {
        var list = [],
            key;
        for (key in LogUtils.current_visible_cards) {
            if (LogUtils.current_visible_cards.hasOwnProperty(key)) {
                var card = LogUtils.current_visible_cards[key];
                card.time_visible = ((new Date().getTime()) - card.first_onscreen) / 1000;

                if (card.time_visible >= 1.0) {
                    if (!card.has_been_read) {
                        card.is_newly_read = true;
                    }
                    else {
                        card.is_newly_read = false;
                    }
                    card.has_been_read = true;
                }
                list.push(card);
            }
        }
        return list;
    },

    // This should only be used in the test harness.
    _resetVisibleCards: function() {
        LogUtils.current_visible_cards = {};
    },

    registerCardLoadEvents: function() {
        $(window).on("myuw:card_load", LogUtils._logCardLoaded);
    },

    _logCardLoaded: function(ev, name, el) {
        var message = {
            action: "loaded",
            card_name: name,
            on_screen: LogUtils.isScrolledIntoView(el),
            screen_width: $(window).width(),
            screen_height: $(window).height()
        };
        window.myuw_log.card_logger.info(JSON.stringify(message));
        LogUtils.get_new_visible_cards();
        LogUtils.get_new_visible_links();
    },

    cardLoaded: function(name, el) {
        $(window).trigger("myuw:card_load", [ name, el ]);
    }
};

/* node.js exports */
if (typeof exports === "undefined") {
    var exports = {};
}
exports.LogUtils = LogUtils;
exports.MyuwLog = MyuwLog;
<|endoftext|>


<commit_before>import * as pdfjs from 'pdfjs-dist/legacy/build/pdf';

import Document from './Document';
import Outline from './Outline';
import Page from './Page';

import { displayWorkerWarning } from './shared/utils';

displayWorkerWarning();

pdfjs.GlobalWorkerOptions.workerSrc = new URL(
  'npm:pdfjs-dist/legacy/build/pdf.worker',
  import.meta.url,
);

export { pdfjs, Document, Outline, Page };
<commit_msg>Use workerPort instead of workerSrc in Parcel 2 specific entry (#941)<commit_after>import * as pdfjs from 'pdfjs-dist/legacy/build/pdf';

import Document from './Document';
import Outline from './Outline';
import Page from './Page';

import { displayWorkerWarning } from './shared/utils';

displayWorkerWarning();

if (typeof window !== 'undefined' && 'Worker' in window) {
  pdfjs.GlobalWorkerOptions.workerPort = new Worker(
    new URL('./pdf.worker.entry.js', import.meta.url),
    { type: 'module' },
  );
}

export { pdfjs, Document, Outline, Page };
<|endoftext|>


<commit_before>'use strict';

//  ---------------------------------------------------------------------------

const coinegg = require ('./coinegg.js');

//  ---------------------------------------------------------------------------

module.exports = class coolcoin extends coinegg {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'coolcoin',
            'name': 'CoolCoin',
            'countries': [ 'HK' ],
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/36770529-be7b1a04-1c5b-11e8-9600-d11f1996b539.jpg',
                'api': {
                    'web': 'https://www.coolcoin.com/coin',
                    'rest': 'https://www.coolcoin.com/api/v1',
                },
                'www': 'https://www.coolcoin.com',
                'doc': 'https://www.coolcoin.com/help.api.html',
                'fees': 'https://www.coolcoin.com/spend.price.html',
            },
            'fees': {
                'trading': {
                    'maker': 0.1 / 100,
                    'taker': 0.1 / 100,
                },
                'funding': {
                    'withdraw': {
                        'BTC': 0.001,
                        'BCH': 0.002,
                        'ETH': 0.01,
                        'ETC': 0.01,
                        'LTC': 0.001,
                        'TBC': '1%',
                        'HSR': '1%',
                        'NEO': '1%',
                        'SDC': '1%',
                        'EOS': '1%',
                        'BTM': '1%',
                        'XAS': '1%',
                        'ACT': '1%',
                        'SAK': '1%',
                        'GCS': '1%',
                        'HCC': '1%',
                        'QTUM': '1%',
                        'GEC': '1%',
                        'TRX': '1%',
                        'IFC': '1%',
                        'PAY': '1%',
                        'PGC': '1%',
                        'KTC': '1%',
                        'INT': '1%',
                        'LSK': '0.5%',
                        'SKT': '1%',
                        'SSS': '1%',
                        'BT1': '1%',
                        'BT2': '1%',
                    },
                },
            },
            'options': {
                'quoteIds': ['btc', 'usdt'],
            },
        });
    }
};
<commit_msg>coolcoin reflink<commit_after>'use strict';

//  ---------------------------------------------------------------------------

const coinegg = require ('./coinegg.js');

//  ---------------------------------------------------------------------------

module.exports = class coolcoin extends coinegg {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'coolcoin',
            'name': 'CoolCoin',
            'countries': [ 'HK' ],
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/36770529-be7b1a04-1c5b-11e8-9600-d11f1996b539.jpg',
                'api': {
                    'web': 'https://www.coolcoin.com/coin',
                    'rest': 'https://www.coolcoin.com/api/v1',
                },
                'www': 'https://www.coolcoin.com',
                'doc': 'https://www.coolcoin.com/help.api.html',
                'fees': 'https://www.coolcoin.com/spend.price.html',
                'referral': 'https://www.coolcoin.com',
            },
            'fees': {
                'trading': {
                    'maker': 0.1 / 100,
                    'taker': 0.1 / 100,
                },
                'funding': {
                    'withdraw': {
                        'BTC': 0.001,
                        'BCH': 0.002,
                        'ETH': 0.01,
                        'ETC': 0.01,
                        'LTC': 0.001,
                        'TBC': '1%',
                        'HSR': '1%',
                        'NEO': '1%',
                        'SDC': '1%',
                        'EOS': '1%',
                        'BTM': '1%',
                        'XAS': '1%',
                        'ACT': '1%',
                        'SAK': '1%',
                        'GCS': '1%',
                        'HCC': '1%',
                        'QTUM': '1%',
                        'GEC': '1%',
                        'TRX': '1%',
                        'IFC': '1%',
                        'PAY': '1%',
                        'PGC': '1%',
                        'KTC': '1%',
                        'INT': '1%',
                        'LSK': '0.5%',
                        'SKT': '1%',
                        'SSS': '1%',
                        'BT1': '1%',
                        'BT2': '1%',
                    },
                },
            },
            'options': {
                'quoteIds': ['btc', 'usdt'],
            },
        });
    }
};
<|endoftext|>


<commit_before>/*!
 * Start Bootstrap - Creative Bootstrap Theme (http://startbootstrap.com)
 * Code licensed under the Apache License v2.0.
 * For details, see http://www.apache.org/licenses/LICENSE-2.0.
 */

(function($) {
    "use strict"; // Start of use strict

    // jQuery for page scrolling feature - requires jQuery Easing plugin
    $('a.page-scroll').bind('click', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: ($($anchor.attr('href')).offset().top - 50)
        }, 1250, 'easeInOutExpo');
        event.preventDefault();
    });

    // Highlight the top nav as scrolling occurs
    $('body').scrollspy({
        target: '.navbar-fixed-top',
        offset: 51
    })

    // Closes the Responsive Menu on Menu Item Click
    $('.navbar-collapse ul li a').click(function() {
        $('.navbar-toggle:visible').click();
    });

    // Fit Text Plugin for Main Header
    $("h1").fitText(
        1.2, {
            minFontSize: '35px',
            maxFontSize: '65px'
        }
    );

    // Offset for Main Navigation
    $('#mainNav').affix({
        offset: {
            top: 100
        }
    })

    // Initialize WOW.js Scrolling Animations
    new WOW().init();

    $('.header-content').delay(2000).css({ opacity: 1, background: "rgba(48,20,10,0.3)"});

    $('#code').submit(function(e){
        e.preventDefault();
        alert('Het spijt ons.\n\nVoor de ingegeven code hebben we geen inschrijving ontvangen.\n\nWe verwijzen u door naar een andere reeks.');
        window.location.replace('http://tim25.github.io/index2.html');
    });

})(jQuery); // End of use strict
<commit_msg>change url<commit_after>/*!
 * Start Bootstrap - Creative Bootstrap Theme (http://startbootstrap.com)
 * Code licensed under the Apache License v2.0.
 * For details, see http://www.apache.org/licenses/LICENSE-2.0.
 */

(function($) {
    "use strict"; // Start of use strict

    // jQuery for page scrolling feature - requires jQuery Easing plugin
    $('a.page-scroll').bind('click', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: ($($anchor.attr('href')).offset().top - 50)
        }, 1250, 'easeInOutExpo');
        event.preventDefault();
    });

    // Highlight the top nav as scrolling occurs
    $('body').scrollspy({
        target: '.navbar-fixed-top',
        offset: 51
    })

    // Closes the Responsive Menu on Menu Item Click
    $('.navbar-collapse ul li a').click(function() {
        $('.navbar-toggle:visible').click();
    });

    // Fit Text Plugin for Main Header
    $("h1").fitText(
        1.2, {
            minFontSize: '35px',
            maxFontSize: '65px'
        }
    );

    // Offset for Main Navigation
    $('#mainNav').affix({
        offset: {
            top: 100
        }
    })

    // Initialize WOW.js Scrolling Animations
    new WOW().init();

    $('.header-content').delay(2000).css({ opacity: 1, background: "rgba(48,20,10,0.3)"});

    $('#code').submit(function(e){
        e.preventDefault();
        alert('Het spijt ons.\n\nVoor de ingegeven code hebben we geen inschrijving ontvangen.\n\nWe verwijzen u door naar een andere reeks.');
        window.location.replace('http://gino25.github.io/index2.html');
    });

})(jQuery); // End of use strict
<|endoftext|>


<commit_before>/*!
 * Start Bootstrap - Creative Bootstrap Theme (http://startbootstrap.com)
 * Code licensed under the Apache License v2.0.
 * For details, see http://www.apache.org/licenses/LICENSE-2.0.
 */

(function($) {
    "use strict"; // Start of use strict

    // jQuery for page scrolling feature - requires jQuery Easing plugin
    $('a.page-scroll').bind('click', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: ($($anchor.attr('href')).offset().top - 50)
        }, 1250, 'easeInOutExpo');
        event.preventDefault();
    });

    // Highlight the top nav as scrolling occurs
    $('body').scrollspy({
        target: '.navbar-fixed-top',
        offset: 51
    })

    // Closes the Responsive Menu on Menu Item Click
    $('.navbar-collapse ul li a').click(function() {
        $('.navbar-toggle:visible').click();
    });

    // Fit Text Plugin for Main Header
    $("h1").fitText(
        1.2, {
            minFontSize: '25px',
            maxFontSize: '65px'
        }
    );

    // Offset for Main Navigation
    $('#mainNav').affix({
        offset: {
            top: 100
        }
    })

    // Initialize WOW.js Scrolling Animations
    new WOW().init();

})(jQuery); // End of use strict
<commit_msg>Update creative.js<commit_after>/*!
 * Start Bootstrap - Creative Bootstrap Theme (http://startbootstrap.com)
 * Code licensed under the Apache License v2.0.
 * For details, see http://www.apache.org/licenses/LICENSE-2.0.
 */

(function($) {
    "use strict"; // Start of use strict

    // jQuery for page scrolling feature - requires jQuery Easing plugin
    $('a.page-scroll').bind('click', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: ($($anchor.attr('href')).offset().top - 50)
        }, 1250, 'easeInOutExpo');
        event.preventDefault();
    });

    // Highlight the top nav as scrolling occurs
    $('body').scrollspy({
        target: '.navbar-fixed-top',
        offset: 51
    })

    // Closes the Responsive Menu on Menu Item Click
    $('.navbar-collapse ul li a').click(function() {
        $('.navbar-toggle:visible').click();
    });

    // Fit Text Plugin for Main Header
    $("h1").fitText(
        1.2, {
            minFontSize: '25px',
            maxFontSize: '65px'
        }
    );

     // Fit Text Plugin for Partfolio
     $(".portfolio-box-caption-content").fitText(
        1.2, {
            minFontSize: '10px',
            maxFontSize: '25px'
        }
    );

    // Offset for Main Navigation
    $('#mainNav').affix({
        offset: {
            top: 100
        }
    })

    // Initialize WOW.js Scrolling Animations
    new WOW().init();

})(jQuery); // End of use strict
<|endoftext|>


<commit_before>/* vim: ts=4:sw=4:expandtab
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

(function () {
    'use strict';
    window.Whisper             = window.Whisper             || {};
    window.Whisper.Database    = window.Whisper.Database    || {};
    window.Whisper.Database.id = window.Whisper.Database.id || 'signal';

    Whisper.Database.migrations = [
        {
            version: "1.0",
            migrate: function(transaction, next) {
                console.log('migration 1.0');
                var messages = transaction.db.createObjectStore("messages");
                messages.createIndex("conversation", ["conversationId", "received_at"], { unique: false });
                messages.createIndex("receipt", "sent_at", { unique: false });

                var conversations = transaction.db.createObjectStore("conversations");
                conversations.createIndex("inbox", "active_at", { unique: false });
                conversations.createIndex("group", "members", { unique: false, multiEntry: true });
                conversations.createIndex("type", "type", { unique: false });

                var groups = transaction.db.createObjectStore('groups');

                var sessions = transaction.db.createObjectStore('sessions');
                var identityKeys = transaction.db.createObjectStore('identityKeys');

                var preKeys = transaction.db.createObjectStore("preKeys");
                var signedPreKeys = transaction.db.createObjectStore("signedPreKeys");

                var items = transaction.db.createObjectStore("items");
                next();
            }
        }
    ];
}());
<commit_msg>Turn off idb query logging<commit_after>/* vim: ts=4:sw=4:expandtab
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

(function () {
    'use strict';
    window.Whisper             = window.Whisper             || {};
    window.Whisper.Database    = window.Whisper.Database    || {};
    window.Whisper.Database.id = window.Whisper.Database.id || 'signal';
    window.Whisper.Database.nolog = true;

    Whisper.Database.migrations = [
        {
            version: "1.0",
            migrate: function(transaction, next) {
                console.log('migration 1.0');
                var messages = transaction.db.createObjectStore("messages");
                messages.createIndex("conversation", ["conversationId", "received_at"], { unique: false });
                messages.createIndex("receipt", "sent_at", { unique: false });

                var conversations = transaction.db.createObjectStore("conversations");
                conversations.createIndex("inbox", "active_at", { unique: false });
                conversations.createIndex("group", "members", { unique: false, multiEntry: true });
                conversations.createIndex("type", "type", { unique: false });

                var groups = transaction.db.createObjectStore('groups');

                var sessions = transaction.db.createObjectStore('sessions');
                var identityKeys = transaction.db.createObjectStore('identityKeys');

                var preKeys = transaction.db.createObjectStore("preKeys");
                var signedPreKeys = transaction.db.createObjectStore("signedPreKeys");

                var items = transaction.db.createObjectStore("items");
                next();
            }
        }
    ];
}());
<|endoftext|>


<commit_before>var titulo = document.getElementById('titulo');
var conteudo = document.getElementById('conteudo');
var visibilidade = document.getElementById('visibilidade');
var criar = document.getElementById('criar');

var lista = document.getElementById('lista');

var deletarTudo = document.getElementById('deletar-tudo');

var painelnota = document.getElementById('painel-nota');

var menuzinho = function(){
	var tg = event.target;
	var id = tg.getAttribute("data-id");
	var pe = tg.parentElement;
	pe = pe.parentElement;
	var json = JSON.parse(pe.getAttribute("data-json"));
	console.log(json);
	pe.setAttribute("class","card-content blue lighten-5");
	pe.innerHTML = 'Edição da nota '+id+' close<input type="text" value="'+json.titulo+'"><textarea class="materialize-textarea">'+json.conteudo+'</textarea><btn class="btn blue" onclick=\'editar("'+id+'")\'>Editar</btn><btn class="btn red" onclick=\'remover("'+id+'")\'>Remover</btn>';
}

function remover(id){
	firebase.database().ref("notas").child(id).remove();
}

function editar(id){
	var up = {};
	up["/notas/"+id] = {titulo:"marcos"};
	return firebase.database().ref().update(up);
}

var menuhtml = '<a href=';

criar.addEventListener('click', function () {
    var r = criarNota(titulo.value, conteudo.value, visibilidade.value);
	painelnota.style.display = 'none';
});

deletarTudo.addEventListener('click', function () {
	firebase.database().ref("notas").remove();
});

function criarNota(titulo, conteudo, visibilidade) {
    var data = {
        titulo: titulo,
        conteudo: conteudo,
		timestamp: + new Date(),
		visibilidade: visibilidade,
		estado: "aberta",
		idusuario: 230
    };
    return firebase.database().ref().child('notas').push(data);
}

firebase.database().ref('notas').on('value', function (snapshot) {
    lista.innerHTML = '';
    snapshot.forEach(function (item) {
		var date = new Date(item.val().timestamp);
		var dia = date.getDate();
		var mes = date.getMonth();
		var ano = date.getFullYear();
		var hours = date.getHours();
		var minutes = date.getMinutes();
		var seconds = date.getSeconds();
		var d = dia + '/' + (mes+1) + '/' + ano;
		var h = hours + ':' + minutes + ':' + seconds;
		var dh = d + ' às ' + h;
		lista.innerHTML += '

'+item.val().titulo+'(...)'+dh+'
'+item.val().conteudo+'

';
    });
	var cardclick = document.getElementsByClassName('cardclick');
	for (var i = 0; i < cardclick.length; i++) {
		cardclick[i].addEventListener('dblclick', menuzinho, false);
	}
});

firebase.database().ref('notas').on('value', function (snapshot) {
    snapshot.forEach(function (item) {
		console.log(item.val().titulo + ' - ' + item.val().conteudo + ' - ' + item.val().visibilidade );
    });
});<commit_msg>Seleção de elementos do formulário de edição de nota<commit_after>var titulo = document.getElementById('titulo');
var conteudo = document.getElementById('conteudo');
var visibilidade = document.getElementById('visibilidade');
var criar = document.getElementById('criar');

var lista = document.getElementById('lista');

var deletarTudo = document.getElementById('deletar-tudo');

var painelnota = document.getElementById('painel-nota');

var menuzinho = function(){
	var tg = event.target;
	var id = tg.getAttribute("data-id");
	var pe = tg.parentElement;
	pe = pe.parentElement;
	var json = JSON.parse(pe.getAttribute("data-json"));
	pe.setAttribute("class","nota-"+id+" card-content blue lighten-5");
	pe.innerHTML = 'Edição da nota '+id+' close<input type="text" name="ttitulo" value="'+json.titulo+'"><textarea id="tconteudo" class="materialize-textarea">'+json.conteudo+'</textarea><btn class="btn blue" onclick=\'editar("'+id+'")\'>Editar</btn><btn class="btn red" onclick=\'remover("'+id+'")\'>Remover</btn>';
}

function remover(id){
	firebase.database().ref("notas").child(id).remove();
}

function editar(id){
	var el = document.getElementsByClassName("nota-"+id)[0];
	var json = JSON.parse(el.getAttribute("data-json"));
	var titulo = el.childNodes[1].value;
	var conteudo = el.childNodes[2].value;
	var up = {};
	up["/notas/"+id] = {titulo:titulo, timestamp:json.timestamp, conteudo:conteudo};
	return firebase.database().ref().update(up);
}

var menuhtml = '<a href=';

criar.addEventListener('click', function () {
    var r = criarNota(titulo.value, conteudo.value, visibilidade.value);
	painelnota.style.display = 'none';
});

deletarTudo.addEventListener('click', function () {
	firebase.database().ref("notas").remove();
});

function criarNota(titulo, conteudo, visibilidade) {
    var data = {
        titulo: titulo,
        conteudo: conteudo,
		timestamp: + new Date(),
		visibilidade: visibilidade,
		estado: "aberta",
		idusuario: 230
    };
    return firebase.database().ref().child('notas').push(data);
}

firebase.database().ref('notas').on('value', function (snapshot) {
    lista.innerHTML = '';
    snapshot.forEach(function (item) {
		var date = new Date(item.val().timestamp);
		var dia = date.getDate();
		var mes = date.getMonth();
		var ano = date.getFullYear();
		var hours = date.getHours();
		var minutes = date.getMinutes();
		var seconds = date.getSeconds();
		var d = dia + '/' + (mes+1) + '/' + ano;
		var h = hours + ':' + minutes + ':' + seconds;
		var dh = d + ' às ' + h;
		lista.innerHTML += '

'+item.val().titulo+'(...)'+dh+'
'+item.val().conteudo+'

';
    });
	var cardclick = document.getElementsByClassName('cardclick');
	for (var i = 0; i < cardclick.length; i++) {
		cardclick[i].addEventListener('dblclick', menuzinho, false);
	}
});

firebase.database().ref('notas').on('value', function (snapshot) {
    snapshot.forEach(function (item) {
		console.log(item.val().titulo + ' - ' + item.val().conteudo + ' - ' + item.val().visibilidade );
    });
});<|endoftext|>


<commit_before>var Resources = require('../conf.js');
var Mongoose = require('mongoose');
var Tunnel = require('tunnel-ssh');
var Conf = require('../conf.js');
var TvMaze = require('../libs/tvMaze.js');
var Common = require('../common.js');
var ScheduleManager = require('../schedule/scheduleManager.js');
var Logger = require('../log/logger.js');
var BotGui = require('../gui/keyboards.js');

var db = undefined;
var Schema = Mongoose.Schema;
//Mongoose.set('debug', true);

var Alert = Mongoose.model('Alert', new Schema({
    ids: String,
    show_name: String,
    showId: Number,
    language: Schema.Types.Mixed,
    nextepisode_airdate: String,
    nextepisode_season: Number,
    nextepisode_episode: Number
}, {
        _id: false
    }));
var User = Mongoose.model('User', new Schema({
    ids: String,
    chatId: Number,
    first_name: String,
    alerts: Array
}));
var Language = Mongoose.model('Language', new Schema({
    code: String,
    int: String,
    native: String
}, {
        _id: false
    }));

exports.getMongoConnection = function () {
    return db;
}

exports.connectToDatabase = function () {
    if (Conf.mongoHost == "") {
        var server = Tunnel(Conf.mongoConfig, function (error, server) {
            if (error) {
                console.log("SSH connection error: " + error);
            }
            Mongoose.connect('mongodb://localhost:' + Conf.mongoConfig.localPort + "/" + Conf.dbName,
            { server: { reconnectTries: Number.MAX_VALUE } });
            db = Mongoose.connection;
            db.on('error', () => {
                console.log('DB connection error ')
            });
            db.once('open', function () {
                console.log("DB connection successful");
                ScheduleManager.startAgenda();
            });
        });
    } else {
        Mongoose.connect('mongodb://localhost:' + Conf.mongoConfig.localPort + "/" + Conf.dbName,
            { server: { reconnectTries: Number.MAX_VALUE } });
        db = Mongoose.connection;
        db.on('error', () => {
            console.log('DB connection error ')
        });
        db.once('open', function () {
            console.log("DB connection successful");
            ScheduleManager.startAgenda();
        });
    }
}

exports.subscribe = function (session, bot, from) {
    Logger.logEvent("alert", [], session);
    var alertsToStore = [];
    var alertsIdList = [];
    if (session.choosenSeriesAlert.show._links.nextepisode) {
        var nextepisodePromise = TvMaze.getNextEpisodeInformation(session.choosenSeriesAlert.show._links.nextepisode.href);

        nextepisodePromise.then(function (nextepisode) {
            session.chosenLanguagesAlert.forEach(function (languageElement, index) {
                var alertToStore = new Alert({
                    show_name: session.choosenSeriesAlert.show.name,
                    showId: session.choosenSeriesAlert.show.id,
                    language: languageElement,
                    nextepisode_airdate: nextepisode.airdate,
                    nextepisode_season: nextepisode.season,
                    nextepisode_episode: nextepisode.number
                    //FOR DEBUG:
                    // nextepisode_airdate: "today",
                    // nextepisode_season: "1",
                    // nextepisode_episode: "1"
                });
                if (alertToStore._doc._id === undefined) {
                    delete alertToStore._doc._id;
                }
                Alert.findOneAndUpdate({ showId: alertToStore.showId, language: languageElement },
                    alertToStore, { new: true, upsert: true },
                    function (err, storedAlert) {
                        if (err) console.log("ERROR IN SAVE MONGO", err);
                        else {
                            ScheduleManager.activateStoredSchedules(storedAlert._doc, bot, false);
                            alertsIdList.push(storedAlert._doc._id.toString());

                            if (index == session.chosenLanguagesAlert.length - 1) {
                                subscribeUser(alertsIdList, session, bot, from);
                            }
                        }
                    }
                );
            });
        });
    } else {
        bot.sendMessage(from.id, nextEpisodeNotAvailableMessage);
        Common.resetValues(session);
    }
}

function subscribeUser(alertsList, session, bot, from) {
    var alertsToAdd = [];
    User.findOne({ chatId: from.id }, function (err, user) {
        if (!user) {
            var newUser = new User({
                chatId: from.id,
                first_name: from.first_name,
                alerts: alertsList
            });
            User.create(newUser, function (err, value) {
                if (err) console.log("error saving new user");
                bot.sendMessage(from.id, Common.successSubscribeMessage(session.choosenSeriesAlert.show.name));
                Common.resetValues(session);
            });
        } else {
            user._doc.alerts.addToSet(alertsList);
            user.save(function () {
                bot.sendMessage(from.id, Common.successSubscribeMessage(session.choosenSeriesAlert.show.name));
                Common.resetValues(session);
            });

        }
    });
}

exports.getAlertsFromUser = function (id, bot, session) {
    User.findOne({ chatId: id }, function (err, user) {
        if (!err && user && user._doc.alerts.length > 0) {
            let alertsId = user._doc.alerts.map(function (alert) { return new Mongoose.Types.ObjectId(alert); });
            Alert.find({ _id: { $in: alertsId } }, function (err, alerts) {
                if (!err && alerts && alerts.length > 0)
                    bot.sendMessage(id, Common.showAlertsMessage, BotGui.generateAlertsInlineKeyboard(alerts));
            });
        }
        else {
            bot.sendMessage(id, Common.noAlertMessage, BotGui.generateKeyboardOptions());
            Common.resetValues(session);
        }
    });
}

function deleteAlertIfNoUserSubscribed(alert) {
    const alertId = alert._id.toString();
    User.find({alerts: alertId}, function(err, users) {
        if(!err && users.length == 0){
            deleteAlert(alertId);
            ScheduleManager.cancelJob(alert.show_name + "_" + alert.language + "_interval");
        }
    });
}

exports.deleteAlertFromSingleUser = function (chatId, alert, userId, bot) {
    var tokens = alert.split("_");
    Alert.findOne({ show_name: tokens[0], language: tokens[1] }, function (err, foundAlert) {
        if (!err && foundAlert != null) {
            User.update({ chatId: chatId }, { $pullAll: { alerts: [foundAlert._doc._id.toString()] } }, function (err) {
                if (err) console.log("Error in updating alerts list of user. " + err);
                else {
                    console.log("Removed active alert: " + foundAlert._doc._id);
                    bot.sendMessage(chatId, Common.deletedAlertMessage, BotGui.generateKeyboardOptions());
                }
                deleteAlertIfNoUserSubscribed(foundAlert._doc);
            });
        }
        else
            console.log("Can't find alert ", foundAlert);
    });
}

var deleteAlert = function (alertId) {
    Alert.findByIdAndRemove(Mongoose.Types.ObjectId(alertId), function (err, foundAlert) {
        if (err) {
            console.log("Cannot remove alert because of: ", err);
        }
    });
}

exports.deleteAlertFromAllUsers = function (alert) {
    const alertId = alert._id.toString()
    User.update({ alerts: alertId }, { $pullAll: { alerts: [alertId] } }, function (err) {
        if (err) {
            console.log("Cannot remove alert from users because of: ", err);
        }
        else
            deleteAlertIfNoUserSubscribed(alert);
    });
}

exports.Alert = Alert;
exports.User = User;
exports.Language = Language;
exports.deleteAlert = deleteAlert;<commit_msg>fix typo<commit_after>var Resources = require('../conf.js');
var Mongoose = require('mongoose');
var Tunnel = require('tunnel-ssh');
var Conf = require('../conf.js');
var TvMaze = require('../libs/tvMaze.js');
var Common = require('../common.js');
var ScheduleManager = require('../schedule/scheduleManager.js');
var Logger = require('../log/logger.js');
var BotGui = require('../gui/keyboards.js');

var db = undefined;
var Schema = Mongoose.Schema;
//Mongoose.set('debug', true);

var Alert = Mongoose.model('Alert', new Schema({
    ids: String,
    show_name: String,
    showId: Number,
    language: Schema.Types.Mixed,
    nextepisode_airdate: String,
    nextepisode_season: Number,
    nextepisode_episode: Number
}, {
        _id: false
    }));
var User = Mongoose.model('User', new Schema({
    ids: String,
    chatId: Number,
    first_name: String,
    alerts: Array
}));
var Language = Mongoose.model('Language', new Schema({
    code: String,
    int: String,
    native: String
}, {
        _id: false
    }));

exports.getMongoConnection = function () {
    return db;
}

exports.connectToDatabase = function () {
    if (Conf.mongoHost == "") {
        var server = Tunnel(Conf.mongoConfig, function (error, server) {
            if (error) {
                console.log("SSH connection error: " + error);
            }
            Mongoose.connect('mongodb://localhost:' + Conf.mongoConfig.localPort + "/" + Conf.dbName,
            { server: { reconnectTries: Number.MAX_VALUE } });
            db = Mongoose.connection;
            db.on('error', () => {
                console.log('DB connection error ')
            });
            db.once('open', function () {
                console.log("DB connection successful");
                ScheduleManager.startAgenda();
            });
        });
    } else {
        Mongoose.connect('mongodb://localhost:' + Conf.mongoConfig.localPort + "/" + Conf.dbName,
            { server: { reconnectTries: Number.MAX_VALUE } });
        db = Mongoose.connection;
        db.on('error', () => {
            console.log('DB connection error ')
        });
        db.once('open', function () {
            console.log("DB connection successful");
            ScheduleManager.startAgenda();
        });
    }
}

exports.subscribe = function (session, bot, from) {
    Logger.logEvent("alert", [], session);
    var alertsToStore = [];
    var alertsIdList = [];
    if (session.choosenSeriesAlert.show._links.nextepisode) {
        var nextepisodePromise = TvMaze.getNextEpisodeInformation(session.choosenSeriesAlert.show._links.nextepisode.href);

        nextepisodePromise.then(function (nextepisode) {
            session.chosenLanguagesAlert.forEach(function (languageElement, index) {
                var alertToStore = new Alert({
                    show_name: session.choosenSeriesAlert.show.name,
                    showId: session.choosenSeriesAlert.show.id,
                    language: languageElement,
                    nextepisode_airdate: nextepisode.airdate,
                    nextepisode_season: nextepisode.season,
                    nextepisode_episode: nextepisode.number
                    //FOR DEBUG:
                    // nextepisode_airdate: "today",
                    // nextepisode_season: "1",
                    // nextepisode_episode: "1"
                });
                if (alertToStore._doc._id === undefined) {
                    delete alertToStore._doc._id;
                }
                Alert.findOneAndUpdate({ showId: alertToStore.showId, language: languageElement },
                    alertToStore, { new: true, upsert: true },
                    function (err, storedAlert) {
                        if (err) console.log("ERROR IN SAVE MONGO", err);
                        else {
                            ScheduleManager.activateStoredSchedules(storedAlert._doc, bot, false);
                            alertsIdList.push(storedAlert._doc._id.toString());

                            if (index == session.chosenLanguagesAlert.length - 1) {
                                subscribeUser(alertsIdList, session, bot, from);
                            }
                        }
                    }
                );
            });
        });
    } else {
        bot.sendMessage(from.id, Mongo.nextEpisodeNotAvailableMessage);
        Common.resetValues(session);
    }
}

function subscribeUser(alertsList, session, bot, from) {
    var alertsToAdd = [];
    User.findOne({ chatId: from.id }, function (err, user) {
        if (!user) {
            var newUser = new User({
                chatId: from.id,
                first_name: from.first_name,
                alerts: alertsList
            });
            User.create(newUser, function (err, value) {
                if (err) console.log("error saving new user");
                bot.sendMessage(from.id, Common.successSubscribeMessage(session.choosenSeriesAlert.show.name));
                Common.resetValues(session);
            });
        } else {
            user._doc.alerts.addToSet(alertsList);
            user.save(function () {
                bot.sendMessage(from.id, Common.successSubscribeMessage(session.choosenSeriesAlert.show.name));
                Common.resetValues(session);
            });

        }
    });
}

exports.getAlertsFromUser = function (id, bot, session) {
    User.findOne({ chatId: id }, function (err, user) {
        if (!err && user && user._doc.alerts.length > 0) {
            let alertsId = user._doc.alerts.map(function (alert) { return new Mongoose.Types.ObjectId(alert); });
            Alert.find({ _id: { $in: alertsId } }, function (err, alerts) {
                if (!err && alerts && alerts.length > 0)
                    bot.sendMessage(id, Common.showAlertsMessage, BotGui.generateAlertsInlineKeyboard(alerts));
            });
        }
        else {
            bot.sendMessage(id, Common.noAlertMessage, BotGui.generateKeyboardOptions());
            Common.resetValues(session);
        }
    });
}

function deleteAlertIfNoUserSubscribed(alert) {
    const alertId = alert._id.toString();
    User.find({alerts: alertId}, function(err, users) {
        if(!err && users.length == 0){
            deleteAlert(alertId);
            ScheduleManager.cancelJob(alert.show_name + "_" + alert.language + "_interval");
        }
    });
}

exports.deleteAlertFromSingleUser = function (chatId, alert, userId, bot) {
    var tokens = alert.split("_");
    Alert.findOne({ show_name: tokens[0], language: tokens[1] }, function (err, foundAlert) {
        if (!err && foundAlert != null) {
            User.update({ chatId: chatId }, { $pullAll: { alerts: [foundAlert._doc._id.toString()] } }, function (err) {
                if (err) console.log("Error in updating alerts list of user. " + err);
                else {
                    console.log("Removed active alert: " + foundAlert._doc._id);
                    bot.sendMessage(chatId, Common.deletedAlertMessage, BotGui.generateKeyboardOptions());
                }
                deleteAlertIfNoUserSubscribed(foundAlert._doc);
            });
        }
        else
            console.log("Can't find alert ", foundAlert);
    });
}

var deleteAlert = function (alertId) {
    Alert.findByIdAndRemove(Mongoose.Types.ObjectId(alertId), function (err, foundAlert) {
        if (err) {
            console.log("Cannot remove alert because of: ", err);
        }
    });
}

exports.deleteAlertFromAllUsers = function (alert) {
    const alertId = alert._id.toString()
    User.update({ alerts: alertId }, { $pullAll: { alerts: [alertId] } }, function (err) {
        if (err) {
            console.log("Cannot remove alert from users because of: ", err);
        }
        else
            deleteAlertIfNoUserSubscribed(alert);
    });
}

exports.Alert = Alert;
exports.User = User;
exports.Language = Language;
exports.deleteAlert = deleteAlert;<|endoftext|>