<commit_before>'use strict';
var fs = require('fs');
var path = require('path');
var chalk = require('chalk');
var dargs = require('dargs');
var gutil = require('gulp-util');
var spawn = require('win-spawn');
var eachAsync = require('each-async');
var intermediate = require('gulp-intermediate');

function rewriteSourcemapPaths (tempDir, origBase, cb) {
	var glob = require('glob');

	glob(path.join(tempDir, '**/*.map'), function (err, files) {
		if (err) {
			return cb(err);
		}

		eachAsync(files, function (file, index, done) {
			fs.readFile(file, function (err, data) {
				if (err) {
					return done(err);
				}

				var sourceMap = JSON.parse(data);

				// Rewrite sourcemaps to point to the original source files.
				sourceMap.sources = sourceMap.sources.map(function (source) {
					return path.join(origBase, source.replace(/\.\.\//g, ''));
				});

				fs.writeFile(file, JSON.stringify(sourceMap), done);
			});
		}, cb);
	});
}

module.exports = function (options) {
	var compileDir = '_14139e58-9ebe-4c0f-beca-73a65bb01ce9';
	options = options || {};
	options.cacheLocation = options.cacheLocation || path.join(__dirname, '.sass-cache');
	options.update = '.:' + compileDir;
	var args = dargs(options, ['bundleExec']);
	var command;

	// Error handling
	var noLogMatcher = /execvp\(\): No such file or directory|spawn ENOENT/;
	var bundleErrMatcher = /bundler: command not found|Could not find gem/;
	var bundleErr = chalk.red('Gemfile version of Sass not found. Install missing gems with `bundle install`.');

	if (options.bundleExec) {
		command = 'bundle';
		args.unshift('exec', 'sass');
	}
	else {
		command = 'sass';
	}

	return intermediate({ output: compileDir, container: 'gulp-ruby-sass' }, function(tempDir, cb, fileProps) {
		if (process.argv.indexOf('--verbose') !== -1) {
			gutil.log('gulp-ruby-sass:', 'Running command:',
				chalk.blue(command, args.join(' ')));
		}

		var sass = spawn(command, args, {cwd: tempDir});

		sass.stdout.on('data', function (data) {
			var msg = data.toString().trim();

			if (bundleErrMatcher.test(msg)) {
				gutil.log('gulp-ruby-sass:', bundleErr);
			}
			else {
				gutil.log('gulp-ruby-sass:', msg.replace(new RegExp(compileDir, 'g'), ''));
			}
		});

		sass.stderr.on('data', function (data) {
			var msg = data.toString().trim();

			if (bundleErrMatcher.test(msg)) {
				gutil.log('gulp-ruby-sass:', bundleErr);
			}
			else if (!noLogMatcher.test(msg)) {
				gutil.log('gulp-ruby-sass:', msg);
			}
		});

		sass.on('error', function (err) {
			var msg = err.toString().trim();

			if (!noLogMatcher.test(msg)) {
				gutil.log('gulp-ruby-sass:', chalk.red(msg));
			}
		});

		sass.on('close', function (code) {
			var dependencies = options.bundleExec ? 'Ruby, Bundler, and Sass' : 'Ruby and Sass';

			if (code === -1) {
				gutil.log('gulp-ruby-sass:', chalk.red('Missing dependencies. ' + dependencies + ' must be installed and available.'));
				return cb();
			}

			if (options.sourcemap) {
				rewriteSourcemapPaths(tempDir, fileProps.base, function (err) {
					if (err) {
						this.emit('error', new gutil.PluginError('gulp-ruby-sass', err));
					}

					cb();
				}.bind(this));
			}
			else {
				cb();
			}
		});
	});
};
<commit_msg>codestyle tweaks<commit_after>'use strict';
var fs = require('fs');
var path = require('path');
var chalk = require('chalk');
var dargs = require('dargs');
var gutil = require('gulp-util');
var spawn = require('win-spawn');
var eachAsync = require('each-async');
var intermediate = require('gulp-intermediate');

function rewriteSourcemapPaths (tempDir, origBase, cb) {
	var glob = require('glob');

	glob(path.join(tempDir, '**/*.map'), function (err, files) {
		if (err) {
			cb(err);
			return;
		}

		eachAsync(files, function (file, i, next) {
			fs.readFile(file, function (err, data) {
				if (err) {
					next(err);
					return;
				}

				var sourceMap = JSON.parse(data);

				// rewrite sourcemaps to point to the original source files
				sourceMap.sources = sourceMap.sources.map(function (source) {
					return path.join(origBase, source.replace(/\.\.\//g, ''));
				});

				fs.writeFile(file, JSON.stringify(sourceMap), next);
			});
		}, cb);
	});
}

module.exports = function (options) {
	var compileDir = '_14139e58-9ebe-4c0f-beca-73a65bb01ce9';
	options = options || {};
	options.cacheLocation = options.cacheLocation || path.join(__dirname, '.sass-cache');
	options.update = '.:' + compileDir;
	var args = dargs(options, ['bundleExec']);
	var command;

	// Error handling
	var noLogMatcher = /execvp\(\): No such file or directory|spawn ENOENT/;
	var bundleErrMatcher = /bundler: command not found|Could not find gem/;
	var bundleErr = chalk.red('Gemfile version of Sass not found. Install missing gems with `bundle install`.');

	if (options.bundleExec) {
		command = 'bundle';
		args.unshift('exec', 'sass');
	} else {
		command = 'sass';
	}

	return intermediate({
		output: compileDir,
		container: 'gulp-ruby-sass'
	}, function (tempDir, cb, fileProps) {
		if (process.argv.indexOf('--verbose') !== -1) {
			gutil.log('gulp-ruby-sass:', 'Running command:',
				chalk.blue(command, args.join(' ')));
		}

		var sass = spawn(command, args, {cwd: tempDir});

		sass.stdout.setEncoding('utf8');
		sass.stderr.setEncoding('utf8');

		sass.stdout.on('data', function (data) {
			var msg = data.trim();

			if (bundleErrMatcher.test(msg)) {
				gutil.log('gulp-ruby-sass:', bundleErr);
			} else {
				gutil.log('gulp-ruby-sass:', msg.replace(new RegExp(compileDir, 'g'), ''));
			}
		});

		sass.stderr.on('data', function (data) {
			var msg = data.trim();

			if (bundleErrMatcher.test(msg)) {
				gutil.log('gulp-ruby-sass:', bundleErr);
			} else if (!noLogMatcher.test(msg)) {
				gutil.log('gulp-ruby-sass:', msg);
			}
		});

		sass.on('error', function (err) {
			var msg = err.trim();

			if (!noLogMatcher.test(msg)) {
				gutil.log('gulp-ruby-sass:', chalk.red(msg));
			}
		});

		sass.on('close', function (code) {
			var dependencies = options.bundleExec ? 'Ruby, Bundler, and Sass' : 'Ruby and Sass';

			if (code === -1) {
				gutil.log('gulp-ruby-sass:', chalk.red('Missing dependencies. ' + dependencies + ' must be installed and available.'));
				return cb();
			}

			if (options.sourcemap) {
				rewriteSourcemapPaths(tempDir, fileProps.base, function (err) {
					if (err) {
						this.emit('error', new gutil.PluginError('gulp-ruby-sass', err));
					}

					cb();
				}.bind(this));
			} else {
				cb();
			}
		});
	});
};
<|endoftext|>


<commit_before>/* Copyright 2015, Yahoo Inc.
   Designed by Irae Carvalho
   Copyrights licensed under the MIT License.
   See the accompanying LICENSE file for terms. */

var ZingaScroller = require('../vendor/zynga.scroller.js');

function ScrollerEvents(domNode, handler, config) {
  if (this.constructor !== ScrollerEvents) {
    return new ScrollerEvents(domNode, handler, config);
  }

  this._node = domNode;
  this._scroller = new ZingaScroller(handler, {

    //scrolling options
    penetrationDeceleration: config.penetrationDeceleration,
    penetrationAcceleration: config.penetrationAcceleration,
    frictionFactor: config.frictionFactor,
    minVelocityToKeepDecelerating: config.minVelocityToKeepDecelerating,

    scrollingX: config.scrollingX,
    scrollingY: config.scrollingY,
    scrollingStarted: this._started.bind(this),
    scrollingComplete: this._stopped.bind(this),
  });

  // Store ScrollerEvents instances during event capturing
  domNode.addEventListener("touchstart",  this._storeScrollers.bind(this), true);
  domNode.addEventListener("touchmove",   this._storeScrollers.bind(this), true);
  domNode.addEventListener("touchend",    this._storeScrollers.bind(this), true);
  domNode.addEventListener("touchcancel", this._storeScrollers.bind(this), true);
  // Then act on this information during bubbling
  domNode.addEventListener("touchstart",  this._touchStart.bind(this), false);
  domNode.addEventListener("touchmove",   this._touchMove.bind(this),  false);
  domNode.addEventListener("touchend",    this._touchEnd.bind(this),   false);
  domNode.addEventListener("touchcancel", this._touchEnd.bind(this),   false);

  return this;
}

function inViewport (touch) {
  return touch.pageX >= 0 &&
         touch.pageX <= window.innerWidth,
         touch.pageY >= 0 &&
         touch.pageY <= window.innerHeight;
}

var members = {
  _disabled: false,
  _temp_disabled: false,
  _isParentScrolling: false,

  /*
    Temporary Disabled is meant for animation purposes.
    It will be stronger then disable itself. During temporary disable
    calling `.enable()` or `.disable()` will just schedule this for when
    restoration is called.
  */
  temporaryDisable: function() {
    if (!this._temp_disabled) {
      this._restore_disabled = this._disabled;
      this._temp_disabled = true;
      this._disabled = true;
    }
  },
  restoreTempDisabled: function() {
    this._temp_disabled = false;
    this._disabled = this._restore_disabled;
  },

  disable: function() {
    this._restore_disabled = true;
    this._disabled = true;
  },
  enable: function() {
    this._restore_disabled = false;
    if (!this._temp_disabled) {
      this._disabled = false;
    }
  },

  _scrolling: false,
  _started: function() {
    this._scrolling = true;
    this.stopEvents();
    var scrollStateChanged = document.createEvent('Event');
    scrollStateChanged.initEvent('scrollStateChanged', true, true);
    scrollStateChanged.state = 'scrolling';
    this._node.dispatchEvent(scrollStateChanged);
  },
  _stopped: function() {
    this._scrolling = false;
    this.resumeEvents();
    var scrollStateChanged = document.createEvent('Event');
    scrollStateChanged.initEvent('scrollStateChanged', true, true);
    scrollStateChanged.state = 'stopped';
    this._node.dispatchEvent(scrollStateChanged);
  },

  stopEvents: function() {
    this._node.firstChild.style.pointerEvents = "none";
  },
  resumeEvents: function() {
    this._node.firstChild.style.pointerEvents = "inherit";
  },

  setDimensions: function(containerWidth, containerHeight, contentWidth, contentHeight) {
    this._scroller.setDimensions(containerWidth, containerHeight, contentWidth, contentHeight);
  },

  scrollTo: function(left, top, animate, zoom) {
    this._scroller.scrollTo(left, top, animate, zoom);
  },

  _storeScrollers: function(event) {
    var scrollers = (event.__scrollers = event.__scrollers || []);
    var len = scrollers.length;
    if (len) {
      var parent = scrollers[len-1];
      this._isParentScrolling = parent._scrolling || parent._isParentScrolling || false;
    }
    scrollers.push(this);
  },

  _touchStart: function(event) {
    if (event.touches[0] && event.touches[0].target && event.touches[0].target.tagName.match(/input|textarea|select/i)) {
      return;
    }

    var scroller = this._scroller;
    if (!this._isParentScrolling && !this._disabled) {
       scroller.doTouchStart(event.touches, event.timeStamp);
    }
    var isMoving = scroller.__enableScrollX || scroller.__enableScrollY || scroller.__isDecelerating || scroller.__isAnimating;
    if (isMoving) {
      event.preventDefault();
      event.stopPropagation();
    }
  },

  _touchMove: function(event) {
    var scroller = this._scroller;

    /*
    If gesture ends outside a webview we don't get a touchEnd event
      so scroll never ends
    The way to fix that is by checking that the touchMove
      was triggered outside the viewport bounds and force
      the scroll to end
    */
    if (!inViewport(event.touches[0])){
      return this._touchEnd(event);
    }

    if (!this._isParentScrolling && !this._disabled) {
       scroller.doTouchMove(event.touches, event.timeStamp, event.scale);
    }
    var isMoving = scroller.__enableScrollX || scroller.__enableScrollY || scroller.__isDecelerating || scroller.__isAnimating;
    if (isMoving) {
      event.stopPropagation();
    }
    event.preventDefault(); // unconditionally to prevent React onScroll handlers
  },

  _touchEnd: function(event) {
    var scroller = this._scroller;
    if (!this._isParentScrolling && !this._disabled) {
       scroller.doTouchEnd(event.timeStamp);
    }
    var isMoving = scroller.__enableScrollX || scroller.__enableScrollY || scroller.__isDecelerating || scroller.__isAnimating;
    if (isMoving) {
      event.preventDefault();
      event.stopPropagation();
    }
  },
};

for(var key in members) {
  ScrollerEvents.prototype[key] = members[key];
}

module.exports = ScrollerEvents;
<commit_msg>removes equality in inViewport function<commit_after>/* Copyright 2015, Yahoo Inc.
   Designed by Irae Carvalho
   Copyrights licensed under the MIT License.
   See the accompanying LICENSE file for terms. */

var ZingaScroller = require('../vendor/zynga.scroller.js');

function ScrollerEvents(domNode, handler, config) {
  if (this.constructor !== ScrollerEvents) {
    return new ScrollerEvents(domNode, handler, config);
  }

  this._node = domNode;
  this._scroller = new ZingaScroller(handler, {

    //scrolling options
    penetrationDeceleration: config.penetrationDeceleration,
    penetrationAcceleration: config.penetrationAcceleration,
    frictionFactor: config.frictionFactor,
    minVelocityToKeepDecelerating: config.minVelocityToKeepDecelerating,

    scrollingX: config.scrollingX,
    scrollingY: config.scrollingY,
    scrollingStarted: this._started.bind(this),
    scrollingComplete: this._stopped.bind(this),
  });

  // Store ScrollerEvents instances during event capturing
  domNode.addEventListener("touchstart",  this._storeScrollers.bind(this), true);
  domNode.addEventListener("touchmove",   this._storeScrollers.bind(this), true);
  domNode.addEventListener("touchend",    this._storeScrollers.bind(this), true);
  domNode.addEventListener("touchcancel", this._storeScrollers.bind(this), true);
  // Then act on this information during bubbling
  domNode.addEventListener("touchstart",  this._touchStart.bind(this), false);
  domNode.addEventListener("touchmove",   this._touchMove.bind(this),  false);
  domNode.addEventListener("touchend",    this._touchEnd.bind(this),   false);
  domNode.addEventListener("touchcancel", this._touchEnd.bind(this),   false);

  return this;
}

function inViewport (touch) {
  return touch.pageX > 0 &&
         touch.pageX < window.innerWidth,
         touch.pageY > 0 &&
         touch.pageY < window.innerHeight;
}

var members = {
  _disabled: false,
  _temp_disabled: false,
  _isParentScrolling: false,

  /*
    Temporary Disabled is meant for animation purposes.
    It will be stronger then disable itself. During temporary disable
    calling `.enable()` or `.disable()` will just schedule this for when
    restoration is called.
  */
  temporaryDisable: function() {
    if (!this._temp_disabled) {
      this._restore_disabled = this._disabled;
      this._temp_disabled = true;
      this._disabled = true;
    }
  },
  restoreTempDisabled: function() {
    this._temp_disabled = false;
    this._disabled = this._restore_disabled;
  },

  disable: function() {
    this._restore_disabled = true;
    this._disabled = true;
  },
  enable: function() {
    this._restore_disabled = false;
    if (!this._temp_disabled) {
      this._disabled = false;
    }
  },

  _scrolling: false,
  _started: function() {
    this._scrolling = true;
    this.stopEvents();
    var scrollStateChanged = document.createEvent('Event');
    scrollStateChanged.initEvent('scrollStateChanged', true, true);
    scrollStateChanged.state = 'scrolling';
    this._node.dispatchEvent(scrollStateChanged);
  },
  _stopped: function() {
    this._scrolling = false;
    this.resumeEvents();
    var scrollStateChanged = document.createEvent('Event');
    scrollStateChanged.initEvent('scrollStateChanged', true, true);
    scrollStateChanged.state = 'stopped';
    this._node.dispatchEvent(scrollStateChanged);
  },

  stopEvents: function() {
    this._node.firstChild.style.pointerEvents = "none";
  },
  resumeEvents: function() {
    this._node.firstChild.style.pointerEvents = "inherit";
  },

  setDimensions: function(containerWidth, containerHeight, contentWidth, contentHeight) {
    this._scroller.setDimensions(containerWidth, containerHeight, contentWidth, contentHeight);
  },

  scrollTo: function(left, top, animate, zoom) {
    this._scroller.scrollTo(left, top, animate, zoom);
  },

  _storeScrollers: function(event) {
    var scrollers = (event.__scrollers = event.__scrollers || []);
    var len = scrollers.length;
    if (len) {
      var parent = scrollers[len-1];
      this._isParentScrolling = parent._scrolling || parent._isParentScrolling || false;
    }
    scrollers.push(this);
  },

  _touchStart: function(event) {
    if (event.touches[0] && event.touches[0].target && event.touches[0].target.tagName.match(/input|textarea|select/i)) {
      return;
    }

    var scroller = this._scroller;
    if (!this._isParentScrolling && !this._disabled) {
       scroller.doTouchStart(event.touches, event.timeStamp);
    }
    var isMoving = scroller.__enableScrollX || scroller.__enableScrollY || scroller.__isDecelerating || scroller.__isAnimating;
    if (isMoving) {
      event.preventDefault();
      event.stopPropagation();
    }
  },

  _touchMove: function(event) {
    var scroller = this._scroller;

    /*
    If gesture ends outside a webview we don't get a touchEnd event
      so scroll never ends
    The way to fix that is by checking that the touchMove
      was triggered outside the viewport bounds and force
      the scroll to end
    */
    if (!inViewport(event.touches[0])){
      return this._touchEnd(event);
    }

    if (!this._isParentScrolling && !this._disabled) {
       scroller.doTouchMove(event.touches, event.timeStamp, event.scale);
    }
    var isMoving = scroller.__enableScrollX || scroller.__enableScrollY || scroller.__isDecelerating || scroller.__isAnimating;
    if (isMoving) {
      event.stopPropagation();
    }
    event.preventDefault(); // unconditionally to prevent React onScroll handlers
  },

  _touchEnd: function(event) {
    var scroller = this._scroller;
    if (!this._isParentScrolling && !this._disabled) {
       scroller.doTouchEnd(event.timeStamp);
    }
    var isMoving = scroller.__enableScrollX || scroller.__enableScrollY || scroller.__isDecelerating || scroller.__isAnimating;
    if (isMoving) {
      event.preventDefault();
      event.stopPropagation();
    }
  },
};

for(var key in members) {
  ScrollerEvents.prototype[key] = members[key];
}

module.exports = ScrollerEvents;
<|endoftext|>


<commit_before>/**
 *
 * SugarCRM Community Edition is a customer relationship management program developed by
 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
 *
 * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd.
 * Copyright (C) 2011 - 2018 SalesAgility Ltd.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by the
 * Free Software Foundation with the addition of the following permission added
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 *
 * 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 Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along with
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA.
 *
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
 * these Appropriate Legal Notices must retain the display of the "Powered by
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
 * reasonably feasible for technical reasons, the Appropriate Legal Notices must
 * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM".
 */

if(typeof(SimpleList) == 'undefined'){
	var Dom = YAHOO.util.Dom;
    SimpleList = function(){
        var editImage;
        var deleteImage;
        var ul_list;
        var jstransaction;
        var lastEdit;
        var isIE = isSupportedIE();
        return {
    init: function(editImage, deleteImage) {
        var ul = document.getElementById('ul1', 'drpdwn');
        SimpleList.lastEdit = null; // Bug 14662
        SimpleList.editImage = editImage;
        SimpleList.deleteImage = deleteImage;
        new YAHOO.util.DDTarget("ul1");

        Studio2.scrollZones = {}
        for (var i = 0; Dom.get("ul" + i); i++){
            Studio2.scrollZones["ul" + i] = Studio2.getScrollZones("ul" + i);
        }

        for (i=0;i<SimpleList.ul_list.length;i++){
            if ( typeof SimpleList.ul_list[i] != "number" && SimpleList.ul_list[i] == "" ) {
                SimpleList.ul_list[i] = SUGAR.language.get('ModuleBuilder', 'LBL_BLANK');
            }
            new Studio2.ListDD(SimpleList.ul_list[i], 'drpdwn', false);
        }
        YAHOO.util.Event.on("dropdownaddbtn", "click", this.addToList, 'dropdown_form');
        SimpleList.jstransaction = new JSTransaction();
        SimpleList.jstransaction.register('deleteDropDown', SimpleList.undoDeleteDropDown, SimpleList.undoDeleteDropDown);
        SimpleList.jstransaction.register('changeDropDownValue', SimpleList.undoDropDownChange, SimpleList.redoDropDownChange);

    },
    isValidDropDownKey : function(value){
    	if(value.match(/^[\w\d \.]+$/i) || value == "")
    		return true;

    	return false;
    },
    isBlank : function(value){
    	return value == SUGAR.language.get('ModuleBuilder', 'LBL_BLANK')
    			|| (typeof value != "number" && value == "");
    },
    addToList : function(event, form){
    	var drop_name = document.getElementById('drop_name');
    	var drop_value = document.getElementById('drop_value');
    	//Validate the dropdown key manually
    	removeFromValidate('dropdown_form', 'drop_name');
    	if(!SimpleList.isValidDropDownKey(escape(drop_name.value))) {
			addToValidate('dropdown_form', 'drop_name', 'error', false, SUGAR.language.get("ModuleBuilder", "LBL_JS_VALIDATE_KEY"));
    	}

    	if (!check_form("dropdown_form")) return;

        var ul1=YAHOO.util.Dom.get("ul1");

        var items = ul1.getElementsByTagName("li");
        for (i=0;i<items.length;i=i+1) {
            if((SimpleList.isBlank(items[i].id) && SimpleList.isBlank(escape(drop_name.value))) || items[i].id == escape(drop_name.value)){
                alert(SUGAR.language.get('ModuleBuilder', 'LBL_DROPDOWN_KEY_EXISTS'));
                return;
            }
            if((!SimpleList.isBlank(escape(drop_name.value)) && SimpleList.isBlank(escape(drop_value.value))) || (SimpleList.isBlank(escape(drop_name.value)) && !SimpleList.isBlank(escape(drop_value.value)))){
                alert(SUGAR.language.get('ModuleBuilder', 'LBL_DROPDOWN_BLANK_WARNING'));
                return;
            }
        }

        liObj = document.createElement('li');
        liObj.className = "draggable";
        if(escape(drop_name.value) == '' || !escape(drop_name.value)){
            liObj.id = SUGAR.language.get('ModuleBuilder', 'LBL_BLANK');
        }else{
            liObj.id = escape(drop_name.value);
        }

        var text1 = document.createElement('input');
        text1.type = 'hidden';
        text1.id = 'value_' + liObj.id;
        text1.name = 'value_' + liObj.id;
        text1.value = escape(drop_value.value);

        var html = "

"+liObj.id+"<input id='value_"+liObj.id+"' value=\""+escape(drop_value.value)+"\" type = 'hidden'>";
        if(drop_value.value == ""){
            html += "[" + SUGAR.language.get('ModuleBuilder', 'LBL_BLANK') + "]";
        }else{
            html += "["+YAHOO.lang.escapeHTML(drop_value.value)+"]";
        }
        html += "";
        html += "";
        html += "<input type='text' id='input_"+liObj.id+"' value=\""+YAHOO.lang.escapeHTML(drop_value.value)+"\" onchange='SimpleList.setDropDownValue(\""+liObj.id+"\", unescape(this.value), true)' >";
        html += "";
        html += "	"+SimpleList.editImage+"";
        html += " "+SimpleList.deleteImage+"";
        html += "

";

        liObj.innerHTML = html;
        ul1.appendChild(liObj);
        new Studio2.ListDD(liObj, 'drpdwn', false);
        drop_value.value = "";
        drop_name.value = "";
        drop_name.focus();

        SimpleList.jstransaction.record('deleteDropDown',{'id': liObj.id });

    },

    sortAscending: function ()
    {
        // now sort using a Shellsort - do this rather than by using the inbuilt sort function as we need to sort a complex DOM inplace
        var parent = YAHOO.util.Dom.get("ul1");
        var items = parent.getElementsByTagName("li") ;
        var increment = Math.floor ( items.length / 2 ) ;

        function swapItems(itemA, itemB) {
        	var placeholder = document.createElement ( "li" ) ;
            Dom.insertAfter(placeholder, itemA);
            Dom.insertBefore(itemA, itemB);
            Dom.insertBefore(itemB, placeholder);

            //Cleanup the placeholder element
            parent.removeChild(placeholder);
        }

        while ( increment > 0 )
        {
        	for (var i = increment; i < items.length; i++)
        	{
            	var j = i;
            	var id = items[i].id;
            	var iValue = document.getElementById( 'input_' + id ).value.toLowerCase() ;

            	while ( ( j >= increment ) && ( document.getElementById( 'input_' + items [j-increment].id ).value.toLowerCase() > iValue ) )
            	{
            		// logically, this is what we need to do: items [j] = items [j - increment];
            		// but we're working with the DOM through a NodeList (items) which is readonly, so things aren't that simple
            		// A placeholder will be used to keep track of where in the DOM the swap needs to take place
            		// especially with IE which enforces the prohibition on duplicate Ids, so copying nodes is problematic
            		swapItems(items [j], items [j - increment]);
                	j = j - increment;
            	}
            }

            if (increment == 2)
            	increment = 1;
            else
            	increment = Math.floor (increment / 2.2);
        }
    },
    sortDescending: function ()
    {
        this.sortAscending();
        var reverse = function ( children )
        {
            var parent = children [ 0 ] . parentNode ;
            var start = 0;
            if ( children [ 0 ].id == '-blank-' ) // don't include -blank- element in the sort
                start = 1 ;
            for ( var i = children.length - 1 ; i >= start ; i-- )
            {
                parent.appendChild ( children [ i ] ) ;
            }
        };
        reverse ( YAHOO.util.Dom.get("ul1").getElementsByTagName("li") ) ;
    },
    handleSave:function(){
         var parseList = function(ul, title) {
            var items = ul.getElementsByTagName("li");
            var out = [];
            for (i=0;i<items.length;i=i+1) {
                var name = items[i].id;
                var value = document.getElementById('value_'+name).value;
                out[i] = [ name , unescape(value) ];
            }
            return YAHOO.lang.JSON.stringify(out);
        };
        var ul1=YAHOO.util.Dom.get("ul1");
        var hasDeletedItem = false;
        for(j = 0; j < SimpleList.jstransaction.JSTransactions.length; j++){
            var liEl = new YAHOO.util.Element(SimpleList.jstransaction.JSTransactions[j]['data']['id']);
            if(liEl && liEl.hasClass('deleted'))
            	hasDeletedItem = true;
            	break;
        }
        if(hasDeletedItem) {
        	if(!confirm(SUGAR.language.get('ModuleBuilder', 'LBL_CONFIRM_SAVE_DROPDOWN')))
        		return false;
    	}

        for(j = 0; j < SimpleList.jstransaction.JSTransactions.length; j++){
            if(SimpleList.jstransaction.JSTransactions[j]['transaction'] == 'deleteDropDown'){
                var liEl = new YAHOO.util.Element(SimpleList.jstransaction.JSTransactions[j]['data']['id']);
                if(liEl && liEl.hasClass('deleted'))
                	ul1.removeChild(liEl.get("element"));
            }
        }
        var list = document.getElementById('list_value');

        var out = parseList(ul1, "List 1");
        list.value = out;
        ModuleBuilder.refreshDD_name = document.getElementById('dropdown_name').value;
        if (document.forms.popup_form)
        {
            ModuleBuilder.handleSave("dropdown_form", ModuleBuilder.refreshDropDown);
        }
        else
        {
            ModuleBuilder.handleSave("dropdown_form", ModuleBuilder.refreshGlobalDropDown);
        }
    },
    deleteDropDownValue : function(id, record){
        var field = new YAHOO.util.Element(id);
        if(record){
            SimpleList.jstransaction.record('deleteDropDown',{'id': id });
        }
        if (field.hasClass('deleted'))
            field.removeClass('deleted');
        else
            field.addClass('deleted');
    },
    editDropDownValue : function(id, record){
        //Close any other dropdown edits
        if (SimpleList)
            SimpleList.endCurrentDropDownEdit();
        var dispSpan = document.getElementById('span_'+id);
        var editSpan = document.getElementById('span_edit_'+id);
        dispSpan.style.display = 'none';

        if(SimpleList.isIE){
            editSpan.style.display = 'inline-block';
        }else{
            editSpan.style.display = 'inline';
        }
        var textbox = document.getElementById('input_'+id);
        textbox.focus();
        SimpleList.lastEdit = id;
    },
    endCurrentDropDownEdit : function() {
        if (SimpleList.lastEdit != null)
        {
            var valueLastEdit = unescape(document.getElementById('input_'+SimpleList.lastEdit).value);
            SimpleList.setDropDownValue(SimpleList.lastEdit,valueLastEdit,true);
        }
    },
    setDropDownValue : function(id, val, record){

        if(record){
            SimpleList.jstransaction.record('changeDropDownValue', {'id':id, 'new':val, 'old':document.getElementById('value_'+ id).value});
        }
        var dispSpan = document.getElementById('span_'+id);
        var editSpan = document.getElementById('span_edit_'+id);
        var textbox = document.getElementById('input_'+id);

        var value = escape(val);
        dispSpan.style.display = 'inline';
        editSpan.style.display = 'none';
        dispSpan.innerHTML = "["+value+"]";
        document.getElementById('value_'+ id).value = value;
        SimpleList.lastEdit = null; // Bug 14662 - clear the last edit point behind us
    },
    undoDeleteDropDown : function(transaction){

        SimpleList.deleteDropDownValue(transaction['id'], false);
    },
    undoDropDownChange : function(transaction){
        SimpleList.setDropDownValue(transaction['id'], transaction['old'], false);
    },
    redoDropDownChange : function(transaction){
        SimpleList.setDropDownValue(transaction['id'], transaction['new'], false);
    },
    undo : function(){
        SimpleList.jstransaction.undo();
    },
    redo : function(){
        SimpleList.jstransaction.redo();
    }
}//return
}();
}<commit_msg>Fixed #6786 -  Edit item list replace spaces with html entity "%20"(hotfix)<commit_after>/**
 *
 * SugarCRM Community Edition is a customer relationship management program developed by
 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
 *
 * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd.
 * Copyright (C) 2011 - 2018 SalesAgility Ltd.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by the
 * Free Software Foundation with the addition of the following permission added
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 *
 * 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 Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along with
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA.
 *
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
 * these Appropriate Legal Notices must retain the display of the "Powered by
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
 * reasonably feasible for technical reasons, the Appropriate Legal Notices must
 * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM".
 */

if(typeof(SimpleList) == 'undefined'){
	var Dom = YAHOO.util.Dom;
    SimpleList = function(){
        var editImage;
        var deleteImage;
        var ul_list;
        var jstransaction;
        var lastEdit;
        var isIE = isSupportedIE();
        return {
    init: function(editImage, deleteImage) {
        var ul = document.getElementById('ul1', 'drpdwn');
        SimpleList.lastEdit = null; // Bug 14662
        SimpleList.editImage = editImage;
        SimpleList.deleteImage = deleteImage;
        new YAHOO.util.DDTarget("ul1");

        Studio2.scrollZones = {}
        for (var i = 0; Dom.get("ul" + i); i++){
            Studio2.scrollZones["ul" + i] = Studio2.getScrollZones("ul" + i);
        }

        for (i=0;i<SimpleList.ul_list.length;i++){
            if ( typeof SimpleList.ul_list[i] != "number" && SimpleList.ul_list[i] == "" ) {
                SimpleList.ul_list[i] = SUGAR.language.get('ModuleBuilder', 'LBL_BLANK');
            }
            new Studio2.ListDD(SimpleList.ul_list[i], 'drpdwn', false);
        }
        YAHOO.util.Event.on("dropdownaddbtn", "click", this.addToList, 'dropdown_form');
        SimpleList.jstransaction = new JSTransaction();
        SimpleList.jstransaction.register('deleteDropDown', SimpleList.undoDeleteDropDown, SimpleList.undoDeleteDropDown);
        SimpleList.jstransaction.register('changeDropDownValue', SimpleList.undoDropDownChange, SimpleList.redoDropDownChange);

    },
    isValidDropDownKey : function(value){
    	if(value.match(/^[\w\d \.]+$/i) || value == "")
    		return true;

    	return false;
    },
    isBlank : function(value){
    	return value == SUGAR.language.get('ModuleBuilder', 'LBL_BLANK')
    			|| (typeof value != "number" && value == "");
    },
    addToList : function(event, form){
    	var drop_name = document.getElementById('drop_name');
    	var drop_value = document.getElementById('drop_value');
    	//Validate the dropdown key manually
    	removeFromValidate('dropdown_form', 'drop_name');
    	if(!SimpleList.isValidDropDownKey(escape(drop_name.value))) {
			addToValidate('dropdown_form', 'drop_name', 'error', false, SUGAR.language.get("ModuleBuilder", "LBL_JS_VALIDATE_KEY"));
    	}

    	if (!check_form("dropdown_form")) return;

        var ul1=YAHOO.util.Dom.get("ul1");

        var items = ul1.getElementsByTagName("li");
        for (i=0;i<items.length;i=i+1) {
            if((SimpleList.isBlank(items[i].id) && SimpleList.isBlank(escape(drop_name.value))) || items[i].id == escape(drop_name.value)){
                alert(SUGAR.language.get('ModuleBuilder', 'LBL_DROPDOWN_KEY_EXISTS'));
                return;
            }
            if((!SimpleList.isBlank(escape(drop_name.value)) && SimpleList.isBlank(escape(drop_value.value))) || (SimpleList.isBlank(escape(drop_name.value)) && !SimpleList.isBlank(escape(drop_value.value)))){
                alert(SUGAR.language.get('ModuleBuilder', 'LBL_DROPDOWN_BLANK_WARNING'));
                return;
            }
        }

        liObj = document.createElement('li');
        liObj.className = "draggable";
        if(escape(drop_name.value) == '' || !escape(drop_name.value)){
            liObj.id = SUGAR.language.get('ModuleBuilder', 'LBL_BLANK');
        }else{
            liObj.id = escape(drop_name.value);
        }

        var text1 = document.createElement('input');
        text1.type = 'hidden';
        text1.id = 'value_' + liObj.id;
        text1.name = 'value_' + liObj.id;
        text1.value = escape(drop_value.value);

        var html = "

"+liObj.id+"<input id='value_"+liObj.id+"' value=\""+escape(drop_value.value)+"\" type = 'hidden'>";
        if(drop_value.value == ""){
            html += "[" + SUGAR.language.get('ModuleBuilder', 'LBL_BLANK') + "]";
        }else{
            html += "["+YAHOO.lang.escapeHTML(drop_value.value)+"]";
        }
        html += "";
        html += "";
        html += "<input type='text' id='input_"+liObj.id+"' value=\""+YAHOO.lang.escapeHTML(drop_value.value)+"\" onchange='SimpleList.setDropDownValue(\""+liObj.id+"\", unescape(this.value), true)' >";
        html += "";
        html += "	"+SimpleList.editImage+"";
        html += " "+SimpleList.deleteImage+"";
        html += "

";

        liObj.innerHTML = html;
        ul1.appendChild(liObj);
        new Studio2.ListDD(liObj, 'drpdwn', false);
        drop_value.value = "";
        drop_name.value = "";
        drop_name.focus();

        SimpleList.jstransaction.record('deleteDropDown',{'id': liObj.id });

    },

    sortAscending: function ()
    {
        // now sort using a Shellsort - do this rather than by using the inbuilt sort function as we need to sort a complex DOM inplace
        var parent = YAHOO.util.Dom.get("ul1");
        var items = parent.getElementsByTagName("li") ;
        var increment = Math.floor ( items.length / 2 ) ;

        function swapItems(itemA, itemB) {
        	var placeholder = document.createElement ( "li" ) ;
            Dom.insertAfter(placeholder, itemA);
            Dom.insertBefore(itemA, itemB);
            Dom.insertBefore(itemB, placeholder);

            //Cleanup the placeholder element
            parent.removeChild(placeholder);
        }

        while ( increment > 0 )
        {
        	for (var i = increment; i < items.length; i++)
        	{
            	var j = i;
            	var id = items[i].id;
            	var iValue = document.getElementById( 'input_' + id ).value.toLowerCase() ;

            	while ( ( j >= increment ) && ( document.getElementById( 'input_' + items [j-increment].id ).value.toLowerCase() > iValue ) )
            	{
            		// logically, this is what we need to do: items [j] = items [j - increment];
            		// but we're working with the DOM through a NodeList (items) which is readonly, so things aren't that simple
            		// A placeholder will be used to keep track of where in the DOM the swap needs to take place
            		// especially with IE which enforces the prohibition on duplicate Ids, so copying nodes is problematic
            		swapItems(items [j], items [j - increment]);
                	j = j - increment;
            	}
            }

            if (increment == 2)
            	increment = 1;
            else
            	increment = Math.floor (increment / 2.2);
        }
    },
    sortDescending: function ()
    {
        this.sortAscending();
        var reverse = function ( children )
        {
            var parent = children [ 0 ] . parentNode ;
            var start = 0;
            if ( children [ 0 ].id == '-blank-' ) // don't include -blank- element in the sort
                start = 1 ;
            for ( var i = children.length - 1 ; i >= start ; i-- )
            {
                parent.appendChild ( children [ i ] ) ;
            }
        };
        reverse ( YAHOO.util.Dom.get("ul1").getElementsByTagName("li") ) ;
    },
    handleSave:function(){
         var parseList = function(ul, title) {
            var items = ul.getElementsByTagName("li");
            var out = [];
            for (i=0;i<items.length;i=i+1) {
                var name = items[i].id;
                var value = document.getElementById('value_'+name).value;
                out[i] = [ name , unescape(value) ];
            }
            return YAHOO.lang.JSON.stringify(out);
        };
        var ul1=YAHOO.util.Dom.get("ul1");
        var hasDeletedItem = false;
        for(j = 0; j < SimpleList.jstransaction.JSTransactions.length; j++){
            var liEl = new YAHOO.util.Element(SimpleList.jstransaction.JSTransactions[j]['data']['id']);
            if(liEl && liEl.hasClass('deleted'))
            	hasDeletedItem = true;
            	break;
        }
        if(hasDeletedItem) {
        	if(!confirm(SUGAR.language.get('ModuleBuilder', 'LBL_CONFIRM_SAVE_DROPDOWN')))
        		return false;
    	}

        for(j = 0; j < SimpleList.jstransaction.JSTransactions.length; j++){
            if(SimpleList.jstransaction.JSTransactions[j]['transaction'] == 'deleteDropDown'){
                var liEl = new YAHOO.util.Element(SimpleList.jstransaction.JSTransactions[j]['data']['id']);
                if(liEl && liEl.hasClass('deleted'))
                	ul1.removeChild(liEl.get("element"));
            }
        }
        var list = document.getElementById('list_value');

        var out = parseList(ul1, "List 1");
        list.value = out;
        ModuleBuilder.refreshDD_name = document.getElementById('dropdown_name').value;
        if (document.forms.popup_form)
        {
            ModuleBuilder.handleSave("dropdown_form", ModuleBuilder.refreshDropDown);
        }
        else
        {
            ModuleBuilder.handleSave("dropdown_form", ModuleBuilder.refreshGlobalDropDown);
        }
    },
    deleteDropDownValue : function(id, record){
        var field = new YAHOO.util.Element(id);
        if(record){
            SimpleList.jstransaction.record('deleteDropDown',{'id': id });
        }
        if (field.hasClass('deleted'))
            field.removeClass('deleted');
        else
            field.addClass('deleted');
    },
    editDropDownValue : function(id, record){
        //Close any other dropdown edits
        if (SimpleList)
            SimpleList.endCurrentDropDownEdit();
        var dispSpan = document.getElementById('span_'+id);
        var editSpan = document.getElementById('span_edit_'+id);
        dispSpan.style.display = 'none';

        if(SimpleList.isIE){
            editSpan.style.display = 'inline-block';
        }else{
            editSpan.style.display = 'inline';
        }
        var textbox = document.getElementById('input_'+id);
        textbox.focus();
        SimpleList.lastEdit = id;
    },
    endCurrentDropDownEdit : function() {
        if (SimpleList.lastEdit != null)
        {
            var valueLastEdit = unescape(document.getElementById('input_'+SimpleList.lastEdit).value);
            SimpleList.setDropDownValue(SimpleList.lastEdit,valueLastEdit,true);
        }
    },
    setDropDownValue : function(id, val, record){

        if(record){
            SimpleList.jstransaction.record('changeDropDownValue', {'id':id, 'new':val, 'old':document.getElementById('value_'+ id).value});
        }
        let dispSpan = document.getElementById('span_'+id);
        let editSpan = document.getElementById('span_edit_'+id);

        let value = encodeURI(val);
        dispSpan.style.display = 'inline';
        editSpan.style.display = 'none';
        value = decodeURI(value);
        dispSpan.innerHTML = "["+value+"]";
        document.getElementById('value_'+ id).value = value;
        SimpleList.lastEdit = null; // Bug 14662 - clear the last edit point behind us
    },
    undoDeleteDropDown : function(transaction){

        SimpleList.deleteDropDownValue(transaction['id'], false);
    },
    undoDropDownChange : function(transaction){
        SimpleList.setDropDownValue(transaction['id'], transaction['old'], false);
    },
    redoDropDownChange : function(transaction){
        SimpleList.setDropDownValue(transaction['id'], transaction['new'], false);
    },
    undo : function(){
        SimpleList.jstransaction.undo();
    },
    redo : function(){
        SimpleList.jstransaction.redo();
    }
}//return
}();
}<|endoftext|>


<commit_before>var request = require('request');
String.prototype.format = function() {
    var content = this;
    for (var i=0; i < arguments.length; i++)
    {
        var replacement = '{' + i + '}';
        content = content.replace(replacement, arguments[i]);
    }
    return content;
};

var me;
var tmdb = function(api_key) {
	me = this;
	this.api_key = api_key;
	this.config = null;
	this.base = 'http://api.themoviedb.org/3';
	this.api_urls =
		{
			configuration:              this.base+'/configuration?api_key='+this.api_key,
			misc_latest:                this.base+'/latest/movie?api_key='+this.api_key,
			misc_now_playing:           this.base+'/movie/now-playing?page={0}&api_key='+this.api_key,
			misc_popular:               this.base+'/movie/popular?page={0}&api_key='+this.api_key,
			misc_top_rated:             this.base+'/movie/top-rated?page={0}&api_key='+this.api_key,
			movie_info:                 this.base+'/movie/{0}?api_key='+this.api_key,
			movie_alternative_titles:   this.base+'/movie/{0}/alternative_titles?api_key='+this.api_key,
			movie_casts:                this.base+'/movie/{0}/casts?api_key='+this.api_key,
			movie_images:               this.base+'/movie/{0}/images?api_key='+this.api_key,
			movie_keywords:             this.base+'/movie/{0}/keywords?api_key='+this.api_key,
			movie_releases:             this.base+'/movie/{0}/releases?api_key='+this.api_key,
			movie_trailers:             this.base+'/movie/{0}/trailers?api_key='+this.api_key,
			movie_translations:         this.base+'/movie/{0}/translations?api_key='+this.api_key,
            movie_similar:              this.base+'/movie/{0}/similar_movies?page={1}&api_key='+this.api_key,
			person_info:                this.base+'/person/{0}?api_key='+this.api_key,
			person_credits:             this.base+'/person/{0}/credits?api_key='+this.api_key,
			person_images:              this.base+'/person/{0}/images?api_key='+this.api_key,
			collection_info:            this.base+'/collection/{0}?api_key='+this.api_key,
			search_movie:               this.base+'/search/movie?query={0}&page={1}&api_key='+this.api_key,
			search_person:              this.base+'/search/person?query={0}&page={1}&api_key='+this.api_key,
			auth_request_token:			this.base+'/authentication/token/new?api_key='+this.api_key,
			auth_session_id:			this.base+'/authentication/session/new?request_token={0}&api_key='+this.api_key,
			write_rate_movie:			this.base+'/movie/{0}/rating?session_id={1}&api_key='+this.api_key,
            company_info:               this.base+'/company/{0}?api_key='+this.api_key,
            company_movies:             this.base+'/company/{0}/movies?api_key='+this.api_key,
            account_info:               this.base+'/account?session_id={0}&api_key='+this.api_key,
            account_favorite_movies:    this.base+'/account/{0}/favorite_movies?session_id={1}&api_key='+this.api_key,
            account_rated_movies:       this.base+'/account/{0}/rated_movies?session_id={1}&api_key='+this.api_key,
            account_add_favorite:       this.base+'/account/{0}/favorite?session_id={1}&api_key='+this.api_key,
		};

	this.configuration(function(err,res) {
		if(!err) {
			me.config = res;
		} else {
			console.error('Error loading configuration: '+err);
		}
	});
};

/**
 * factory function
 **/
module.exports.init = function(apikey) {
	return new tmdb(apikey);
};

/**
 * misc methods
 * all but the 'latest'-function can be supplied with a page argument,
 * if page is left out the first page is returned
 **/
tmdb.prototype.misc = {
	latest: function(callback) {
		var url = me.api_urls.misc_latest;
		executeQuery({url: url}, callback);
	},
	nowPlaying: function(p, callback) {
		if(arguments.length === 1) {
			callback = p;
			var page = 1;
		} else {
			var page = ((typeof p !== 'number') ? page = 1 : page = p);
		}
		var url = me.api_urls.misc_now_playing.format(page);
		executeQuery({url: url}, callback);
	},
	popular: function(p, callback) {
		if(arguments.length === 1) {
			callback = p;
			var page = 1;
		} else {
			var page = ((typeof p !== 'number') ? page = 1 : page = p);
		}
		var url = me.api_urls.misc_popular.format(page);
		executeQuery({url: url}, callback);
	},
	topRated: function(p, callback) {
		if(arguments.length === 1) {
			callback = p;
			var page = 1;
		} else {
			var page = ((typeof p !== 'number') ? page = 1 : page = p);
		}
		var url = me.api_urls.misc_top_rated.format(page);
		executeQuery({url: url}, callback);
	},
};

/**
 * Get current configuration for constructing complete image urls
 **/
tmdb.prototype.configuration = function(callback) {
	var url = me.api_urls.configuration;
	executeQuery({url: url}, callback);
};

/**
 * movie methods
 * q = id (can be either tmdb id or imdb id)
 **/
tmdb.prototype.movie = {
    info: function(q, callback) {
        var url = me.api_urls.movie_info.format(q);
        executeQuery({url:url}, callback);
    },
    alternativeTitles: function(q, callback) {
        var url = me.api_urls.movie_alternative_titles.format(q);
        executeQuery({url:url}, callback);
    },
    casts: function(q, callback) {
        var url = me.api_urls.movie_casts.format(q);
        executeQuery({url:url}, callback);
    },
    images: function(q, callback) {
        var url = me.api_urls.movie_images.format(q);
        executeQuery({url:url}, callback);
    },
    keywords: function(q, callback) {
        var url = me.api_urls.movie_keywords.format(q);
        executeQuery({url:url}, callback);
    },
    releases: function(q, callback) {
        var url = me.api_urls.movie_releases.format(q);
        executeQuery({url:url}, callback);
    },
    trailers: function(q, callback) {
        var url = me.api_urls.movie_trailers.format(q);
        executeQuery({url:url}, callback);
    },
    translations: function(q, callback) {
        var url = me.api_urls.movie_translations.format(q);
        executeQuery({url:url}, callback);
    },
    similar: function(q, p, callback) {
        if(arguments.length === 2) {
            callback = p;
            p = 1;
        } else {
            if (typeof p !== 'number') { p = 1; }
        }
        var url = me.api_urls.movie_similar.format(q,p);
        executeQuery({url:url}, callback);
    }
};

/**
 * search methods
 * q = searchterm, p = page
 * page defaults to 1 if not specified or invalid
 **/
tmdb.prototype.search = {
    movie: function(q, p, callback) {
		if(arguments.length === 2) {
			callback = p;
			p = 1;
		} else {
			if (typeof p !== 'number') { p = 1; }
		}
        var url = me.api_urls.search_movie.format(q, p);
        executeQuery({url:url}, callback);
    },
    person: function(q, p, callback) {
		if(arguments.length === 2) {
			callback = p;
			p = 1;
		} else {
			if (typeof p !== 'number') { p = 1; }
		}
        var url = me.api_urls.search_person.format(q, p);
        executeQuery({url:url}, callback);
	},
};

/**
 * person methods
 * id = person id
 **/
tmdb.prototype.person = {
    info: function(id, callback) {
        var url = me.api_urls.person_info.format(id);
        executeQuery({url:url}, callback);
    },
    credits: function(id, callback) {
        var url = me.api_urls.person_credits.format(id);
        executeQuery({url:url}, callback);
    },
    images: function(id, callback) {
        var url = me.api_urls.person_images.format(id);
        executeQuery({url:url}, callback);
    },
};

/**
 * collection methods
 * id = collection id
 **/
tmdb.prototype.collection = {
    info: function(id, callback) {
        var url = me.api_urls.collection_info.format(id);
        executeQuery({url: url}, callback);
    },
};

/**
 * authentication methods
 **/
tmdb.prototype.authentication = {
	requestToken: function(callback) {
		var url = me.api_urls.auth_request_token;
		executeQuery({url:url}, callback);
	},
	sessionId: function(token, callback) {
		var url = me.api_urls.auth_session_id.format(token);
		executeQuery({url:url}, callback);
	}
};

/**
 * company methods
 **/
tmdb.prototype.company = {
    info: function(id, callback) {
        var url = me.api_urls.company_info.format(id);
        executeQuery({url: url}, callback);
    },
    movies: function(id, callback) {
        var url = me.api_urls.company_movies.format(id);
        executeQuery({url: url}, callback);
    },
};

/**
 * account methods
 **/
tmdb.prototype.account = {
    info: function(sid, callback) {
        var url = me.api_urls.account_info.format(sid);
        executeQuery({url: url}, callback);
    },
    favorite_movies: function(id, sid, callback) {
        var url = me.api_urls.account_favorite_movies.format(id,sid);
        executeQuery({url: url}, callback);
    },
    rated_movies: function(id, sid, callback) {
        var url = me.api_urls.account_rated_movies.format(id,sid);
        executeQuery({url: url}, callback);
    },
    add_favorite: function(aid, mid, sid, isfavorite, callback) {
        var url = me.api_urls.account_add_favorite.format(aid,sid);
        executePost({url: url},{movie_id: mid, favorite: isfavorite}, callback);
    },
};

/**
 * write methods
 * id = item id (movie id etc.)
 * sid = session id
 **/
tmdb.prototype.write = {
	rateMovie: function(id, sid, rating, callback) {
		var url = me.api_urls.write_rate_movie.format(id,sid);
		executePost({url:url}, {value:rating}, callback);
	},
};

/**
 * Sends the query to tmdb and ships the response of to be processed
 **/
var executeQuery = function(url,callback) {
    request(
        {
            uri:encodeURI(url.url),
            headers: {"Accept": 'application/json'}
        },
        function(err,res,body) {
            processQuery(url,err,res,body,callback);
        }
    );
}

/**
 * Processes the query response from TMDb
 **/
var processQuery = function(url, error, response, body, callback) {
    var res = null;
    try {
        res = JSON.parse(body);
    } catch(e) {
    }

    if(!error && response.statusCode === 200 && !res.status_code) {
        callback(undefined,res);
        return;
    }

	if(res.status_code) {
		switch(res.status_code) {
			case 6: // Invalid id
				callback(res,undefined);
				break;
			case 7: // Invalid API key
				callback(res,undefined);
				break;
			case 10: // API key suspended, not good
				callback(res,undefined);
				break;
			case 12: // The item/record was updated successfully
				callback(res,undefined);
				break;
			case 17: // Session denied
				callback(res,undefined);
				break;
		}
	} else {
		callback(error,res);
	}
}

/**
 * posts the data to TMDb and ships the response of to be processed
 **/
var executePost = function(url,data,callback) {
    request(
        {
			method: 'POST',
            uri:encodeURI(url.url),
			json: data,
            headers: {"Content-Type": 'application/json', "Accept": 'application/json'},
        },
        function(err,res,body) {
            processPost(url,err,res,body,callback);
        }
    );
}

/**
 * Processes the post response from TMDb
 **/
var processPost = function(url, error, response, body, callback) {
    var res = null;
    try {
        res = body;
    } catch(e) {
    }

    if(!error && response.statusCode === 200 && !res.status_code) {
        callback(undefined,res);
        return;
    }

	if(res.status_code) {
		switch(res.status_code) {
            case 5: // not valid json supplied
                callback(res,undefined);
                break;
			case 6: // Invalid id
				callback(res,undefined);
				break;
			case 7: // Invalid API key
				callback(res,undefined);
				break;
			case 10: // API key suspended, not good
				callback(res,undefined);
				break;
			case 12: // The item/record was updated successfully
				callback(undefined,res);
				break;
            case 13: // The item/record was deleted successfully
                callback(undefined,res);
                break;
			case 17: // Session denied
				callback(res,undefined);
				break;
		}
	} else {
		callback(error,res);
	}
}

<commit_msg>added new methods<commit_after>var request = require('request');
String.prototype.format = function() {
    var content = this;
    for (var i=0; i < arguments.length; i++)
    {
        var replacement = '{' + i + '}';
        content = content.replace(replacement, arguments[i]);
    }
    return content;
};

var me;
var tmdb = function(api_key) {
	me = this;
	this.api_key = api_key;
	this.config = null;
	this.base = 'http://api.themoviedb.org/3';
	this.api_urls =
		{
			configuration:              this.base+'/configuration?api_key='+this.api_key,
			misc_latest:                this.base+'/latest/movie?api_key='+this.api_key,
            misc_upcoming:              this.base+'/movie/upcoming?page={0}&api_key='+this.api_key,
			misc_now_playing:           this.base+'/movie/now-playing?page={0}&api_key='+this.api_key,
			misc_popular:               this.base+'/movie/popular?page={0}&api_key='+this.api_key,
			misc_top_rated:             this.base+'/movie/top-rated?page={0}&api_key='+this.api_key,
			movie_info:                 this.base+'/movie/{0}?api_key='+this.api_key,
			movie_alternative_titles:   this.base+'/movie/{0}/alternative_titles?api_key='+this.api_key,
			movie_casts:                this.base+'/movie/{0}/casts?api_key='+this.api_key,
			movie_images:               this.base+'/movie/{0}/images?api_key='+this.api_key,
			movie_keywords:             this.base+'/movie/{0}/keywords?api_key='+this.api_key,
			movie_releases:             this.base+'/movie/{0}/releases?api_key='+this.api_key,
			movie_trailers:             this.base+'/movie/{0}/trailers?api_key='+this.api_key,
			movie_translations:         this.base+'/movie/{0}/translations?api_key='+this.api_key,
            movie_similar:              this.base+'/movie/{0}/similar_movies?page={1}&api_key='+this.api_key,
			person_info:                this.base+'/person/{0}?api_key='+this.api_key,
			person_credits:             this.base+'/person/{0}/credits?api_key='+this.api_key,
			person_images:              this.base+'/person/{0}/images?api_key='+this.api_key,
			collection_info:            this.base+'/collection/{0}?api_key='+this.api_key,
			search_movie:               this.base+'/search/movie?query={0}&page={1}&api_key='+this.api_key,
			search_person:              this.base+'/search/person?query={0}&page={1}&api_key='+this.api_key,
            search_companies:           this.base+'/search/company?query={0}&page={1}&api_key='+this.api_key,
			auth_request_token:			this.base+'/authentication/token/new?api_key='+this.api_key,
			auth_session_id:			this.base+'/authentication/session/new?request_token={0}&api_key='+this.api_key,
			write_rate_movie:			this.base+'/movie/{0}/rating?session_id={1}&api_key='+this.api_key,
            company_info:               this.base+'/company/{0}?api_key='+this.api_key,
            company_movies:             this.base+'/company/{0}/movies?api_key='+this.api_key,
            account_info:               this.base+'/account?session_id={0}&api_key='+this.api_key,
            account_add_favorite:       this.base+'/account/{0}/favorite?session_id={1}&api_key='+this.api_key,
            account_favorite_movies:    this.base+'/account/{0}/favorite_movies?session_id={1}&api_key='+this.api_key,
            account_add_movie_watchlist: this.base+'/account/{0}/movie_watchlist?session_id={1}&api_key='+this.api_key,
            account_movie_watchlist:    this.base+'/account/{0}/movie_watchlist?session_id={1}&api_key='+this.api_key,
            account_rated_movies:       this.base+'/account/{0}/rated_movies?session_id={1}&api_key='+this.api_key,
            genre_list:                 this.base+'/genre/list?api_key='+this.api_key,
            genre_movies:               this.base+'/genre/{0}/movies?page={0}&page={1}&api_key='+this.api_key
		};

	this.configuration(function(err,res) {
		if(!err) {
			me.config = res;
		} else {
			console.error('Error loading configuration: '+err);
		}
	});
};

/**
 * factory function
 **/
module.exports.init = function(apikey) {
	return new tmdb(apikey);
};

/**
 * misc methods
 * all but the 'latest'-function can be supplied with a page argument,
 * if page is left out the first page is returned
 **/
tmdb.prototype.misc = {
    upcoming: function(p, callback) {
		if(arguments.length === 1) {
			callback = p;
			var page = 1;
		} else {
			var page = ((typeof p !== 'number') ? page = 1 : page = p);
		}
		var url = me.api_urls.misc_upcoming.format(page);
		executeQuery({url: url}, callback);
	},
	latest: function(callback) {
		var url = me.api_urls.misc_latest;
		executeQuery({url: url}, callback);
	},
	nowPlaying: function(p, callback) {
		if(arguments.length === 1) {
			callback = p;
			var page = 1;
		} else {
			var page = ((typeof p !== 'number') ? page = 1 : page = p);
		}
		var url = me.api_urls.misc_now_playing.format(page);
		executeQuery({url: url}, callback);
	},
	popular: function(p, callback) {
		if(arguments.length === 1) {
			callback = p;
			var page = 1;
		} else {
			var page = ((typeof p !== 'number') ? page = 1 : page = p);
		}
		var url = me.api_urls.misc_popular.format(page);
		executeQuery({url: url}, callback);
	},
	topRated: function(p, callback) {
		if(arguments.length === 1) {
			callback = p;
			var page = 1;
		} else {
			var page = ((typeof p !== 'number') ? page = 1 : page = p);
		}
		var url = me.api_urls.misc_top_rated.format(page);
		executeQuery({url: url}, callback);
	},
};

/**
 * genre methods
 **/
tmdb.prototype.genre = {
    list: function(callback) {
        var url = me.api_urls.genre_list;
        executeQuery({url:url}, callback);
    },

    movies: function(q, p, callback) {
        if(arguments.length === 2) {
            callback = p;
            p = 1;
        } else {
            if (typeof p !== 'number') { p = 1; }
        }
        var url = me.api_urls.genre_movies.format(q,p);
        executeQuery({url:url}, callback);
    }
};

/**
 * Get current configuration for constructing complete image urls
 **/
tmdb.prototype.configuration = function(callback) {
	var url = me.api_urls.configuration;
	executeQuery({url: url}, callback);
};

/**
 * movie methods
 * q = id (can be either tmdb id or imdb id)
 **/
tmdb.prototype.movie = {
    info: function(q, callback) {
        var url = me.api_urls.movie_info.format(q);
        executeQuery({url:url}, callback);
    },
    alternativeTitles: function(q, callback) {
        var url = me.api_urls.movie_alternative_titles.format(q);
        executeQuery({url:url}, callback);
    },
    casts: function(q, callback) {
        var url = me.api_urls.movie_casts.format(q);
        executeQuery({url:url}, callback);
    },
    images: function(q, callback) {
        var url = me.api_urls.movie_images.format(q);
        executeQuery({url:url}, callback);
    },
    keywords: function(q, callback) {
        var url = me.api_urls.movie_keywords.format(q);
        executeQuery({url:url}, callback);
    },
    releases: function(q, callback) {
        var url = me.api_urls.movie_releases.format(q);
        executeQuery({url:url}, callback);
    },
    trailers: function(q, callback) {
        var url = me.api_urls.movie_trailers.format(q);
        executeQuery({url:url}, callback);
    },
    translations: function(q, callback) {
        var url = me.api_urls.movie_translations.format(q);
        executeQuery({url:url}, callback);
    },
    similar: function(q, p, callback) {
        if(arguments.length === 2) {
            callback = p;
            p = 1;
        } else {
            if (typeof p !== 'number') { p = 1; }
        }
        var url = me.api_urls.movie_similar.format(q,p);
        executeQuery({url:url}, callback);
    }
};

/**
 * search methods
 * q = searchterm, p = page
 * page defaults to 1 if not specified or invalid
 **/
tmdb.prototype.search = {
    movie: function(q, p, callback) {
		if(arguments.length === 2) {
			callback = p;
			p = 1;
		} else {
			if (typeof p !== 'number') { p = 1; }
		}
        var url = me.api_urls.search_movie.format(q, p);
        executeQuery({url:url}, callback);
    },
    person: function(q, p, callback) {
		if(arguments.length === 2) {
			callback = p;
			p = 1;
		} else {
			if (typeof p !== 'number') { p = 1; }
		}
        var url = me.api_urls.search_person.format(q, p);
        executeQuery({url:url}, callback);
	},
    companies: function(q, p, callback) {
		if(arguments.length === 2) {
			callback = p;
			p = 1;
		} else {
			if (typeof p !== 'number') { p = 1; }
		}
        var url = me.api_urls.search_companies.format(q, p);
        executeQuery({url:url}, callback);
    },
};

/**
 * person methods
 * id = person id
 **/
tmdb.prototype.person = {
    info: function(id, callback) {
        var url = me.api_urls.person_info.format(id);
        executeQuery({url:url}, callback);
    },
    credits: function(id, callback) {
        var url = me.api_urls.person_credits.format(id);
        executeQuery({url:url}, callback);
    },
    images: function(id, callback) {
        var url = me.api_urls.person_images.format(id);
        executeQuery({url:url}, callback);
    },
};

/**
 * collection methods
 * id = collection id
 **/
tmdb.prototype.collection = {
    info: function(id, callback) {
        var url = me.api_urls.collection_info.format(id);
        executeQuery({url: url}, callback);
    },
};

/**
 * authentication methods
 **/
tmdb.prototype.authentication = {
	requestToken: function(callback) {
		var url = me.api_urls.auth_request_token;
		executeQuery({url:url}, callback);
	},
	sessionId: function(token, callback) {
		var url = me.api_urls.auth_session_id.format(token);
		executeQuery({url:url}, callback);
	}
};

/**
 * company methods
 **/
tmdb.prototype.company = {
    info: function(id, callback) {
        var url = me.api_urls.company_info.format(id);
        executeQuery({url: url}, callback);
    },
    movies: function(id, callback) {
        var url = me.api_urls.company_movies.format(id);
        executeQuery({url: url}, callback);
    },
};

/**
 * account methods
 **/
tmdb.prototype.account = {
    info: function(sid, callback) {
        var url = me.api_urls.account_info.format(sid);
        executeQuery({url: url}, callback);
    },
    favorite_movies: function(id, sid, callback) {
        var url = me.api_urls.account_favorite_movies.format(id,sid);
        executeQuery({url: url}, callback);
    },
    rated_movies: function(id, sid, callback) {
        var url = me.api_urls.account_rated_movies.format(id,sid);
        executeQuery({url: url}, callback);
    },
    add_favorite: function(aid, mid, sid, isfavorite, callback) {
        var url = me.api_urls.account_add_favorite.format(aid,sid);
        executePost({url: url},{movie_id: mid, favorite: isfavorite}, callback);
    },
    movie_watchlist: function(id, sid, callback) {
        var url = me.api_urls.account_movie_watchlist.format(id,sid);
        executeQuery({url: url}, callback);
    },
    add_movie_watchlist: function(aid, mid, sid, isinwatchlist, callback) {
        var url = me.api_urls.account_add_movie_watchlist.format(aid,sid);
        executePost({url: url},{movie_id: mid, movie_watchlist: isinwatchlist}, callback);
    },
};

/**
 * write methods
 * id = item id (movie id etc.)
 * sid = session id
 **/
tmdb.prototype.write = {
	rateMovie: function(id, sid, rating, callback) {
		var url = me.api_urls.write_rate_movie.format(id,sid);
		executePost({url:url}, {value:rating}, callback);
	},
};

/**
 * Sends the query to tmdb and ships the response of to be processed
 **/
var executeQuery = function(url,callback) {
    request(
        {
            uri:encodeURI(url.url),
            headers: {"Accept": 'application/json'}
        },
        function(err,res,body) {
            processQuery(url,err,res,body,callback);
        }
    );
}

/**
 * Processes the query response from TMDb
 **/
var processQuery = function(url, error, response, body, callback) {
    var res = null;
    try {
        res = JSON.parse(body);
    } catch(e) {
    }

    if(!error && response.statusCode === 200 && !res.status_code) {
        callback(undefined,res);
        return;
    }

	if(res.status_code) {
		switch(res.status_code) {
			case 6: // Invalid id
				callback(res,undefined);
				break;
			case 7: // Invalid API key
				callback(res,undefined);
				break;
			case 10: // API key suspended, not good
				callback(res,undefined);
				break;
			case 12: // The item/record was updated successfully
				callback(res,undefined);
				break;
			case 17: // Session denied
				callback(res,undefined);
				break;
		}
	} else {
		callback(error,res);
	}
}

/**
 * posts the data to TMDb and ships the response of to be processed
 **/
var executePost = function(url,data,callback) {
    request(
        {
			method: 'POST',
            uri:encodeURI(url.url),
			json: data,
            headers: {"Content-Type": 'application/json', "Accept": 'application/json'},
        },
        function(err,res,body) {
            processPost(url,err,res,body,callback);
        }
    );
}

/**
 * Processes the post response from TMDb
 **/
var processPost = function(url, error, response, body, callback) {
    var res = null;
    try {
        res = body;
    } catch(e) {
    }

    if(!error && response.statusCode === 200 && !res.status_code) {
        callback(undefined,res);
        return;
    }

	if(res.status_code) {
		switch(res.status_code) {
            case 5: // not valid json supplied
                callback(res,undefined);
                break;
			case 6: // Invalid id
				callback(res,undefined);
				break;
			case 7: // Invalid API key
				callback(res,undefined);
				break;
			case 10: // API key suspended, not good
				callback(res,undefined);
				break;
			case 12: // The item/record was updated successfully
				callback(undefined,res);
				break;
            case 13: // The item/record was deleted successfully
                callback(undefined,res);
                break;
			case 17: // Session denied
				callback(res,undefined);
				break;
		}
	} else {
		callback(error,res);
	}
}

<|endoftext|>


<commit_before>/**
 * @providesModule Notifications
 */

'use strict';

import { NativeModules, DeviceEventEmitter, NetInfo, Platform } from 'react-native';
import invariant from 'invariant';

const { RNOneSignal } = NativeModules;

var Notifications = {
	onError: false,
	onNotificationOpened: false,
	onNotificationsRegistered: false
};

var _pendingNotifications = [];
var DEVICE_NOTIF_EVENT = 'remoteNotificationOpened';
var DEVICE_NOTIF_REG_EVENT = 'remoteNotificationsRegistered';
var DEVICE_IDS_AVAILABLE = 'idsAvailable';

/**
 * Configure local and remote notifications
 * @param {Object}		options
 * @param {function}	options.onNotificationOpened - Fired when a remote notification is received.
 * @param {function} 	options.onError - None
 */
Notifications.configure = function(options: Object) {
	if ( typeof options.onError !== 'undefined' ) {
		this.onError = options.onError;
	}

	if ( typeof options.onNotificationOpened !== 'undefined' ) {
		this.onNotificationOpened = options.onNotificationOpened;

		if (_pendingNotifications.length > 0) {
			var notification = _pendingNotifications.pop();
			this._onNotificationOpened(notification.message, notification.data, notification.isActive);
		}
	}

	if( typeof options.onNotificationsRegistered !== 'undefined' ) {
		this.onNotificationsRegistered = options.onNotificationsRegistered;
	}

	if( typeof options.onIdsAvailable !== 'undefined' ) {
		this.onIdsAvailable = options.onIdsAvailable;
	}

	function handleConnectionStateChange(isConnected) {
    if(!isConnected) return;

    RNOneSignal.configure();
    NetInfo.isConnected.removeEventListener('change', handleConnectionStateChange);
  }

  NetInfo.isConnected.fetch().then(isConnected => {
    if(isConnected) return RNOneSignal.configure();
    NetInfo.isConnected.addEventListener('change', handleConnectionStateChange);
  }).catch((...args)=>this.onError(args));
};

/* Unregister */
Notifications.unregister = function() {
	this.onNotificationOpened = false;
};

Notifications.requestPermissions = function(permissions) {
	var requestedPermissions = {};
	if (Platform.OS == 'ios') {
		if (permissions) {
			requestedPermissions = {
				alert: !!permissions.alert,
				badge: !!permissions.badge,
				sound: !!permissions.sound
			};
		} else {
			requestedPermissions = {
				alert: true,
				badge: true,
				sound: true
			};
		}
		RNOneSignal.requestPermissions(requestedPermissions);
	} else {
		console.log("This function is not supported on Android");
	}
};

Notifications.registerForPushNotifications = function(){
	if (Platform.OS == 'ios') {
		RNOneSignal.registerForPushNotifications();
	} else {
		console.log("This function is not supported on Android");
	}
};

Notifications.checkPermissions = function(callback: Function) {
	if (Platform.OS == 'ios') {
		invariant(
			typeof callback === 'function',
			'Must provide a valid callback'
		);
		RNOneSignal.checkPermissions(callback);
	} else {
		console.log("This function is not supported on Android");
	}
};

Notifications._onNotificationOpened = function(message, data, isActive) {
	if ( this.onNotificationOpened === false ) {
		var notification = {message: message, data: data, isActive: isActive};
		_pendingNotifications.push(notification);
		return;
	}
	this.onNotificationOpened(message, data, isActive);
};

Notifications._onNotificationsRegistered = function(payload) {
	if ( this.onNotificationsRegistered === false ) {
		return;
 	}
 	this.onNotificationsRegistered(payload);
};

Notifications.sendTag = function(key, value) {
	RNOneSignal.sendTag(key, value);
};

Notifications.sendTags = function(tags) {
	RNOneSignal.sendTags(tags || {});
};

Notifications.getTags = function(next) {
	RNOneSignal.getTags(next);
};

Notifications.deleteTag = function(key) {
	RNOneSignal.deleteTag(key);
};

Notifications.enableVibrate = function(enable) {
	if (Platform.OS == 'android') {
		RNOneSignal.enableVibrate(enable);
	} else {
		console.log("This function is not supported on iOS");
	}
};

Notifications.enableSound = function(enable) {
	if (Platform.OS == 'android') {
		RNOneSignal.enableSound(enable);
	} else {
		console.log("This function is not supported on iOS");
	}
};

Notifications.enableNotificationsWhenActive = function(enable) {
	if (Platform.OS == 'android') {
		RNOneSignal.enableNotificationsWhenActive(enable);
	} else {
		console.log("This function is not supported on iOS");
	}
};

Notifications.enableInAppAlertNotification = function(enable) {
	RNOneSignal.enableInAppAlertNotification(enable);
};

Notifications.setSubscription = function(enable) {
	RNOneSignal.setSubscription(enable);
};

Notifications.promptLocation = function() {
	if (Platform.OS == 'android') {
		RNOneSignal.promptLocation();
	} else {
		console.log("This function is not supported on iOS");
	}
};

Notifications.postNotification = function(contents, data, player_id) {
	if (Platform.OS == 'android') {
		RNOneSignal.postNotification(JSON.stringify(contents), JSON.stringify(data), player_id);
	} else {
		RNOneSignal.postNotification(contents, data, player_id);
	}
};

Notifications.clearOneSignalNotifications = function() {
	if (Platform.OS == 'android') {
		RNOneSignal.clearOneSignalNotifications();
	} else {
		console.log("This function is not supported on iOS");
	}
};

Notifications.cancelNotification = function(id) {
	if (Platform.OS == 'android') {
		RNOneSignal.cancelNotification(id);
	} else {
		console.log("This function is not supported on iOS");
	}
};

Notifications.idsAvailable = function(idsAvailable) {
	console.log('Please use the onIdsAvailable event instead, it can be defined in the register options');
};

DeviceEventEmitter.addListener(DEVICE_NOTIF_EVENT, function(notifData) {
	var message = notifData.message;
	var hasAdditionalData = notifData.additionalData !== null && typeof notifData.additionalData === 'object';
	var data = hasAdditionalData ? notifData.additionalData : null;
	var isActive = notifData.isActive;
	Notifications._onNotificationOpened(message, data, isActive);
});

DeviceEventEmitter.addListener(DEVICE_NOTIF_REG_EVENT, function(notifData) {
	Notifications._onNotificationsRegistered(notifData)
});

DeviceEventEmitter.addListener(DEVICE_IDS_AVAILABLE, function(idsAvailable) {
	if (Notifications.onIdsAvailable) {
		Notifications.onIdsAvailable(idsAvailable);
	}
});

module.exports = Notifications;
<commit_msg>Returns Meta data of notification<commit_after>/**
 * @providesModule Notifications
 */

'use strict';

import { NativeModules, DeviceEventEmitter, NetInfo, Platform } from 'react-native';
import invariant from 'invariant';

const { RNOneSignal } = NativeModules;

var Notifications = {
	onError: false,
	onNotificationOpened: false,
	onNotificationsRegistered: false
};

var _pendingNotifications = [];
var DEVICE_NOTIF_EVENT = 'remoteNotificationOpened';
var DEVICE_NOTIF_REG_EVENT = 'remoteNotificationsRegistered';
var DEVICE_IDS_AVAILABLE = 'idsAvailable';

/**
 * Configure local and remote notifications
 * @param {Object}		options
 * @param {function}	options.onNotificationOpened - Fired when a remote notification is received.
 * @param {function} 	options.onError - None
 */
Notifications.configure = function(options: Object) {
	if ( typeof options.onError !== 'undefined' ) {
		this.onError = options.onError;
	}

	if ( typeof options.onNotificationOpened !== 'undefined' ) {
		this.onNotificationOpened = options.onNotificationOpened;

		if (_pendingNotifications.length > 0) {
			var notification = _pendingNotifications.pop();
			this._onNotificationOpened(notification.message, notification.data, notification.isActive);
		}
	}

	if( typeof options.onNotificationsRegistered !== 'undefined' ) {
		this.onNotificationsRegistered = options.onNotificationsRegistered;
	}

	if( typeof options.onIdsAvailable !== 'undefined' ) {
		this.onIdsAvailable = options.onIdsAvailable;
	}

	function handleConnectionStateChange(isConnected) {
    if(!isConnected) return;

    RNOneSignal.configure();
    NetInfo.isConnected.removeEventListener('change', handleConnectionStateChange);
  }

  NetInfo.isConnected.fetch().then(isConnected => {
    if(isConnected) return RNOneSignal.configure();
    NetInfo.isConnected.addEventListener('change', handleConnectionStateChange);
  }).catch((...args)=>this.onError(args));
};

/* Unregister */
Notifications.unregister = function() {
	this.onNotificationOpened = false;
};

Notifications.requestPermissions = function(permissions) {
	var requestedPermissions = {};
	if (Platform.OS == 'ios') {
		if (permissions) {
			requestedPermissions = {
				alert: !!permissions.alert,
				badge: !!permissions.badge,
				sound: !!permissions.sound
			};
		} else {
			requestedPermissions = {
				alert: true,
				badge: true,
				sound: true
			};
		}
		RNOneSignal.requestPermissions(requestedPermissions);
	} else {
		console.log("This function is not supported on Android");
	}
};

Notifications.registerForPushNotifications = function(){
	if (Platform.OS == 'ios') {
		RNOneSignal.registerForPushNotifications();
	} else {
		console.log("This function is not supported on Android");
	}
};

Notifications.checkPermissions = function(callback: Function) {
	if (Platform.OS == 'ios') {
		invariant(
			typeof callback === 'function',
			'Must provide a valid callback'
		);
		RNOneSignal.checkPermissions(callback);
	} else {
		console.log("This function is not supported on Android");
	}
};

Notifications._onNotificationOpened = function(message, data, isActive) {
	if ( this.onNotificationOpened === false ) {
		var notification = {message: message, data: data, isActive: isActive};
		_pendingNotifications.push(notification);
		return;
	}
	this.onNotificationOpened(message, data, isActive);
};

Notifications._onNotificationsRegistered = function(payload) {
	if ( this.onNotificationsRegistered === false ) {
		return;
 	}
 	this.onNotificationsRegistered(payload);
};

Notifications.sendTag = function(key, value) {
	RNOneSignal.sendTag(key, value);
};

Notifications.sendTags = function(tags) {
	RNOneSignal.sendTags(tags || {});
};

Notifications.getTags = function(next) {
	RNOneSignal.getTags(next);
};

Notifications.deleteTag = function(key) {
	RNOneSignal.deleteTag(key);
};

Notifications.enableVibrate = function(enable) {
	if (Platform.OS == 'android') {
		RNOneSignal.enableVibrate(enable);
	} else {
		console.log("This function is not supported on iOS");
	}
};

Notifications.enableSound = function(enable) {
	if (Platform.OS == 'android') {
		RNOneSignal.enableSound(enable);
	} else {
		console.log("This function is not supported on iOS");
	}
};

Notifications.enableNotificationsWhenActive = function(enable) {
	if (Platform.OS == 'android') {
		RNOneSignal.enableNotificationsWhenActive(enable);
	} else {
		console.log("This function is not supported on iOS");
	}
};

Notifications.enableInAppAlertNotification = function(enable) {
	RNOneSignal.enableInAppAlertNotification(enable);
};

Notifications.setSubscription = function(enable) {
	RNOneSignal.setSubscription(enable);
};

Notifications.promptLocation = function() {
	if (Platform.OS == 'android') {
		RNOneSignal.promptLocation();
	} else {
		console.log("This function is not supported on iOS");
	}
};

Notifications.postNotification = function(contents, data, player_id) {
	if (Platform.OS == 'android') {
		RNOneSignal.postNotification(JSON.stringify(contents), JSON.stringify(data), player_id);
	} else {
		RNOneSignal.postNotification(contents, data, player_id);
	}
};

Notifications.clearOneSignalNotifications = function() {
	if (Platform.OS == 'android') {
		RNOneSignal.clearOneSignalNotifications();
	} else {
		console.log("This function is not supported on iOS");
	}
};

Notifications.cancelNotification = function(id) {
	if (Platform.OS == 'android') {
		RNOneSignal.cancelNotification(id);
	} else {
		console.log("This function is not supported on iOS");
	}
};

Notifications.idsAvailable = function(idsAvailable) {
	console.log('Please use the onIdsAvailable event instead, it can be defined in the register options');
};

DeviceEventEmitter.addListener(DEVICE_NOTIF_EVENT, function(notifData) {
	var message = notifData.message;
	var additionalData = notifData.additionalData !== '{}' ? JSON.parse(notifData.additionalData) : null;
	var hasAdditionalData = additionalData !== null && typeof additionalData === 'object';
	var data = hasAdditionalData ? additionalData : null;
	var isActive = notifData.isActive;
	Notifications._onNotificationOpened(message, data, isActive);
});

DeviceEventEmitter.addListener(DEVICE_NOTIF_REG_EVENT, function(notifData) {
	Notifications._onNotificationsRegistered(notifData)
});

DeviceEventEmitter.addListener(DEVICE_IDS_AVAILABLE, function(idsAvailable) {
	if (Notifications.onIdsAvailable) {
		Notifications.onIdsAvailable(idsAvailable);
	}
});

module.exports = Notifications;
<|endoftext|>


<commit_before>/* -----------------------------------------------
/* Author : Vincent Garreau  - vincentgarreau.com
/* Github : https://github.com/VincentGarreau/particles.js
/* ----------------------------------------------- */

function launchParticlesJS(the_id, params){

	/* particles.js variables */
	window.pJS = {
		canvas: {
			el: document.querySelector('#'+the_id+' > canvas'),
			w: document.querySelector('#'+the_id+' > canvas').offsetWidth,
			h: document.querySelector('#'+the_id+' > canvas').offsetHeight,
			color_hex_bg: '#15414e',
			opacity: 1
		},
		particles: {
			color_hex: '#ffffff',
			opacity: 1,
			size: 2.5,
			nb: 200,
			array: [],
			anim: {
				speed: 1
			}
		},
		retina_detect: true,
		interactivity: {},
		fn: {}
	};

	/* params settings */
	if(params){
		pJS.canvas.color_hex_bg = params.canvas.color_hex_bg;
		pJS.canvas.opacity = params.canvas.opacity;
		pJS.particles.color_hex = params.particles.color_hex;
		pJS.particles.opacity = params.particles.opacity;
		pJS.particles.size = params.particles.size;
		pJS.particles.nb = params.particles.nb;
		pJS.particles.anim.speed = params.particles.anim.speed;
		pJS.retina_detect = params.retina_detect;
	}

	/* convert hex colors to rgb */
	pJS.canvas.color_rgb_bg = hexToRgb(pJS.canvas.color_hex_bg);
	pJS.particles.color_rgb = hexToRgb(pJS.particles.color_hex);

	/* detect retina */
	if(pJS.retina_detect){
		if(window.devicePixelRatio > 1){
			pJS.retina = true;
			pJS.canvas.w = pJS.canvas.el.offsetWidth*2;
			pJS.canvas.h = pJS.canvas.el.offsetHeight*2;
			pJS.particles.anim.speed = pJS.particles.anim.speed*2;
		}
	};

	/* ---------- CANVAS functions ------------ */

	pJS.fn.canvasInit = function(){
		pJS.canvas.ctx = pJS.canvas.el.getContext('2d');
	};

	pJS.fn.canvasSize = function(){
		pJS.canvas.el.width = pJS.canvas.w;
		pJS.canvas.el.height = pJS.canvas.h;

		window.onresize = function(){
			/* resize canvas */
			if(pJS.retina){
				pJS.canvas.w = pJS.canvas.el.offsetWidth*2;
				pJS.canvas.h = pJS.canvas.el.offsetHeight*2;
			}else{
				pJS.canvas.w = pJS.canvas.el.offsetWidth;
				pJS.canvas.h = pJS.canvas.el.offsetHeight;
			}
			pJS.canvas.el.width = pJS.canvas.w;
			pJS.canvas.el.height = pJS.canvas.h;

			/* repaint canvas */
			pJS.fn.canvasPaint();
		}
	};

	pJS.fn.canvasPaint = function(){
		pJS.canvas.ctx.fillStyle = 'rgba('+pJS.canvas.color_rgb_bg.r+','+pJS.canvas.color_rgb_bg.g+','+pJS.canvas.color_rgb_bg.b+','+pJS.canvas.opacity+')';
		pJS.canvas.ctx.fillRect(0, 0, pJS.canvas.w, pJS.canvas.h);
	};

	/* --------- PARTICLES functions ----------- */

	pJS.fn.particle = function(color, opacity){

		/* position */
		this.x = Math.random() * pJS.canvas.w;
		this.y = Math.random() * pJS.canvas.h;

		/* size */
		if(pJS.retina){
			this.radius = Math.random() * pJS.particles.size * 2;
		}else{
			this.radius = Math.random() * pJS.particles.size * 1;
		}

		/* color */
		this.color = color;

		/* opacity */
		this.opacity = opacity;

		/* animation - velocity for speed */
		this.vx = -.5 + Math.random() * 1;
		this.vy = -.5 + Math.random() * 1;

		/* draw function */
		this.draw = function(){
			pJS.canvas.ctx.fillStyle = 'rgba('+this.color.r+','+this.color.g+','+this.color.b+','+this.opacity+')';
			pJS.canvas.ctx.beginPath();
			pJS.canvas.ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
			pJS.canvas.ctx.fill();
		}

	};

	pJS.fn.particlesCreate = function(){
		for(var i = 0; i < pJS.particles.nb; i++) {
			pJS.particles.array.push(new pJS.fn.particle(pJS.particles.color_rgb, pJS.particles.opacity));
		}
	};

	pJS.fn.particlesAnimate = function(){
		for(var i = 0; i < pJS.particles.array.length; i++){
			/* the particle */
			var p = pJS.particles.array[i];

			/* move the particle */
			p.x += p.vx * pJS.particles.anim.speed;
			p.y += p.vy * pJS.particles.anim.speed;

			/* change particle position if it is out of window */
			if(p.x + p.radius > pJS.canvas.w) p.x = p.radius;
			else if(p.x - p.radius < 0) p.x = pJS.canvas.w - p.radius;
			if(p.y + p.radius > pJS.canvas.h) p.y = p.radius;
			else if(p.y - p.radius < 0) p.y = pJS.canvas.h - p.radius;
		}
	};

	pJS.fn.particlesDraw = function(){
		/* repaint canvas */
		pJS.fn.canvasPaint();

		/* draw each particle */
		for(var i = 0; i < pJS.particles.array.length; i++){
			var p = pJS.particles.array[i];
			p.draw('rgba('+p.color.r+','+p.color.g+','+p.color.b+','+p.opacity+')');
		}

		/* move particle */
		pJS.fn.particlesAnimate();
	};

	/* --------- LAUNCH ----------- */

	function launchParticles(){
		pJS.fn.canvasInit();
		pJS.fn.canvasSize();
		pJS.fn.canvasPaint();
		pJS.fn.particlesCreate();
		pJS.fn.particlesDraw();
	};

	launchParticles();

	function launchAnimation(){
		pJS.fn.particlesDraw();
		requestAnimFrame(launchAnimation);
	};

	launchAnimation();

};

/* --- VENDORS --- */

window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
		  window.webkitRequestAnimationFrame ||
		  window.mozRequestAnimationFrame    ||
		  window.oRequestAnimationFrame      ||
		  window.msRequestAnimationFrame     ||
		  function(callback){
			window.setTimeout(callback, 1000 / 60);
		  };
})();

function hexToRgb(hex){
    // By Tim Down - http://stackoverflow.com/a/5624139/3493650
    // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
    var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
    hex = hex.replace(shorthandRegex, function(m, r, g, b) {
        return r + r + g + g + b + b;
    });
    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16)
    } : null;
};

