<commit_before>function preProcess(transaction) {
  return Object.assign(
    {},
    transaction,
    {
      amount: +transaction.amount // turn transaction amount into a Number
    }
  );
}

d3.csv('/assets/data/data.csv', preProcess, function (fraudData) {
  /* Program layout

    1. Calculate extra fields based on fraud checks and add these to each row (transaction)
      respectively (for example how muuch a transaction.amount deviates from the mean)
    2. Calculate how much 'fraud points' each transaction gets, based on the extra fields added
      on the previous step, and add these to each transaction (we do this as a separate step so
      we can easily tweak the point calculation)
    3. Draw the chart with d3
  */

  /* Fraud checks

    There are 7 fraud indicators we test on:
    1. The amount does not coincide with the average amount
      Extra thingies:
      a. The transaction amount is 0
      b. The transaction amount has more than two decimal points
    2. Shopper email or card number is used in quick succession
    3. Shopper country is high risk
    4. Different countries used by the same shopper email address
    5. Shopper country differs from issuing country and/or country of currency
    6. Card number already used by other shopper (shopper email)
    7. Transaction time check

  */

  /* precalculation for check 1 */

  function calculateMean(arr) {
    return arr.reduce((a, b) => a + b, 0) / arr.length;
  }

  function calculateVariance(arr) {
    let arrMean = calculateMean(arr);
    return arr.map(a => Math.pow(a - arrMean, 2)).reduce((a, b) => a + b) / arr.length;
  }

  // Get the amounts from the dataset
  const TRANSACTION_AMOUNTS = fraudData.map((transaction) => transaction.amount);

  // Caculate the mean from this amount
  const MEAN = calculateMean(TRANSACTION_AMOUNTS);

  // Calculate standardDeviation: (http://www.mathsisfun.com/data/standard-deviation.html)
  const STANDARDDEVIATION = Math.sqrt(calculateVariance(TRANSACTION_AMOUNTS));

  // Max
  const TRANSACTION_MAX = d3.max(TRANSACTION_AMOUNTS);

  //
  function addDeviation(transaction) {
    return {
      isAboveStandardDeviation: transaction.amount > (MEAN + STANDARDDEVIATION),
      isBelowStandardDeviation: transaction.amount < (MEAN - STANDARDDEVIATION),
    };
  }

  function addPercentageDifference(transaction) {
    return {
      differenceInPercentage: (transaction.amount / MEAN) * 100,
    };
  }

  /* Fraud check 1 'The amount does not coincide with the average amount' */
  function checkOne(transaction) {
    const scale = d3.scaleLinear()
                    .domain([MEAN + STANDARDDEVIATION, TRANSACTION_MAX])
                    .range([0, 25])
                    .clamp(true);

    let points = 0;
    let hasMoreThanTwoDecimalPlaces = false;

    if (transaction.amount.toString().indexOf('.') !== -1) {
      hasMoreThanTwoDecimalPlaces = transaction.amount.toString().split('.')[1].length > 2;
    }

    if (transaction.amount === 0 || hasMoreThanTwoDecimalPlaces) {
      points = 25;
    } else if (transaction.amount > (MEAN + STANDARDDEVIATION)) {
      points = scale(transaction.amount);
    }
    return { checkOne: points };
  }

  /* Fraud check 2 'Shopper email or card number is used in quick succession' */

  /* Fraud check 3 'Shopper country is high risk' */

  /* Fraud check 4 ' Different countries used by the same shopper email address' */

  /* Fraud check 5 'Shopper country differs from issuing country and/or country of currency' */

  /* Fraud check 6 'Card number already used by other shopper (shopper email)' */

  /* Fraud check 7 'Transaction time check' */

  /* Add aditional fraud info to transaction */
  function addCalculatedFraudIndicators(data) {
    return data.map(function(transaction) {
      return Object.assign({},
        addDeviation(transaction),
        addPercentageDifference(transaction),
        transaction
      );
    });
  }

  const ENHANCED_DATA = addCalculatedFraudIndicators(fraudData);

  /* Calculate Points */
  function givePoints(enhancedData) {
    return enhancedData.map(function(transaction) {
      return Object.assign({},
        checkOne(transaction),
        transaction
      );
    });
  }

  const FINISHED_DATA = givePoints(ENHANCED_DATA);
  console.table(FINISHED_DATA);

  /* Draw chart */

});
<commit_msg>round points for check 1<commit_after>function preProcess(transaction) {
  return Object.assign(
    {},
    transaction,
    {
      amount: +transaction.amount // turn transaction amount into a Number
    }
  );
}

d3.csv('/assets/data/data.csv', preProcess, function (fraudData) {
  /* Program layout

    1. Calculate extra fields based on fraud checks and add these to each row (transaction)
      respectively (for example how muuch a transaction.amount deviates from the mean)
    2. Calculate how much 'fraud points' each transaction gets, based on the extra fields added
      on the previous step, and add these to each transaction (we do this as a separate step so
      we can easily tweak the point calculation)
    3. Draw the chart with d3
  */

  /* Fraud checks

    There are 7 fraud indicators we test on:
    1. The amount does not coincide with the average amount
      Extra thingies:
      a. The transaction amount is 0
      b. The transaction amount has more than two decimal points
    2. Shopper email or card number is used in quick succession
    3. Shopper country is high risk
    4. Different countries used by the same shopper email address
    5. Shopper country differs from issuing country and/or country of currency
    6. Card number already used by other shopper (shopper email)
    7. Transaction time check

  */

  /* precalculation for check 1 */
  function calculateMean(arr) {
    return arr.reduce((a, b) => a + b, 0) / arr.length;
  }

  function calculateVariance(arr) {
    let arrMean = calculateMean(arr);
    return arr.map(a => Math.pow(a - arrMean, 2)).reduce((a, b) => a + b) / arr.length;
  }

  // Get the amounts from the dataset
  const TRANSACTION_AMOUNTS = fraudData.map((transaction) => transaction.amount);

  const MEAN = calculateMean(TRANSACTION_AMOUNTS);

  // Calculate standardDeviation: (http://www.mathsisfun.com/data/standard-deviation.html)
  const STANDARDDEVIATION = Math.sqrt(calculateVariance(TRANSACTION_AMOUNTS));

  const TRANSACTION_MAX = d3.max(TRANSACTION_AMOUNTS);

  function addDeviation(transaction) {
    return {
      isAboveStandardDeviation: transaction.amount > (MEAN + STANDARDDEVIATION),
      isBelowStandardDeviation: transaction.amount < (MEAN - STANDARDDEVIATION),
    };
  }

  function addPercentageDifference(transaction) {
    return {
      differenceInPercentage: (transaction.amount / MEAN) * 100,
    };
  }

  /* Fraud check 1 'The amount does not coincide with the average amount' */
  function checkOne(transaction) {
    const scale = d3.scaleLinear()
                    .domain([MEAN + STANDARDDEVIATION, TRANSACTION_MAX])
                    .rangeRound([0, 25])
                    .clamp(true);

    let points = 0;
    let hasMoreThanTwoDecimalPlaces = false;

    if (transaction.amount.toString().indexOf('.') !== -1) {
      hasMoreThanTwoDecimalPlaces = transaction.amount.toString().split('.')[1].length > 2;
    }

    if (transaction.amount === 0 || hasMoreThanTwoDecimalPlaces) {
      points = 25;
    } else if (transaction.amount > (MEAN + STANDARDDEVIATION)) {
      points = scale(transaction.amount);
    }
    return { checkOne: points };
  }

  /* Fraud check 2 'Shopper email or card number is used in quick succession' */

  /* Fraud check 3 'Shopper country is high risk' */

  /* Fraud check 4 ' Different countries used by the same shopper email address' */

  /* Fraud check 5 'Shopper country differs from issuing country and/or country of currency' */

  /* Fraud check 6 'Card number already used by other shopper (shopper email)' */

  /* Fraud check 7 'Transaction time check' */

  /* Add aditional fraud info to transaction */
  function addCalculatedFraudIndicators(data) {
    return data.map(function(transaction) {
      return Object.assign({},
        addDeviation(transaction),
        addPercentageDifference(transaction),
        transaction
      );
    });
  }

  const ENHANCED_DATA = addCalculatedFraudIndicators(fraudData);

  /* Calculate Points */
  function givePoints(enhancedData) {
    return enhancedData.map(function(transaction) {
      return Object.assign({},
        checkOne(transaction),
        transaction
      );
    });
  }

  const FINISHED_DATA = givePoints(ENHANCED_DATA);
  console.table(FINISHED_DATA);

  /* Draw chart */

});
<|endoftext|>


<commit_before>var Ascend = (function() {

	return func = function(config) {
		var ascend = this;

		// Setup the default configs
		defaults = {
			overlays: true,
		}

		// Merge the configs
		config = deepMerge(defaults,config);

		// console.log(config);

		// Setup to leap loop and check for gestures.
		if (!this.controller) {
			this.controller = new Leap.Controller({ enableGestures: true });
			this.controller.on('animationFrame', function(frame){
				if (frame.id%10 === 0) {
					if (frame.pointables.length) {
						// trigger('pointables', frame);
					} else {
						// trigger('pointablesout', frame);
					}
					if (frame.hands.length) {
						// trigger('hands', frame);
					} else {
						// trigger('handsout', frame);
					}
					if (frame.fingers.length) {
						// trigger('fingers', frame);
					} else {
						// trigger('fingersout', frame);
					}
					if (frame.tools.length) {
						console.log('Tool '+frame.tools[0].id+' Detected');
						// trigger('tools', frame);
					} else {
						// trigger('toolsout', frame);
					}
					if (frame.gestures.length > 0) {
						trigger('gesture', frame);
						frame.gestures.forEach(function(gesture) {
							trigger(gesture.type, gesture);
							trigger(gesture.type + gesture.state,gesture);
						});
					}
				}
			});

			//Lets bind some default functions
			bind('connect', function() {
				console.log('Device Connected');
			});

			bind('deviceConnected', function() {
				console.log('Device Connected');
			});

			bind('deviceDisconnected', function() {
				console.log('Device Disconnected');
			});

			bind('focus', function(){
				overLayDiv.style.display = 'none';
			});

			bind('blur', function(){
				overLayDiv.style.display = 'block';
			});

			//Lets monitor the default things for LeapJS
			this.controller.on('connect', function(){
				trigger('connect');
			});

			this.controller.on('deviceConnected', function(){
				trigger('deviceConnected');
			});

			this.controller.on('deviceDisconnected', function(){
				trigger('deviceDisconnected');
			});
			this.controller.on('focus', function(){
				trigger('focus');
			});

			this.controller.on('blur', function(){
				trigger('blur');
			});

			//Finally Connect
			this.controller.connect();
		}

		function bind(eventType, listener) {
			if(!this._listeners) {
				 this._listeners = {};
			}
			if(!(eventType in this._listeners)) {
				this._listeners[eventType] = [];
			}
			var arr = this._listeners[eventType];
			if(arrIndexOf(arr, listener) === -1) {
				arr.push(listener);
			}
			return;
		};

		function showBindings() {
			return this._listeners ? this._listeners : null;
		};

		function unbind(eventType, listener) {
			if(!(this._listeners && (eventType in this._listeners))) {
				return;
			}
			var arr = this._listeners[eventType];
			var idx = arrIndexOf(arr, listener);
			if (idx !== -1) {
				if(arr.length > 1) {
					this._listeners[eventType] = arr.slice(0, idx).concat( arr.slice(idx+1) );
				} else {
					delete this._listeners[eventType];
				}
				return;
			}
			return;
		};

		function trigger(eventType) {
			var args = Array.prototype.slice.call(arguments, 0);
			if (this._listeners && eventType in this._listeners) {
				for(var i=0; i < this._listeners[eventType].length; i++) {
					this._listeners[eventType][i].apply(this, args);
				}
			}
		};

		function arrIndexOf(arr, obj) {
			for(var i=0; i < arr.length; i++){
				if(arr[i] === obj){
					return i;
				}
			}
			return -1;
		}

		function deepMerge(obj1, obj2) {
			for (var p in obj2) {
				try {
					if ( obj2[p].constructor==Object ) {
						obj1[p] = MergeRecursive(obj1[p], obj2[p]);
					} else {
						obj1[p] = obj2[p];
					}
				} catch(e) {
					obj1[p] = obj2[p];
				}
			}
			return obj1;
		}

		// Create our overlay layer
		var overLayDiv = document.createElement("div");
		overLayDiv.setAttribute("style","display: none; width: 100%; height: 100%; color: white; background-color: rgba(0,0,0,0.6); overflow: hidden; position: fixed; top: 0px; left: 0px; z-index: 9999;");
		overLayDiv.innerHTML = "Hello";

		document.body.appendChild(overLayDiv);

		return {
			controller: ascend.controller,
			bind: function(eventType, listener){ return bind.call(ascend, eventType, listener); },
			unbind: function(eventType, listener){ return unbind.call(ascend); },
			listbindings: function(){return showBindings.call(ascend)},
			trigger: function(eventType){ return trigger.call(ascend, eventType); }
		};
	}

})();<commit_msg>Updating Overlays<commit_after>var Ascend = (function() {

	return func = function(config) {
		var ascend = this;

		// Setup the default configs
		defaults = {
			overlays: true,
		}

		// Merge the configs
		config = deepMerge(defaults,config);

		// console.log(config);

		// Setup to leap loop and check for gestures.
		if (!this.controller) {
			this.controller = new Leap.Controller({ enableGestures: true });
			this.controller.on('animationFrame', function(frame){
				if (frame.id%10 === 0) {
					if (frame.pointables.length) {
						// trigger('pointables', frame);
					} else {
						// trigger('pointablesout', frame);
					}
					if (frame.hands.length) {
						// trigger('hands', frame);
					} else {
						// trigger('handsout', frame);
					}
					if (frame.fingers.length) {
						// trigger('fingers', frame);
					} else {
						// trigger('fingersout', frame);
					}
					if (frame.tools.length) {
						console.log('Tool '+frame.tools[0].id+' Detected');
						// trigger('tools', frame);
					} else {
						// trigger('toolsout', frame);
					}
					if (frame.gestures.length > 0) {
						trigger('gesture', frame);
						frame.gestures.forEach(function(gesture) {
							trigger(gesture.type, gesture);
							trigger(gesture.type + gesture.state,gesture);
						});
					}
				}
			});

			//Lets bind some default functions
			bind('connect', function() {
				console.log('Device Connected');
			});

			bind('deviceConnected', function() {
				console.log('Device Connected');
			});

			bind('deviceDisconnected', function() {
				if (config.overlays == true) {
					overLayDevice.setAttribute('src','/images/leapDeviceOn.gif');
				}
				console.log('Device Disconnected');
			});

			//Lets monitor the default things for LeapJS
			this.controller.on('connect', function(){
				trigger('connect');
			});

			this.controller.on('deviceConnected', function(){
				trigger('deviceConnected');
			});

			this.controller.on('deviceDisconnected', function(){
				trigger('deviceDisconnected');
			});
			this.controller.on('focus', function(){
				trigger('focus');
			});

			this.controller.on('blur', function(){
				trigger('blur');
			});

			//Finally Connect
			this.controller.connect();
		}

		function bind(eventType, listener) {
			if(!this._listeners) {
				 this._listeners = {};
			}
			if(!(eventType in this._listeners)) {
				this._listeners[eventType] = [];
			}
			var arr = this._listeners[eventType];
			if(arrIndexOf(arr, listener) === -1) {
				arr.push(listener);
			}
			return;
		};

		function showBindings() {
			return this._listeners ? this._listeners : null;
		};

		function unbind(eventType, listener) {
			if(!(this._listeners && (eventType in this._listeners))) {
				return;
			}
			var arr = this._listeners[eventType];
			var idx = arrIndexOf(arr, listener);
			if (idx !== -1) {
				if(arr.length > 1) {
					this._listeners[eventType] = arr.slice(0, idx).concat( arr.slice(idx+1) );
				} else {
					delete this._listeners[eventType];
				}
				return;
			}
			return;
		};

		function trigger(eventType) {
			var args = Array.prototype.slice.call(arguments, 0);
			if (this._listeners && eventType in this._listeners) {
				for(var i=0; i < this._listeners[eventType].length; i++) {
					this._listeners[eventType][i].apply(this, args);
				}
			}
		};

		function arrIndexOf(arr, obj) {
			for(var i=0; i < arr.length; i++){
				if(arr[i] === obj){
					return i;
				}
			}
			return -1;
		}

		function deepMerge(obj1, obj2) {
			for (var p in obj2) {
				try {
					if ( obj2[p].constructor==Object ) {
						obj1[p] = MergeRecursive(obj1[p], obj2[p]);
					} else {
						obj1[p] = obj2[p];
					}
				} catch(e) {
					obj1[p] = obj2[p];
				}
			}
			return obj1;
		}

		if (config.overlays == true) {
			var overLayDiv = document.createElement('div');
			overLayDiv.setAttribute('style','display: block; width: 100%; height: 100%; color: white; background-color: rgba(0,0,0,0); overflow: hidden; position: fixed; top: 0px; left: 0px; z-index: 9999;');
			var overLayDevice = document.createElement('img');
			overLayDevice.setAttribute('src','/images/leapDeviceOn.gif');
			overLayDevice.setAttribute('style','width: 50px');
			document.body.appendChild(overLayDiv).appendChild(overLayDevice);
		}

		return {
			controller: ascend.controller,
			bind: function(eventType, listener){ return bind.call(ascend, eventType, listener); },
			unbind: function(eventType, listener){ return unbind.call(ascend); },
			listbindings: function(){return showBindings.call(ascend)},
			trigger: function(eventType){ return trigger.call(ascend, eventType); }
		};
	}

})();<|endoftext|>


<commit_before>
var Inverted = require('level-inverted-index')
var through  = require('through')

exports.db = function (db, config) {
  var packageDb = db.sublevel('pkg')
  var indexDb = db.sublevel('index')

  var i = 0

  Inverted(packageDb, indexDb, function (key, value, index) {
    index(value.readme)
    index(value.name)
    index(value.author)
    index(value.keywords)
    index(value.description)
  }, function (value, query) {
    /*
    var matches = []

    var matchers =
      query.map(function (str) {
        return new RegExp('(?:\s|^)' + str.replace('~', '.*') + '(?:$|\s)')
      })

    //return value.description

    value.readme.split('\n')
    */
    return {
      name: value.name,
      maintainers: value.maintainers,
      //version: value.version,
      description: value.description || '',
      preview: (function () {
        if(!value.readme) return
        //make a modue to find the matches.
        //this is really crude, at the moment.

        return value.readme.split('\n')
                .slice(0, 5).join('\n')
      })()
    }
    return [
      '-----------------------------',
      (value.readme ? value.readme.substring(0, 140) + '...' : value.description || value.name)
      .split('\n').map(function (e) {
        return '  ' + e
      }).join('\n')
    ].join('\n')
  })
}

exports.commands = function (db) {
  db.commands.push(function (db, config, cb) {
  var args = config._.slice()
  if(args.shift() != 'search')
    return

  if(!args.length)
    return cb(new Error('expects search term'))

  db.sublevel('index')
    .createQueryStream(args)
    .pipe(through(function (data) {
      this.queue(data.key + '\n')
    }))
    .on('end', cb)
    .pipe(process.stdout)

    return true
  })

}
<commit_msg>include descriptions in the search results<commit_after>
var Inverted = require('level-inverted-index')
var through  = require('through')