/* --- LAUNCH --- */

window.particlesJS = function(the_id, params){
	if(!the_id){ the_id = 'particles-js'; }
	/* create canvas element */
	var canvas_el = document.createElement('canvas');
	canvas_el.style.width = "100%";
	canvas_el.style.height = "100%";
	var canvas = document.getElementById(the_id).appendChild(canvas_el);
	/* launch particle.js */
	if(canvas != null){
		launchParticlesJS(the_id, params);
	}
};<commit_msg>beautify vars<commit_after>/* -----------------------------------------------
/* Author : Vincent Garreau  - vincentgarreau.com
/* Github : https://github.com/VincentGarreau/particles.js
/* ----------------------------------------------- */

function launchParticlesJS(the_id, params){

	/* particles.js variables */
	pJS = {
		canvas: {
			el: document.querySelector('#'+the_id+' > canvas'),
			w: document.querySelector('#'+the_id+' > canvas').offsetWidth,
			h: document.querySelector('#'+the_id+' > canvas').offsetHeight,
			color_hex_bg: '#15414e',
			opacity: 1
		},
		particles: {
			color_hex: '#ffffff',
			opacity: 1,
			size: 2.5,
			nb: 200,
			array: [],
			anim: {
				speed: 1
			}
		},
		retina_detect: true,
		interactivity: {},
		fn: {}
	};

	/* params settings */
	if(params){
		pJS.canvas.color_hex_bg = params.canvas.color_hex_bg;
		pJS.canvas.opacity = params.canvas.opacity;
		pJS.particles.color_hex = params.particles.color_hex;
		pJS.particles.opacity = params.particles.opacity;
		pJS.particles.size = params.particles.size;
		pJS.particles.nb = params.particles.nb;
		pJS.particles.anim.speed = params.particles.anim.speed;
		pJS.retina_detect = params.retina_detect;
	}

	/* convert hex colors to rgb */
	pJS.canvas.color_rgb_bg = hexToRgb(pJS.canvas.color_hex_bg);
	pJS.particles.color_rgb = hexToRgb(pJS.particles.color_hex);

	/* detect retina */
	if(pJS.retina_detect){
		if(window.devicePixelRatio > 1){
			pJS.retina = true;
			pJS.canvas.w = pJS.canvas.el.offsetWidth*2;
			pJS.canvas.h = pJS.canvas.el.offsetHeight*2;
			pJS.particles.anim.speed = pJS.particles.anim.speed*2;
		}
	};

	/* ---------- CANVAS functions ------------ */

	pJS.fn.canvasInit = function(){
		pJS.canvas.ctx = pJS.canvas.el.getContext('2d');
	};

	pJS.fn.canvasSize = function(){
		pJS.canvas.el.width = pJS.canvas.w;
		pJS.canvas.el.height = pJS.canvas.h;

		window.onresize = function(){
			/* resize canvas */
			if(pJS.retina){
				pJS.canvas.w = pJS.canvas.el.offsetWidth*2;
				pJS.canvas.h = pJS.canvas.el.offsetHeight*2;
			}else{
				pJS.canvas.w = pJS.canvas.el.offsetWidth;
				pJS.canvas.h = pJS.canvas.el.offsetHeight;
			}
			pJS.canvas.el.width = pJS.canvas.w;
			pJS.canvas.el.height = pJS.canvas.h;

			/* repaint canvas */
			pJS.fn.canvasPaint();
		}
	};

	pJS.fn.canvasPaint = function(){
		pJS.canvas.ctx.fillStyle = 'rgba('+pJS.canvas.color_rgb_bg.r+','+pJS.canvas.color_rgb_bg.g+','+pJS.canvas.color_rgb_bg.b+','+pJS.canvas.opacity+')';
		pJS.canvas.ctx.fillRect(0, 0, pJS.canvas.w, pJS.canvas.h);
	};

	/* --------- PARTICLES functions ----------- */

	pJS.fn.particle = function(color, opacity){

		/* position */
		this.x = Math.random() * pJS.canvas.w;
		this.y = Math.random() * pJS.canvas.h;

		/* size */
		if(pJS.retina){
			this.radius = Math.random() * pJS.particles.size * 2;
		}else{
			this.radius = Math.random() * pJS.particles.size * 1;
		}

		/* color */
		this.color = color;

		/* opacity */
		this.opacity = opacity;

		/* animation - velocity for speed */
		this.vx = -.5 + Math.random() * 1;
		this.vy = -.5 + Math.random() * 1;

		/* draw function */
		this.draw = function(){
			pJS.canvas.ctx.fillStyle = 'rgba('+this.color.r+','+this.color.g+','+this.color.b+','+this.opacity+')';
			pJS.canvas.ctx.beginPath();
			pJS.canvas.ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
			pJS.canvas.ctx.fill();
		}

	};

	pJS.fn.particlesCreate = function(){
		for(var i = 0; i < pJS.particles.nb; i++) {
			pJS.particles.array.push(new pJS.fn.particle(pJS.particles.color_rgb, pJS.particles.opacity));
		}
	};

	pJS.fn.particlesAnimate = function(){
		for(var i = 0; i < pJS.particles.array.length; i++){
			/* the particle */
			var p = pJS.particles.array[i];

			/* move the particle */
			p.x += p.vx * pJS.particles.anim.speed;
			p.y += p.vy * pJS.particles.anim.speed;

			/* change particle position if it is out of window */
			if(p.x + p.radius > pJS.canvas.w) p.x = p.radius;
			else if(p.x - p.radius < 0) p.x = pJS.canvas.w - p.radius;
			if(p.y + p.radius > pJS.canvas.h) p.y = p.radius;
			else if(p.y - p.radius < 0) p.y = pJS.canvas.h - p.radius;
		}
	};

	pJS.fn.particlesDraw = function(){
		/* repaint canvas */
		pJS.fn.canvasPaint();

		/* draw each particle */
		for(var i = 0; i < pJS.particles.array.length; i++){
			var p = pJS.particles.array[i];
			p.draw('rgba('+p.color.r+','+p.color.g+','+p.color.b+','+p.opacity+')');
		}

		/* move particle */
		pJS.fn.particlesAnimate();
	};

	/* --------- LAUNCH ----------- */

	function launchParticles(){
		pJS.fn.canvasInit();
		pJS.fn.canvasSize();
		pJS.fn.canvasPaint();
		pJS.fn.particlesCreate();
		pJS.fn.particlesDraw();
	};

	launchParticles();

	function launchAnimation(){
		pJS.fn.particlesDraw();
		requestAnimFrame(launchAnimation);
	};

	launchAnimation();

};

/* --- VENDORS --- */

window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
		  window.webkitRequestAnimationFrame ||
		  window.mozRequestAnimationFrame    ||
		  window.oRequestAnimationFrame      ||
		  window.msRequestAnimationFrame     ||
		  function(callback){
			window.setTimeout(callback, 1000 / 60);
		  };
})();

function hexToRgb(hex){
    // By Tim Down - http://stackoverflow.com/a/5624139/3493650
    // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
    var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
    hex = hex.replace(shorthandRegex, function(m, r, g, b) {
        return r + r + g + g + b + b;
    });
    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16)
    } : null;
};

/* --- LAUNCH --- */

window.particlesJS = function(the_id, params){
	if(!the_id){ the_id = 'particles-js'; }
	/* create canvas element */
	var canvas_el = document.createElement('canvas');
	canvas_el.style.width = "100%";
	canvas_el.style.height = "100%";
	var canvas = document.getElementById(the_id).appendChild(canvas_el);
	/* launch particle.js */
	if(canvas != null){
		launchParticlesJS(the_id, params);
	}
};<|endoftext|>