exports.db = function (db, config) {
  var packageDb = db.sublevel('pkg')
  var indexDb = db.sublevel('index')

  var i = 0

  Inverted(packageDb, indexDb, function (key, value, index) {
    index(value.readme)
    index(value.name)
    index(value.author)
    index(value.keywords)
    index(value.description)
  }, function (value, query) {
    /*
    var matches = []

    var matchers =
      query.map(function (str) {
        return new RegExp('(?:\s|^)' + str.replace('~', '.*') + '(?:$|\s)')
      })

    //return value.description

    value.readme.split('\n')
    */
    return {
      name: value.name,
      maintainers: value.maintainers,
      //version: value.version,
      description: value.description || '',
      preview: (function () {
        if(!value.readme) return
        //make a modue to find the matches.
        //this is really crude, at the moment.

        return value.readme.split('\n')
                .slice(0, 5).join('\n')
      })()
    }
    return [
      '-----------------------------',
      (value.readme ? value.readme.substring(0, 140) + '...' : value.description || value.name)
      .split('\n').map(function (e) {
        return '  ' + e
      }).join('\n')
    ].join('\n')
  })
}

exports.commands = function (db) {
  db.commands.push(function (db, config, cb) {
  var args = config._.slice()
  if(args.shift() != 'search')
    return

  if(!args.length)
    return cb(new Error('expects search term'))

  db.sublevel('index')
    .createQueryStream(args)
    .pipe(through(function (data) {
      this.queue(rpad(data.key, 22) + ' ' + data.value.description + '\n')
    }))
    .on('end', cb)
    .pipe(process.stdout)

    return true
  })

}

function rpad (s, n) {
  return s + Array(Math.max(2, n - s.length + 1)).join(' ')
}
<|endoftext|>


<commit_before>(function(angular) {

  if(!angular) {
    return;
  }

  ///////////////
  // Directive //
  ///////////////

  angular.module('headroom', []).directive('headroom', function() {
    return {
      restrict: 'EA',
      scope: {
        tolerance: '=',
        offset: '=',
        classes: '=',
        scroller: '@'
      },
      link: function(scope, element) {
        var options = {};
        angular.forEach(Headroom.options, function(value, key) {
          options[key] = scope[key] || Headroom.options[key];
        });
        if (options.scroller) {
          options.scroller = angular.element(options.scroller)[0];
        }
        var headroom = new Headroom(element[0], options);
        headroom.init();
        scope.$on('$destroy', function() {
          headroom.destroy();
        });
      }
    };
  });

}(window.angular));
<commit_msg>made scroller selector lookup workable with jqLite<commit_after>(function(angular) {

  if(!angular) {
    return;
  }

  ///////////////
  // Directive //
  ///////////////

  angular.module('headroom', []).directive('headroom', function() {
    return {
      restrict: 'EA',
      scope: {
        tolerance: '=',
        offset: '=',
        classes: '=',
        scroller: '@'
      },
      link: function(scope, element) {
        var options = {};
        angular.forEach(Headroom.options, function(value, key) {
          options[key] = scope[key] || Headroom.options[key];
        });
        if (options.scroller) {
          options.scroller = document.querySelector(options.scroller);
        }
        var headroom = new Headroom(element[0], options);
        headroom.init();
        scope.$on('$destroy', function() {
          headroom.destroy();
        });
      }
    };
  });

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


<commit_before>/**
 * Created by chriscai on 2014/10/14.
 */

var MongoClient = require('mongodb').MongoClient,
    map = require('map-stream');

var hadCreatedCollection = {};

var insertDocuments = function(db , model) {
    var collectionName = 'badjslog_' + model.id;
    var collection = db.collection(collectionName);
    collection.insert([
        model.model
    ] , function (err , result){
        if (hadCreatedCollection[collectionName]) {
            return ;
        }
        collection.indexExists('date_-1' , function (err , result ){
            if(!result){
                collection.createIndex( {date : -1 } , function (err , result){

                });
            }
            hadCreatedCollection[collectionName] = true;
        })
    });
}

var url = global.MONGDO_URL;
var mongoDB;
// Use connect method to connect to the Server
MongoClient.connect(url, function(err, db) {
    if(err){
        console.log("failed connect to server");
    }else {
        console.log("Connected correctly to server");
    }
    mongoDB = db;
});

module.exports = function (){
   return map(function (data) {
       try{
        var dataStr = data.toString();
        data = JSON.parse(dataStr.substring(dataStr.indexOf(' ')));
       }catch (e){
           console.log('parse error');
           return ;
       }

       if(!data.id ){
            console.log('not id data');
            return ;
       }

       if(!mongoDB ){
           console.log('cannot connect mongodb');
           return ;
       }
       var id = data.id;
       delete data.id;

       var all = '';
       for(var key in data ) {
            all += ';'+key+'=' + data[key];
       }
       data.all = all;
       data.date = new Date;

           insertDocuments(mongoDB , {id : id,
               model : data
           });

    });
}<commit_msg>将时间交由accepter 设置<commit_after>/**
 * Created by chriscai on 2014/10/14.
 */

var MongoClient = require('mongodb').MongoClient,
    map = require('map-stream');

var hadCreatedCollection = {};

var insertDocuments = function(db , model) {
    var collectionName = 'badjslog_' + model.id;
    var collection = db.collection(collectionName);
    collection.insert([
        model.model
    ] , function (err , result){
        if (hadCreatedCollection[collectionName]) {
            return ;
        }
        collection.indexExists('date_-1' , function (err , result ){
            if(!result){
                collection.createIndex( {date : -1 } , function (err , result){

                });
            }
            hadCreatedCollection[collectionName] = true;
        })
    });
}

var url = global.MONGDO_URL;
var mongoDB;
// Use connect method to connect to the Server
MongoClient.connect(url, function(err, db) {
    if(err){
        console.log("failed connect to server");
    }else {
        console.log("Connected correctly to server");
    }
    mongoDB = db;
});

module.exports = function (){
   return map(function (data) {
       try{
        var dataStr = data.toString();
        data = JSON.parse(dataStr.substring(dataStr.indexOf(' ')));
       }catch (e){
           console.log('parse error');
           return ;
       }

       if(!data.id ){
            console.log('not id data');
            return ;
       }

       if(!mongoDB ){
           console.log('cannot connect mongodb');
           return ;
       }
       var id = data.id;
       delete data.id;

       var all = '';
       for(var key in data ) {
            all += ';'+key+'=' + data[key];
       }
       data.all = all;
       data.date = new Date(data.date);

           insertDocuments(mongoDB , {id : id,
               model : data
           });

    });
}<|endoftext|>


<commit_before>var ImageLoader_0_5_x = function() { };

// TODO: Capture viewport_width and viewport_height on initialiaztion.

ImageLoader_0_5_x.prototype.version_number = function() {
    return "0.5.0";
};

ImageLoader_0_5_x.prototype.set_url_template= function() {
    // TODO: Take in a parameter and set the instance variable
    //       `_url_template` so that it can be set one time
    //       and isn't required for every call.
}

ImageLoader_0_5_x.prototype.load_environment = function() {
    // TODO: Setup an initilization type call the
    //       pulls in and the environmental parameters
    //       from the browser a single time so they can
    //       be used across multiple uses.
};

ImageLoader_0_5_x.prototype.image_string_from_params = function(params) {
    console.log(params);
    var _width = 640;
    var output_string = '';
    return output_string;
};

// TODO: Delete this funciton and move its contents into `load_environment`
ImageLoader_0_5_x.prototype.load_environmental_params = function() {
    this._dpr = window.devicePixelRatio ? window.devicePixelRatio : 1;
};

ImageLoader_0_5_x.prototype.url_to_call = function() {
	return this._url_template.replace('[WIDTH]', this.url_request_width()).replace('[HEIGHT]', this.url_request_height()).replace('[QUALITY]', this._quality).replace('[IMAGE_NAME]', this._image_name)
};

ImageLoader_0_5_x.prototype.img_tag = function() {
	return ''
};

ImageLoader_0_5_x.prototype.load_params = function(params) {
	// This is the core funciton that takes all possible inputs.
	// Convience methods will be used in production, but they will all communicate
	// load_params.

  // Required
  this._image_name = params["image_name"];
  this._viewport_height = params["viewport_height"];
  this._viewport_width = params["viewport_width"];
  this._raw_height = params["raw_height"];
  this._raw_width = params["raw_width"];
  this._url_template = params["url_template"];

  // Optional
  this._dpr = params["dpr"] ? params["dpr"] : 1;
  this._max_render_width = params["max_render_width"] ? params["max_render_width"] : params["raw_width"];
  this._percent_of_viewport_width = params["percent_of_viewport_width"] ? params["percent_of_viewport_width"] : 100;
  this._quality = params["quality"] ? params["quality"] : 80;

  // If `percent_of_viewport_height` is called, translate it into `_percent_of_viewport_width`.
  if("percent_of_viewport_height" in params) {
    this._percent_of_viewport_width = Math.floor(this._viewport_height * params["percent_of_viewport_height"] * this._raw_width / this._raw_height / this._viewport_width);
  }

};

ImageLoader_0_5_x.prototype.render_height = function() {
	return  Math.floor(this._raw_height * this.render_width() / this._raw_width );
};

ImageLoader_0_5_x.prototype.render_width = function() {
	return Math.floor(Math.min(this._max_render_width, (this._percent_of_viewport_width * .01 * this._viewport_width)));
};

ImageLoader_0_5_x.prototype.url_request_height = function() {
  return this.render_height() * this._dpr;
};

ImageLoader_0_5_x.prototype.url_request_width = function() {
  return this.render_width() * this._dpr;
};

<commit_msg>Added a height stub and notes to produce it and the width via function calls.<commit_after>var ImageLoader_0_5_x = function() { };

// TODO: Capture viewport_width and viewport_height on initialiaztion.

ImageLoader_0_5_x.prototype.version_number = function() {
    return "0.5.0";
};

ImageLoader_0_5_x.prototype.set_url_template= function() {
    // TODO: Take in a parameter and set the instance variable
    //       `_url_template` so that it can be set one time
    //       and isn't required for every call.
}

ImageLoader_0_5_x.prototype.load_environment = function() {
    // TODO: Setup an initilization type call the
    //       pulls in and the environmental parameters
    //       from the browser a single time so they can
    //       be used across multiple uses.
};

ImageLoader_0_5_x.prototype.image_string_from_params = function(params) {
    console.log(params);
    var _width = 640;  // TODO: make a function to build this.
    var _height = 436; // TODO: make a function to build this.
    var output_string = '';
    return output_string;
};

// TODO: Delete this funciton and move its contents into `load_environment`
ImageLoader_0_5_x.prototype.load_environmental_params = function() {
    this._dpr = window.devicePixelRatio ? window.devicePixelRatio : 1;
};

ImageLoader_0_5_x.prototype.url_to_call = function() {
	return this._url_template.replace('[WIDTH]', this.url_request_width()).replace('[HEIGHT]', this.url_request_height()).replace('[QUALITY]', this._quality).replace('[IMAGE_NAME]', this._image_name)
};

ImageLoader_0_5_x.prototype.img_tag = function() {
	return ''
};

ImageLoader_0_5_x.prototype.load_params = function(params) {
	// This is the core funciton that takes all possible inputs.
	// Convience methods will be used in production, but they will all communicate
	// load_params.

  // Required
  this._image_name = params["image_name"];
  this._viewport_height = params["viewport_height"];
  this._viewport_width = params["viewport_width"];
  this._raw_height = params["raw_height"];
  this._raw_width = params["raw_width"];
  this._url_template = params["url_template"];

  // Optional
  this._dpr = params["dpr"] ? params["dpr"] : 1;
  this._max_render_width = params["max_render_width"] ? params["max_render_width"] : params["raw_width"];
  this._percent_of_viewport_width = params["percent_of_viewport_width"] ? params["percent_of_viewport_width"] : 100;
  this._quality = params["quality"] ? params["quality"] : 80;

  // If `percent_of_viewport_height` is called, translate it into `_percent_of_viewport_width`.
  if("percent_of_viewport_height" in params) {
    this._percent_of_viewport_width = Math.floor(this._viewport_height * params["percent_of_viewport_height"] * this._raw_width / this._raw_height / this._viewport_width);
  }

};

ImageLoader_0_5_x.prototype.render_height = function() {
	return  Math.floor(this._raw_height * this.render_width() / this._raw_width );
};

ImageLoader_0_5_x.prototype.render_width = function() {
	return Math.floor(Math.min(this._max_render_width, (this._percent_of_viewport_width * .01 * this._viewport_width)));
};

ImageLoader_0_5_x.prototype.url_request_height = function() {
  return this.render_height() * this._dpr;
};

ImageLoader_0_5_x.prototype.url_request_width = function() {
  return this.render_width() * this._dpr;
};

<|endoftext|>


<commit_before>var _ = require('lodash');
var EmailHandler = require('./email-handler');
var options = require('./options-handler').options;
var log = require('./logger').log;

var model = require('./model');
var Page = model.Page;
var PageVersion = model.PageVersion;
var User = model.User;

var debug = require('debug')('Sync');
var util = require('../node_modules/livedb/lib/util');

var lastVersionDumped = {};
var driver = null;
var database = null;

exports.init = function(driver_, database_) {
  driver = driver_;
  database = database_;
};

var dumpPageVersion = function(result, callback) {
  log.debug("IN DUMP PAGE VERSION");
  Page.findOne({_id:result.docName}, function(err, page){
    log.debug("FOUND A PAGE");
    if (page == null) {
      log.debug("ERROR: UPDATING PAGE THAT DOES NOT EXIST");
      return;
    }
    if (page.content == result.data) {
      // The page hasn't changed between versions, don't make a new pageversion
      lastVersionDumped[result.docName] = result.v;
      return;
    }

    var newPageVersion = new PageVersion({pageId:page._id,version:page.nextVersion,content:result.data,editorIds:[]});
    log.debug("DUMPING " + page.name + " WITH VERSION " + page.nextVersion);
    page.nextVersion++;
    page.content = result.data;
    page.lastModifiedTime = newPageVersion.timestamp;
    console.log("TIMESTAMP: " + page.lastModifiedTime);
    page.save(function (err) {
      log.debug("SAVED PAGE");
      if (err) {
        console.log(err);
        if (callback) {
          callback();
        }
      } else {
        log.debug("DUMPING PAGEVERSION");
        newPageVersion.save(function (err,innerPageVersion) {
          if (err) {
            console.log(err);
          }
          lastVersionDumped[result.docName] = result.v;
          User.find({watchedPageIds:page._id}, function(err, users) {
            if (users.length>0) {
              log.info({message:"Notifying watchers",watchers:users});
            }
            for (var i=0;i<users.length;i++) {
              EmailHandler.sendMail(
                users[i].email,
                page.name+" has been updated.",
                "A friendly reminder that the page you watched, "+page.name+", has been updated.  You can see the latest changes by going here: "+(options.ssl?"https":"http")+"://"+options.hostname+":"+options.port+"/view/"+page.name);
            }
            if (callback) {
              log.debug("EXECUTING CALLBACK");
              callback();
            }
          });
        });
      }
    });
  });
};

exports.sync = function(docName, callback) {
  //console.log("Checking for new versions");
  log.debug("PERFORMING SYNC");
  database.query(null, "users", null, null, function(dummy,results){
    log.debug("LOOKING FOR DOCUMENT");
    var foundDocument = false;
    for (var i=0;i<results.length;i++) {
      var result = results[i];
      if (result.docName != docName) {
        continue;
      }
      if (!(lastVersionDumped[result.docName] == result.v)) {
        log.debug("DUMPING NEW VERSION");
        log.debug(result);
        // Dump new PageVersion
        foundDocument = true;
        dumpPageVersion(result, callback);
        return;
      }
    }
    if (!foundDocument) {
      // Something went really wrong
      callback();
    }
    return;
  });
};

exports.syncAndRemove = function(docName) {
  log.debug("Removing liveDB doc " + docName);
  exports.sync(docName, function() {
    delete database.collections['users'][docName];
    delete database.ops['users'][docName];
    delete driver.versions[util.encodeCD('users', docName)];
  });
};

exports.syncAll = function() {
  //console.log("Checking for new versions");
  database.query(null, "users", null, null, function(dummy,results){
    _.each(results,function(result) {
      if (!(lastVersionDumped[result.docName] == result.v)) {
        // Dump new PageVersion
        dumpPageVersion(result);
      }
    });
  });
};
<commit_msg>Add missing callback when trying to sync an unchanged document.<commit_after>var _ = require('lodash');
var EmailHandler = require('./email-handler');
var options = require('./options-handler').options;
var log = require('./logger').log;

var model = require('./model');
var Page = model.Page;
var PageVersion = model.PageVersion;
var User = model.User;

var debug = require('debug')('Sync');
var util = require('../node_modules/livedb/lib/util');

var lastVersionDumped = {};
var driver = null;
var database = null;

exports.init = function(driver_, database_) {
  driver = driver_;
  database = database_;
};

var dumpPageVersion = function(result, callback) {
  log.debug("IN DUMP PAGE VERSION");
  Page.findOne({_id:result.docName}, function(err, page){
    log.debug("FOUND A PAGE");
    if (page == null) {
      log.debug("ERROR: UPDATING PAGE THAT DOES NOT EXIST");
      return;
    }
    if (page.content == result.data) {
      // The page hasn't changed between versions, don't make a new pageversion
      lastVersionDumped[result.docName] = result.v;
      callback();
      return;
    }

    var newPageVersion = new PageVersion({pageId:page._id,version:page.nextVersion,content:result.data,editorIds:[]});
    log.debug("DUMPING " + page.name + " WITH VERSION " + page.nextVersion);
    page.nextVersion++;
    page.content = result.data;
    page.lastModifiedTime = newPageVersion.timestamp;
    console.log("TIMESTAMP: " + page.lastModifiedTime);
    page.save(function (err) {
      log.debug("SAVED PAGE");
      if (err) {
        console.log(err);
        if (callback) {
          callback();
        }
      } else {
        log.debug("DUMPING PAGEVERSION");
        newPageVersion.save(function (err,innerPageVersion) {
          if (err) {
            console.log(err);
          }
          lastVersionDumped[result.docName] = result.v;
          User.find({watchedPageIds:page._id}, function(err, users) {
            if (users.length>0) {
              log.info({message:"Notifying watchers",watchers:users});
            }
            for (var i=0;i<users.length;i++) {
              EmailHandler.sendMail(
                users[i].email,
                page.name+" has been updated.",
                "A friendly reminder that the page you watched, "+page.name+", has been updated.  You can see the latest changes by going here: "+(options.ssl?"https":"http")+"://"+options.hostname+":"+options.port+"/view/"+page.name);
            }
            if (callback) {
              log.debug("EXECUTING CALLBACK");
              callback();
            }
          });
        });
      }
    });
  });
};

exports.sync = function(docName, callback) {
  //console.log("Checking for new versions");
  log.debug("PERFORMING SYNC");
  database.query(null, "users", null, null, function(dummy,results){
    log.debug("LOOKING FOR DOCUMENT");
    var foundDocument = false;
    for (var i=0;i<results.length;i++) {
      var result = results[i];
      if (result.docName != docName) {
        continue;
      }
      if (!(lastVersionDumped[result.docName] == result.v)) {
        log.debug("DUMPING NEW VERSION");
        log.debug(result);
        // Dump new PageVersion
        foundDocument = true;
        dumpPageVersion(result, callback);
        return;
      }
    }
    if (!foundDocument) {
      // Something went really wrong
      callback();
    }
    return;
  });
};

exports.syncAndRemove = function(docName) {
  log.debug("Removing liveDB doc " + docName);
  exports.sync(docName, function() {
    delete database.collections['users'][docName];
    delete database.ops['users'][docName];
    delete driver.versions[util.encodeCD('users', docName)];
  });
};

exports.syncAll = function() {
  //console.log("Checking for new versions");
  database.query(null, "users", null, null, function(dummy,results){
    _.each(results,function(result) {
      if (!(lastVersionDumped[result.docName] == result.v)) {
        // Dump new PageVersion
        dumpPageVersion(result);
      }
    });
  });
};
<|endoftext|>


<commit_before>/**
 * Unit tests for the Firebolt function and namespace
 */

// References for Resharper
/// <reference path="../qunit/qunit.js"/>
/// <reference path="../../src/firebolt.js"/>

module('Firebolt');

test('ajaxSetup', function() {
	var ajaxSettings = Firebolt.ajaxSetup(),
		testObject = {
			a: [1, 2, 3],
			b: false,
			c: 0,
			d: {
				inner: 24
			}
		};

	Firebolt.ajaxSetup({test: 1});
	strictEqual(ajaxSettings.test, 1, 'Extends the AJAX settings object.');

	Firebolt.ajaxSetup({test: testObject});
	deepEqual(ajaxSettings.test, testObject, 'Deep-extends the AJAX settings object.');
	notEqual(ajaxSettings.test, testObject);
});

test('data', function() {
	var object = {},
		dataStore = Firebolt.data(object);

	ok(Firebolt.isPlainObject(dataStore) && Firebolt.isEmptyObject(dataStore),
		'When passed just an object, returns its data store object.');

	ok(Firebolt.isEmptyObject(object), 'Defines the data store at a non-enumerable property on the specifed object');

	strictEqual(Firebolt.data(object, 'a', 1), object, 'Returns the passed in object when setting properties.');

	strictEqual(dataStore.a, 1, 'Can store data properties.');

	Firebolt.data(object, {b: 'b', c: null});
	deepEqual(dataStore, {a: 1, b: 'b', c: null}, 'Can store multiple properties at once.');

	strictEqual(Firebolt.data(object, 'a'), 1, 'Can retrieve previously set properties.');

	var element = Firebolt.elem('div', {'data-stuff': 23});
	dataStore = Firebolt.data(element, undefined, undefined, 1);

	strictEqual(dataStore.stuff, 23,
		'Adds data from custom "data-*" attributes on elements to the data store and parses the data to the correct JavaScript type.');

	strictEqual(Firebolt.data(element, 'stuff', undefined, 1), 23,
		'Can retrieve data in custom "data-*" attributes on an element as the correct JavaScript type.');

	Firebolt.data(element, 'stuff', ['a', 'b'], 1);
	deepEqual(dataStore.stuff, ['a', 'b'],
		'Overwrites data retrieved from custom "data-*" attributes on an element when new data with the same key is set.');

	delete dataStore.stuff;
	strictEqual(Firebolt.data(element, 'stuff', undefined, 1), 23,
		'Restores data retrieved from custom "data-*" attributes on an element when other data with the same key is removed.');
});

test('elem', function() {
	var element = Firebolt.elem('div');
	ok(element.nodeType === 1 && element.nodeName === 'DIV', 'Creates a new Element.');

	element = Firebolt.elem('p', {'class': 'one two', 'data-custom': 'test'});
	ok(element.className === 'one two' && element.getAttribute('data-custom') === 'test',
		'Creates a new element with the specified properties');
});

test('globalEval', function() {
	Firebolt.globalEval('var globalEvalTest1 = true;');
	strictEqual(window.globalEvalTest1, true, 'Executes the passed in code in the global context.');

	Firebolt.globalEval('"use strict"; function globalEvalTest2() { return 10; }');
	strictEqual(window.globalEvalTest2(), 10, 'Executes code with a strict mode pragma in the global context.');
});

test('hasData', function() {
	var object = {};

	strictEqual(Firebolt.hasData(object), false,
		'Correctly reports that an object without Firebolt data does not have data.');

	Firebolt.data(object, 'a', 0);
	strictEqual(Firebolt.hasData(object), true,
		'Correctly reports that an object with Firebolt data has data.');

	Firebolt.removeData(object, 'a');
	strictEqual(Firebolt.hasData(object), false,
		'Correctly reports that an object that used to have Firebolt data does not have data.');

	object = Firebolt.elem('div', {'data-stuff': 23});
	strictEqual(Firebolt.hasData(object), false,
		'Correctly reports that an element that has not had the $.data() function called on it yet does not have data.');

	Firebolt.data(object, undefined, undefined, 1);
	strictEqual(Firebolt.hasData(object), true,
		'Correctly reports that an element with data pulled from a "data-*" attribute has data.');
});

test('isPlainObject', function func() {
	// False
	ok(!Firebolt.isPlainObject(1));
	ok(!Firebolt.isPlainObject('string'));
	ok(!Firebolt.isPlainObject(undefined));
	ok(!Firebolt.isPlainObject(null));
	ok(!Firebolt.isPlainObject([]));
	ok(!Firebolt.isPlainObject([{}]));
	ok(!Firebolt.isPlainObject(true));
	ok(!Firebolt.isPlainObject(/RegExp/));
	ok(!Firebolt.isPlainObject(func));
	ok(!Firebolt.isPlainObject(window));
	ok(!Firebolt.isPlainObject(document));
	ok(!Firebolt.isPlainObject(document.body));
	ok(!Firebolt.isPlainObject(document.createTextNode('text')));
	ok(!Firebolt.isPlainObject(document.getElementsByTagName('div')));
	ok(!Firebolt.isPlainObject(document.querySelectorAll('div')));

	// True
	ok(Firebolt.isPlainObject({}));
});

test('parseHTML', function() {
	var iframe = document.createElement('iframe'),
		element;

	element = Firebolt.parseHTML('
')[0];
	ok(element && element.tagName.toLowerCase() === 'div', 'Can make a simple, single element.');

	ok(element && element.ownerDocument === document, 'By default, creates elements in the context of the current document.');

	document.head.appendChild(iframe);
	element = Firebolt.parseHTML('
', iframe.contentDocument)[0];
	ok(element && element.ownerDocument === iframe.contentDocument, 'Can create elements in the context of another document.');
	iframe.remove();

	'option optgroup thead tbody tfoot colgroup caption tr col td th script link legend'.split(' ').forEach(function(tagName) {
		element = Firebolt.parseHTML('<' + tagName + ' class="test" />')[0];
		ok(element && element.tagName.toLowerCase() === tagName && element.className === 'test',
			'Can make special element: <' + tagName + '>.');
	});

	ok(Firebolt.parseHTML('
para

').length === 2, 'Can make multiple elements.');

	document.body.appendChild(Firebolt.parseHTML('')[0]);
	ok(window.whoa != 9, 'Created scripts are not evaluated.');
});

test('removeData', function() {
	var object = {},
		testData = {a: 1, b: 2, c: 3},
		dataStore = Firebolt.data(object, testData);

	Firebolt.removeData(object, 'a');
	ok(!('a' in dataStore), 'Removes a single piece of data.');

	Firebolt.data(object, testData);
	Firebolt.removeData(object, 'a b');
	ok(!('a' in dataStore) && !('b' in dataStore), 'Removes multiple pieces of data when given a space-separated string.');

	Firebolt.data(object, testData);
	Firebolt.removeData(object, ['b', 'c']);
	ok(!('b' in dataStore) && !('c' in dataStore), 'Removes multiple pieces of data when given an array of strings.');

	Firebolt.data(object, testData);
	Firebolt.removeData(object);
	ok(Firebolt.isEmptyObject(dataStore), 'Removes all data when called with no specified values.');

	object = Firebolt.elem('div', {'data-test': true});
	dataStore = Firebolt.data(object, undefined, undefined, 1);
	Firebolt.removeData(object, 'test');
	ok(!('test' in dataStore), 'Removes a single piece of data that was pulled from a "data-*" attribute.');
});

test('text', function() {
	var text = Firebolt.text('hello');
	ok(text.nodeType === 3 && text.nodeValue === 'hello', 'Creates a new TextNode with the specified string value.');

	text = Firebolt.text();
	ok(text.nodeType === 3 && text.nodeValue === '', 'Creates a new, empty TextNode when called with no parameters.');
});
<commit_msg>Updated .data() unit tests to test the new functionality<commit_after>/**
 * Unit tests for the Firebolt function and namespace
 */

// References for Resharper
/// <reference path="../qunit/qunit.js"/>
/// <reference path="../../src/firebolt.js"/>

module('Firebolt');

test('ajaxSetup', function() {
	var ajaxSettings = Firebolt.ajaxSetup(),
		testObject = {
			a: [1, 2, 3],
			b: false,
			c: 0,
			d: {
				inner: 24
			}
		};

	Firebolt.ajaxSetup({test: 1});
	strictEqual(ajaxSettings.test, 1, 'Extends the AJAX settings object.');

	Firebolt.ajaxSetup({test: testObject});
	deepEqual(ajaxSettings.test, testObject, 'Deep-extends the AJAX settings object.');
	notEqual(ajaxSettings.test, testObject);
});

test('data', function() {
	var object = {},
		dataStore = Firebolt.data(object);

	ok(Firebolt.isPlainObject(dataStore) && Firebolt.isEmptyObject(dataStore),
		'When passed just an object, returns its data store object.');

	ok(Firebolt.isEmptyObject(object), 'Defines the data store at a non-enumerable property on the specifed object');

	strictEqual(Firebolt.data(object, 'a', 1), object, 'Returns the passed in object when setting properties.');

	strictEqual(dataStore.a, 1, 'Can store data properties.');

	Firebolt.data(object, {b: 'b', c: null});
	deepEqual(dataStore, {a: 1, b: 'b', c: null}, 'Can store multiple properties at once.');

	strictEqual(Firebolt.data(object, 'a'), 1, 'Can retrieve previously set properties.');

	var element = Firebolt.elem('div', {'data-stuff': 23});
	dataStore = Firebolt.data(element, undefined, undefined, 1);

	strictEqual(dataStore.stuff, 23,
		'Adds data from custom "data-*" attributes on elements to the data store and parses the data to the correct JavaScript type.');

	strictEqual(Firebolt.data(element, 'stuff', undefined, 1), 23,
		'Can retrieve data in custom "data-*" attributes on an element as the correct JavaScript type.');

	Firebolt.data(element, 'stuff', ['a', 'b'], 1);
	deepEqual(dataStore.stuff, ['a', 'b'],
		'Overwrites data retrieved from custom "data-*" attributes on an element when new data with the same key is set.');

	delete dataStore.stuff;
	strictEqual(Firebolt.data(element, undefined, undefined, 1).stuff, undefined,
		'When retrieving the data store object, it will not have any data at a key that was recently removed.');

	strictEqual(Firebolt.data(element, 'stuff', undefined, 1), 23,
		'Retrieves "data-*" attributes data when it is being retrieved specifically by name and there is currently no data with the same name.');

	strictEqual(Firebolt.data(element, undefined, undefined, 1).stuff, 23,
		'Adds data retrieved from custom "data-*" attributes to the data store object.');
});

test('elem', function() {
	var element = Firebolt.elem('div');
	ok(element.nodeType === 1 && element.nodeName === 'DIV', 'Creates a new Element.');

	element = Firebolt.elem('p', {'class': 'one two', 'data-custom': 'test'});
	ok(element.className === 'one two' && element.getAttribute('data-custom') === 'test',
		'Creates a new element with the specified properties');
});

test('globalEval', function() {
	Firebolt.globalEval('var globalEvalTest1 = true;');
	strictEqual(window.globalEvalTest1, true, 'Executes the passed in code in the global context.');

	Firebolt.globalEval('"use strict"; function globalEvalTest2() { return 10; }');
	strictEqual(window.globalEvalTest2(), 10, 'Executes code with a strict mode pragma in the global context.');
});

test('hasData', function() {
	var object = {};

	strictEqual(Firebolt.hasData(object), false,
		'Correctly reports that an object without Firebolt data does not have data.');

	Firebolt.data(object, 'a', 0);
	strictEqual(Firebolt.hasData(object), true,
		'Correctly reports that an object with Firebolt data has data.');

	Firebolt.removeData(object, 'a');
	strictEqual(Firebolt.hasData(object), false,
		'Correctly reports that an object that used to have Firebolt data does not have data.');

	object = Firebolt.elem('div', {'data-stuff': 23});
	strictEqual(Firebolt.hasData(object), false,
		'Correctly reports that an element that has not had the $.data() function called on it yet does not have data.');

	Firebolt.data(object, undefined, undefined, 1);
	strictEqual(Firebolt.hasData(object), true,
		'Correctly reports that an element with data pulled from a "data-*" attribute has data.');
});

test('isPlainObject', function func() {
	// False
	ok(!Firebolt.isPlainObject(1));
	ok(!Firebolt.isPlainObject('string'));
	ok(!Firebolt.isPlainObject(undefined));
	ok(!Firebolt.isPlainObject(null));
	ok(!Firebolt.isPlainObject([]));
	ok(!Firebolt.isPlainObject([{}]));
	ok(!Firebolt.isPlainObject(true));
	ok(!Firebolt.isPlainObject(/RegExp/));
	ok(!Firebolt.isPlainObject(func));
	ok(!Firebolt.isPlainObject(window));
	ok(!Firebolt.isPlainObject(document));
	ok(!Firebolt.isPlainObject(document.body));
	ok(!Firebolt.isPlainObject(document.createTextNode('text')));
	ok(!Firebolt.isPlainObject(document.getElementsByTagName('div')));
	ok(!Firebolt.isPlainObject(document.querySelectorAll('div')));

	// True
	ok(Firebolt.isPlainObject({}));
});

test('parseHTML', function() {
	var iframe = document.createElement('iframe'),
		element;

	element = Firebolt.parseHTML('
')[0];
	ok(element && element.tagName.toLowerCase() === 'div', 'Can make a simple, single element.');

	ok(element && element.ownerDocument === document, 'By default, creates elements in the context of the current document.');

	document.head.appendChild(iframe);
	element = Firebolt.parseHTML('
', iframe.contentDocument)[0];
	ok(element && element.ownerDocument === iframe.contentDocument, 'Can create elements in the context of another document.');
	iframe.remove();

	'option optgroup thead tbody tfoot colgroup caption tr col td th script link legend'.split(' ').forEach(function(tagName) {
		element = Firebolt.parseHTML('<' + tagName + ' class="test" />')[0];
		ok(element && element.tagName.toLowerCase() === tagName && element.className === 'test',
			'Can make special element: <' + tagName + '>.');
	});

	ok(Firebolt.parseHTML('
para

').length === 2, 'Can make multiple elements.');

	document.body.appendChild(Firebolt.parseHTML('')[0]);
	ok(window.whoa != 9, 'Created scripts are not evaluated.');
});

test('removeData', function() {
	var object = {},
		testData = {a: 1, b: 2, c: 3},
		dataStore = Firebolt.data(object, testData);

	Firebolt.removeData(object, 'a');
	ok(!('a' in dataStore), 'Removes a single piece of data.');

	Firebolt.data(object, testData);
	Firebolt.removeData(object, 'a b');
	ok(!('a' in dataStore) && !('b' in dataStore), 'Removes multiple pieces of data when given a space-separated string.');

	Firebolt.data(object, testData);
	Firebolt.removeData(object, ['b', 'c']);
	ok(!('b' in dataStore) && !('c' in dataStore), 'Removes multiple pieces of data when given an array of strings.');

	Firebolt.data(object, testData);
	Firebolt.removeData(object);
	ok(Firebolt.isEmptyObject(dataStore), 'Removes all data when called with no specified values.');

	object = Firebolt.elem('div', {'data-test': true});
	dataStore = Firebolt.data(object, undefined, undefined, 1);
	Firebolt.removeData(object, 'test');
	ok(!('test' in dataStore), 'Removes a single piece of data that was pulled from a "data-*" attribute.');
});

test('text', function() {
	var text = Firebolt.text('hello');
	ok(text.nodeType === 3 && text.nodeValue === 'hello', 'Creates a new TextNode with the specified string value.');

	text = Firebolt.text();
	ok(text.nodeType === 3 && text.nodeValue === '', 'Creates a new, empty TextNode when called with no parameters.');
});
<|endoftext|>


<commit_before>/*
Expollapser version 0.11.0
*/

(function ($) {

	// Defaults
	var expollapser_defaults = {
		'toggler': 'header',
		'bodyElement': 'next',
		'expandHeaderCss': null,
		'expandBodyCss': null,
		'collapseHeaderCss': null,
		'collapseBodyCss': null,
		'headerReplaceHtml': '',
		'open': false,
		'contentHtml': '',
		'expandAnimator': function (header, body, toggler, callback) { $(body).slideDown(200, callback); },
		'collapseAnimator': function (header, body, toggler, callback) { $(body).slideUp(200, callback); },
		'togglerSeparation': false
	};

	function expollapser_setDefaults(options) {
		if (options) {
			$.extend(expollapser_defaults, options);
		}
	}

	// Define methods of the expollapser plugin
	var methods = {

		// init : Sets up the plugin on the matched element(s)
		init: function (options) {
			return this.each(function () {
				var $this = $(this);
				var data = $this.data('expollapser');

				// If the plugin hasn't been initialized yet
				if (!data) {
					var settings = $.extend({}, expollapser_defaults); // Clone, shallow copy

					// Merge user options
					if (options) {
						$.extend(settings, options);
					}

					// Process the settings, basically by converting all convenience string settings
					// to underlying functions.
					settings.bodyElement = processBodyElement(settings.bodyElement);
					settings.headerReplaceHtml = processHeaderReplaceHtml(settings.headerReplaceHtml);

					$(this).bind('preExpand', function (e, context) {
						ensureClass(context.header, settings.expandHeaderCss);
						ensureClassRemoved(context.header, settings.collapseHeaderCss);
						ensureClass(context.body, settings.expandBodyCss);
						ensureClassRemoved(context.body, settings.collapseBodyCss);
					});

					$(this).bind('postExpand', function (e, context) {
						settings.headerReplaceHtml(context.header);
					});

					$(this).bind('postCollapse', function (e, context) {
						ensureClassRemoved(context.header, settings.expandHeaderCss);
						ensureClass(context.header, settings.collapseHeaderCss);
						ensureClassRemoved(context.body, settings.expandBodyCss);
						ensureClass(context.body, settings.collapseBodyCss);
						settings.headerReplaceHtml(context.header);
					});

					settings.contentHtml = processContentHtml(settings.contentHtml, settings);

					// Setup data
					$(this).data('expollapser', {
						isopen: settings.open,
						getTogglers: resolveTogglers(settings.toggler, $this),
						contentLoaded: false,
						disabled: false,
						settings: settings
					});

					if (settings.open == true) {
						ensureClass($(this), settings.expandHeaderCss);
						ensureClass(settings.bodyElement($(this)), settings.expandBodyCss);
						settings.headerReplaceHtml($(this));
						settings.bodyElement($this).show();
					}
					else {
						ensureClass($(this), settings.collapseHeaderCss);
						ensureClass(settings.bodyElement($(this)), settings.collapseBodyCss);
						settings.headerReplaceHtml($(this));
						settings.bodyElement($this).hide();
					}

					// Setup togglers
					ensureToggleHookup($(this).data('expollapser').getTogglers, $(this));
				}
			});
		},

		// disable: Disables expand/collapse functionality
		disable: function () {
			return this.each(function () {
				$(this).data('expollapser')['disabled'] = true;
				$(this).data('expollapser').getTogglers($(this)).css('cursor', 'auto');
			})
		},

		// enable: Enables expand/collapse functionality
		enable: function () {
			return this.each(function () {
				$(this).data('expollapser')['disabled'] = false;
				$(this).data('expollapser').getTogglers($(this)).css('cursor', 'hand');
			})
		},

		// toggle: Toggles between expanded and collapsed state
		toggle: function (toggler) {
			return this.each(function () {
				var data = $(this).data('expollapser');

				// Handle special case with multiple togglers producing multiple contents
				if (data.isopen == true && data.settings.togglerSeparation && data.expandedBy.get(0) != toggler.get(0)) {
					var $this = $(this);
					$(this).expollapser('collapse', data.expandedBy, function () { $this.expollapser('expand', toggler) });
				}
				else { // Default toggle
					if (data.isopen == false)
						$(this).expollapser('expand', toggler);
					else {
						$(this).expollapser('collapse', toggler);
					}
				}
			});
		},

		// expand: Expands the matched element(s)
		expand: function (toggler) {
			return this.each(function () {
				var $this = $(this);
				var data = $(this).data('expollapser');
				var settings = data.settings;
				if (data.isopen == false && data.disabled == false) {
					if (toggler == null)
						toggler = $(data.getTogglers($this).get(0));
					var bodyElement = settings.bodyElement($(this));
					$(this).trigger('preExpand', { header: $this, body: bodyElement, toggler: toggler });

					// Set content and do expand animation
					data.expandedBy = toggler;
					data.isopen = true;
					settings.contentHtml($(this), bodyElement, toggler, function () { });
					settings.expandAnimator($this, bodyElement, toggler, function () {
						$this.trigger('postExpand', { header: $this, body: bodyElement, toggler: toggler });
					});
				}
			});
		},

		collapse: function (toggler, callback) {
			return this.each(function () {
				var $this = $(this);
				var data = $this.data('expollapser');
				var settings = $this.data('expollapser').settings;
				if (data.isopen == true && data.disabled == false) {
					if (toggler == null)
						toggler = data.expandedBy;
					if (toggler == null)
						toggler = $this;
					var bodyElement = settings.bodyElement($this);
					$(this).trigger('preCollapse', { header: $this, body: bodyElement, toggler: toggler });

					data.isopen = false;
					settings.collapseAnimator($this, bodyElement, toggler, function () {
						$this.trigger('postCollapse', { header: $this, body: bodyElement, toggler: toggler });
						if (callback)
							callback();
					});
				}
			});
		}
	};

	// Ensures that the supplied togglers function on the supplied header element is setup with click events
	function ensureToggleHookup(togglersFn, headerElement) {
		togglersFn(headerElement).each(function () {
			// Set up click events of togglersFn if they have no click event already
			if (!$.data(this, 'events') || !$.data(this, 'events')['click'] || $.data(this, 'events')['click'].length == 0) {
				$(this).css('cursor', 'hand');
				if (!$(this).data('expollapser'))
					$(this).data('expollapser', { oldHtml: null });
				else
					$.extend($(this).data('expollapser'), { oldHtml: null });

				$(this).bind('click.expollapser', function () {
					headerElement.expollapser('toggle', $(this));
					return false;
				});
			}
		});
	}

	function assertStringOrFunction(subject, name, allowNull) {
		if ((!subject && allowNull) || typeof subject === 'string' || $.isFunction(subject))
			return;

		alert('Expollapser options error: ' + name + ' should be either a string or a function.');
	}

	function insertFn(fn, fnInsert) {
		return function (header, content, toggler) {
			fnInsert(header, content, toggler);
			fn(header, content, toggler);
		};
	}

	function ensureClass(jq, cssClass) {
		if (cssClass && !jq.hasClass(cssClass))
			jq.addClass(cssClass);
	};

	function ensureClassRemoved(jq, cssClass) {
		if (cssClass)
			jq.removeClass(cssClass);
	};

	// Parses bodyElement setting and returns a function to get the content element
	function processBodyElement(contentSetting) {
		assertStringOrFunction(contentSetting, 'bodyElement');
		if (typeof contentSetting === 'string') {
			if (contentSetting == 'next')
				return function (headerElement) { return headerElement.next(); };
			else if (contentSetting == 'prev')
				return function (headerElement) { return headerElement.prev(); };
			else
				return function () { return $(contentSetting); };
		}

		return contentSetting;
	}

	// Parse for convenience settings in togglers
	function resolveTogglers(togglersSetting, $header) {
		assertStringOrFunction(togglersSetting, 'togglers');
		var togglersFunction;
		if (typeof togglersSetting === 'string') {
			if (togglersSetting == 'header') {
				return function () { return $header; };
			}
			else if (togglersSetting == 'headerLinks') {
				return function () { return $('a', $header); };
			}
			else {
				var stringSetting = togglersSetting;
				return function () { return $(stringSetting, $header); };
			}
		}

		return togglersSetting;
	}

	function processHeaderReplaceHtml(setting) {
		assertStringOrFunction(setting, 'headerReplaceHtml');
		if (typeof setting === 'string') {
			var html = setting;
			if (html.indexOf('<-->') > -1) {
				var replaceExpressions = html.split(',');
				return function (header) {
					for (var item in replaceExpressions) {
						var pair = replaceExpressions[item].split('<-->');
						if (header.data('expollapser') && header.data('expollapser').isopen == true) {
							header.html(header.html().replace(pair[0], pair[1]));
						}
						else {
							header.html(header.html().replace(pair[1], pair[0]));
						}
					}
				};
			}

			return function () { };
		}

		return setting;
	}

	// TODO: getUniqueId check om loaded content.
	function processContentHtml(setting, settings) {
		assertStringOrFunction(setting, 'contentHtml', false);
		var processedSetting;
		if (typeof setting === 'string') {
			var stringSetting = setting;
			if (setting == 'togglerHref')
				stringSetting = 'togglerAttr:href';
			if (stringSetting.beginsWith('togglerAttr:')) {
				processedSetting = function (header, content, toggler, callback) {
					$.get(toggler.attr(stringSetting.substring(12)), function (response) {
						content.html(response);
						callback();
					});
				};
				settings.togglerSeparation = true;
			}
			else if (setting.beginsWith('url:'))
				processedSetting = function (header, content, toggler, callback) {
					$.get(stringSetting.substring(4), function (response) {
						content.html(response);
						callback();
					});
				};
			else if (setting.length > 0)
				processedSetting = function (header, content, toggler, callback) {
					content.html(stringSetting);
					callback();
				};
			else
				processedSetting = function (header, content, toggler, callback) { callback(); };
		}
		else {
			processedSetting = setting;
		}

		var finalSetting = function (header, content, toggler, callback) {
			var id = getUniqueId(header, content, toggler);
			if (header.data('expollapser').contentLoaded != id) {
				processedSetting(header, content, toggler, function () {
					ensureToggleHookup(header.data('expollapser').getTogglers, header);
					callback();
				});
			}
			else
				callback();
		};

		return finalSetting;
	}

	function getUniqueId(elem1, elem2, elem3) {
		return $(elem1).attr($.expando) + $(elem2).attr($.expando) + $(elem3).attr($.expando);
	}

	// Core plugin registration point
	$.fn.expollapser = function (method) {

		// Method calling logic
		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		}
		else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		}
		else {
			$.error('Method ' + method + ' does not exist on jQuery.expollapser');
		}
	};

	// Prototype extensions for common used string functions
	String.prototype.beginsWith = function (t, i) {
		if (i == false) {
			return (t == this.substring(0, t.length));
		}
		else {
			return (t.toLowerCase() == this.substring(0, t.length).toLowerCase());
		}
	}

	String.prototype.endsWith = function (t, i) {
		if (i == false) {
			return (t == this.substring(this.length - t.length));
		}
		else {
			return (t.toLowerCase() == this.substring(this.length - t.length).toLowerCase());
		}
	}
})(jQuery);

<commit_msg>Cleanup.<commit_after>/*
Expollapser version 0.11.0
*/

(function ($) {

	// Defaults
	var expollapser_defaults = {
		'toggler': 'header',
		'bodyElement': 'next',
		'expandHeaderCss': null,
		'expandBodyCss': null,
		'collapseHeaderCss': null,
		'collapseBodyCss': null,
		'headerReplaceHtml': '',
		'open': false,
		'contentHtml': '',
		'expandAnimator': function (header, body, toggler, callback) { $(body).slideDown(200, callback); },
		'collapseAnimator': function (header, body, toggler, callback) { $(body).slideUp(200, callback); },
		'togglerSeparation': false
	};

	function expollapser_setDefaults(options) {
		if (options) {
			$.extend(expollapser_defaults, options);
		}
	}

	// Define methods of the expollapser plugin
	var methods = {

		// init : Sets up the plugin on the matched element(s)
		init: function (options) {
			return this.each(function () {
				var $this = $(this);
				var data = $this.data('expollapser');

				// If the plugin hasn't been initialized yet
				if (!data) {
					var settings = $.extend({}, expollapser_defaults); // Clone, shallow copy

					// Merge user options
					if (options) {
						$.extend(settings, options);
					}

					// Process the settings, basically by converting all convenience string settings
					// to underlying functions.
					settings.bodyElement = processBodyElement(settings.bodyElement);
					settings.headerReplaceHtml = processHeaderReplaceHtml(settings.headerReplaceHtml);
					settings.contentHtml = processContentHtml(settings.contentHtml, settings);

					$(this).bind('preExpand', function (e, context) {
						ensureClass(context.header, settings.expandHeaderCss);
						ensureClassRemoved(context.header, settings.collapseHeaderCss);
						ensureClass(context.body, settings.expandBodyCss);
						ensureClassRemoved(context.body, settings.collapseBodyCss);
					});

					$(this).bind('postExpand', function (e, context) {
						settings.headerReplaceHtml(context.header);
					});

					$(this).bind('postCollapse', function (e, context) {
						ensureClassRemoved(context.header, settings.expandHeaderCss);
						ensureClass(context.header, settings.collapseHeaderCss);
						ensureClassRemoved(context.body, settings.expandBodyCss);
						ensureClass(context.body, settings.collapseBodyCss);
						settings.headerReplaceHtml(context.header);
					});

					// Setup data
					$(this).data('expollapser', {
						isopen: settings.open,
						getTogglers: resolveTogglers(settings.toggler, $this),
						contentLoaded: false,
						disabled: false,
						settings: settings
					});

					if (settings.open == true) {
						ensureClass($(this), settings.expandHeaderCss);
						ensureClass(settings.bodyElement($(this)), settings.expandBodyCss);
						settings.headerReplaceHtml($(this));
						settings.bodyElement($this).show();
					}
					else {
						ensureClass($(this), settings.collapseHeaderCss);
						ensureClass(settings.bodyElement($(this)), settings.collapseBodyCss);
						settings.headerReplaceHtml($(this));
						settings.bodyElement($this).hide();
					}

					// Setup togglers
					ensureToggleHookup($(this).data('expollapser').getTogglers, $(this));
				}
			});
		},

		// disable: Disables expand/collapse functionality
		disable: function () {
			return this.each(function () {
				$(this).data('expollapser')['disabled'] = true;
				$(this).data('expollapser').getTogglers($(this)).css('cursor', 'auto');
			})
		},

		// enable: Enables expand/collapse functionality
		enable: function () {
			return this.each(function () {
				$(this).data('expollapser')['disabled'] = false;
				$(this).data('expollapser').getTogglers($(this)).css('cursor', 'hand');
			})
		},

		// toggle: Toggles between expanded and collapsed state
		toggle: function (toggler) {
			return this.each(function () {
				var data = $(this).data('expollapser');

				// Handle special case with multiple togglers producing multiple contents
				if (data.isopen == true && data.settings.togglerSeparation && data.expandedBy.get(0) != toggler.get(0)) {
					var $this = $(this);
					$(this).expollapser('collapse', data.expandedBy, function () { $this.expollapser('expand', toggler) });
				}
				else { // Default toggle
					if (data.isopen == false)
						$(this).expollapser('expand', toggler);
					else {
						$(this).expollapser('collapse', toggler);
					}
				}
			});
		},

		// expand: Expands the matched element(s)
		expand: function (toggler) {
			return this.each(function () {
				var $this = $(this);
				var data = $(this).data('expollapser');
				var settings = data.settings;
				if (data.isopen == false && data.disabled == false) {
					if (toggler == null)
						toggler = $(data.getTogglers($this).get(0));
					var bodyElement = settings.bodyElement($(this));
					$(this).trigger('preExpand', { header: $this, body: bodyElement, toggler: toggler });

					// Set content and do expand animation
					data.expandedBy = toggler;
					data.isopen = true;
					settings.contentHtml($(this), bodyElement, toggler, function () { });
					settings.expandAnimator($this, bodyElement, toggler, function () {
						$this.trigger('postExpand', { header: $this, body: bodyElement, toggler: toggler });
					});
				}
			});
		},

		collapse: function (toggler, callback) {
			return this.each(function () {
				var $this = $(this);
				var data = $this.data('expollapser');
				var settings = $this.data('expollapser').settings;
				if (data.isopen == true && data.disabled == false) {
					if (toggler == null)
						toggler = data.expandedBy;
					if (toggler == null)
						toggler = $this;
					var bodyElement = settings.bodyElement($this);
					$(this).trigger('preCollapse', { header: $this, body: bodyElement, toggler: toggler });

					data.isopen = false;
					settings.collapseAnimator($this, bodyElement, toggler, function () {
						$this.trigger('postCollapse', { header: $this, body: bodyElement, toggler: toggler });
						if (callback)
							callback();
					});
				}
			});
		}
	};

	// Ensures that the supplied togglers function on the supplied header element is setup with click events
	function ensureToggleHookup(togglersFn, headerElement) {
		togglersFn(headerElement).each(function () {
			// Set up click events of togglersFn if they have no click event already
			if (!$.data(this, 'events') || !$.data(this, 'events')['click'] || $.data(this, 'events')['click'].length == 0) {
				$(this).css('cursor', 'hand');
				$(this).bind('click.expollapser', function () {
					headerElement.expollapser('toggle', $(this));
					return false;
				});
			}
		});
	}

	function assertStringOrFunction(subject, name, allowNull) {
		if ((!subject && allowNull) || typeof subject === 'string' || $.isFunction(subject))
			return;

		alert('Expollapser options error: ' + name + ' should be either a string or a function.');
	}

	function ensureClass(jq, cssClass) {
		if (cssClass && !jq.hasClass(cssClass))
			jq.addClass(cssClass);
	};

	function ensureClassRemoved(jq, cssClass) {
		if (cssClass)
			jq.removeClass(cssClass);
	};

	// Parses bodyElement setting and returns a function to get the content element
	function processBodyElement(contentSetting) {
		assertStringOrFunction(contentSetting, 'bodyElement');
		if (typeof contentSetting === 'string') {
			if (contentSetting == 'next')
				return function (headerElement) { return headerElement.next(); };
			else if (contentSetting == 'prev')
				return function (headerElement) { return headerElement.prev(); };
			else
				return function () { return $(contentSetting); };
		}

		return contentSetting;
	}

	// Parse for convenience settings in togglers
	function resolveTogglers(togglersSetting, $header) {
		assertStringOrFunction(togglersSetting, 'togglers');
		var togglersFunction;
		if (typeof togglersSetting === 'string') {
			if (togglersSetting == 'header') {
				return function () { return $header; };
			}
			else if (togglersSetting == 'headerLinks') {
				return function () { return $('a', $header); };
			}
			else {
				var stringSetting = togglersSetting;
				return function () { return $(stringSetting, $header); };
			}
		}

		return togglersSetting;
	}

	function processHeaderReplaceHtml(setting) {
		assertStringOrFunction(setting, 'headerReplaceHtml');
		if (typeof setting === 'string') {
			var html = setting;
			if (html.indexOf('<-->') > -1) {
				var replaceExpressions = html.split(',');
				return function (header) {
					for (var item in replaceExpressions) {
						var pair = replaceExpressions[item].split('<-->');
						if (header.data('expollapser') && header.data('expollapser').isopen == true) {
							header.html(header.html().replace(pair[0], pair[1]));
						}
						else {
							header.html(header.html().replace(pair[1], pair[0]));
						}
					}
				};
			}

			return function () { };
		}

		return setting;
	}

	// TODO: getUniqueId check om loaded content.
	function processContentHtml(setting, settings) {
		assertStringOrFunction(setting, 'contentHtml', false);
		var processedSetting;
		if (typeof setting === 'string') {
			var stringSetting = setting;
			if (setting == 'togglerHref')
				stringSetting = 'togglerAttr:href';
			if (stringSetting.beginsWith('togglerAttr:')) {
				processedSetting = function (header, content, toggler, callback) {
					$.get(toggler.attr(stringSetting.substring(12)), function (response) {
						content.html(response);
						callback();
					});
				};
				settings.togglerSeparation = true;
			}
			else if (setting.beginsWith('url:'))
				processedSetting = function (header, content, toggler, callback) {
					$.get(stringSetting.substring(4), function (response) {
						content.html(response);
						callback();
					});
				};
			else if (setting.length > 0)
				processedSetting = function (header, content, toggler, callback) {
					content.html(stringSetting);
					callback();
				};
			else
				processedSetting = function (header, content, toggler, callback) { callback(); };
		}
		else {
			processedSetting = setting;
		}

		var finalSetting = function (header, content, toggler, callback) {
			var id = getUniqueId(header, content, toggler);
			if (header.data('expollapser').contentLoaded != id) {
				processedSetting(header, content, toggler, function () {
					ensureToggleHookup(header.data('expollapser').getTogglers, header);
					callback();
				});
			}
			else
				callback();
		};

		return finalSetting;
	}

	function getUniqueId(elem1, elem2, elem3) {
		return $(elem1).attr($.expando) + $(elem2).attr($.expando) + $(elem3).attr($.expando);
	}

	// Core plugin registration point
	$.fn.expollapser = function (method) {

		// Method calling logic
		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		}
		else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		}
		else {
			$.error('Method ' + method + ' does not exist on jQuery.expollapser');
		}
	};

	// Prototype extensions for common used string functions
	String.prototype.beginsWith = function (t, i) {
		if (i == false) {
			return (t == this.substring(0, t.length));
		}
		else {
			return (t.toLowerCase() == this.substring(0, t.length).toLowerCase());
		}
	}

	String.prototype.endsWith = function (t, i) {
		if (i == false) {
			return (t == this.substring(this.length - t.length));
		}
		else {
			return (t.toLowerCase() == this.substring(this.length - t.length).toLowerCase());
		}
	}
})(jQuery);

<|endoftext|>


<commit_before>import fs from 'fs'
import _ from 'lodash'
import postcss from 'postcss'
import cssnext from 'postcss-cssnext'
import stylefmt from 'stylefmt'

import defaultConfig from './defaultConfig'

import addCustomMediaQueries from './lib/addCustomMediaQueries'
import generateUtilities from './lib/generateUtilities'
// import substituteHoverableAtRules from './lib/substituteHoverableAtRules'
import substituteResponsiveAtRules from './lib/substituteResponsiveAtRules'
import substituteClassApplyAtRules from './lib/substituteClassApplyAtRules'

export default postcss.plugin('tailwind', options => {
  options = options || defaultConfig

  return postcss([
    addCustomMediaQueries(options),
    generateUtilities(options),
    // substituteHoverableAtRules(options),
    substituteResponsiveAtRules(options),
    substituteClassApplyAtRules(options),
    cssnext(),
    stylefmt,
  ])
})
<commit_msg>Re-enable hoverable at rules<commit_after>import fs from 'fs'
import _ from 'lodash'
import postcss from 'postcss'
import cssnext from 'postcss-cssnext'
import stylefmt from 'stylefmt'

import defaultConfig from './defaultConfig'

import addCustomMediaQueries from './lib/addCustomMediaQueries'
import generateUtilities from './lib/generateUtilities'
import substituteHoverableAtRules from './lib/substituteHoverableAtRules'
import substituteResponsiveAtRules from './lib/substituteResponsiveAtRules'
import substituteClassApplyAtRules from './lib/substituteClassApplyAtRules'

export default postcss.plugin('tailwind', options => {
  options = options || defaultConfig

  return postcss([
    addCustomMediaQueries(options),
    generateUtilities(options),
    substituteHoverableAtRules(options),
    substituteResponsiveAtRules(options),
    substituteClassApplyAtRules(options),
    cssnext(),
    stylefmt,
  ])
})
<|endoftext|>