<commit_before>'use strict';

/*
  Note that pretty much everything in this file is purpose built for doing
  vertex animation in such a way that all animations are always running, run
  in sync, and all copies of the same vertex animated mesh share the same data.
  This means it is not generalized at all, and abuses various object properties
  to store state information which would normally be abstracted elsewhere for
  non-shared animating, or controllable animations (play,pause,rewind).
 */

function MorphAnimManager() {
  this.anims = {};
  this.cache = new IndexedCache(this._loadOne.bind(this));
}

// Loads one
MorphAnimManager.prototype._loadOne = function(animIdx, callback) {
  var animInfo = this.anims[animIdx];

  var texture = ROSETexLoader.load(animInfo.texPath);
  texture.wrapT = THREE.RepeatWrapping;
  texture.wrapS = THREE.RepeatWrapping;
  var mat = new THREE.MeshBasicMaterial({color: 0xffffff, map: texture});

  if (animInfo.twoSided) {
    mat.side = THREE.DoubleSide;
  }
  if (animInfo.alphaTest) {
    mat.alphaTest = 0.5;
  }

  mat.transparent = true;
  mat.opacity = animInfo.alpha;
  mat.depthTest = animInfo.depthTest;
  mat.depthWrite = animInfo.depthWrite;
  mat.blending = THREE.CustomBlending;
  mat.blendEquation = convertZnzinBlendOp(animInfo.blendOp);
  mat.blendSrc = convertZnzinBlendType(animInfo.blendSrc);
  mat.blendDst = convertZnzinBlendType(animInfo.blendDst);

  Mesh.load(animInfo.meshPath, function(geom) {
    geom.dynamic = true;

    Animation.load(animInfo.animPath, function(animData) {
      // Validate the animation
      for (var l = 0; l < animData.channels.length; ++l) {
        var channel = animData.channels[l];
        if (channel.type === Animation.CHANNEL_TYPE.Position) {
        } else if (channel.type === Animation.CHANNEL_TYPE.Normal) {
        } else if (channel.type === Animation.CHANNEL_TYPE.Uv1) {
        } else {
          console.warn('Encountered unhandled morph animation channel type:', channel.type);
        }
      }

      console.log(animData);

      // Create an animator to tick every frame
      var anim = new _VertexAnimUpdater(geom, animData);
      THREE.AnimationHandler.play(anim);

      // Force an update now as the mesh does not always match frame 0
      anim.update(0);

      if (callback) {
        callback({
          geom: geom,
          mat: mat,
          anim: anim
        });
      }
    });
  });

};

MorphAnimManager.prototype.create = function(animIdx, callback) {
  var obj = new THREE.Object3D();

  this.cache.get(animIdx, function(data) {
    var mesh = new THREE.Mesh(data.geom, data.mat);
    mesh.renderDepth = -99999;
    obj.add(mesh);

    if (callback) {
      callback();
    }
  });

  return obj;
};

/**
 * Load helper so the MorphAnimManager can be controlled by the GDM.
 *
 * @param path Path to STB listing the morph objects
 * @param callback
 */
MorphAnimManager.load = function(path, callback) {
  var data = new MorphAnimManager();

  var waitAll = new MultiWait();
  var dataTableWait = waitAll.one();
  DataTable.load(path, function(qdata) {
    for (var i = 0; i < qdata.rows.length; ++i) {
      var animInfo = qdata.rows[i];
      if (animInfo[1] && animInfo[3]) {
        data.anims[i] = {
          meshPath: animInfo[1],
          animPath: animInfo[2],
          texPath: animInfo[3],
          alpha: parseFloat(animInfo[4]),
          twoSided: parseInt(animInfo[5]) !== 0,
          alphaTest: parseInt(animInfo[6]) !== 0,
          depthTest: parseInt(animInfo[7]) !== 0,
          depthWrite: parseInt(animInfo[8]) !== 0,
          blendSrc: parseInt(animInfo[9]),
          blendDest: parseInt(animInfo[10]),
          blendOp: parseInt(animInfo[11])
        };
      }
    }
    dataTableWait();
  });
  waitAll.wait(function() {
    callback(data);
  });
};

function _VertexAnimUpdater(geom, anim) {
  this.geom = geom;
  this.anim = anim;
  this.time = 0;
  this.frame = 0;
}

_VertexAnimUpdater.prototype.resetBlendWeights = function() {
};

_VertexAnimUpdater.prototype.update = function(delta) {
  this.time += delta;

  var newFrame = Math.floor(this.time * this.anim.fps);
  while (newFrame >= this.anim.frameCount) {
    this.time -= this.anim.frameCount / this.anim.fps;
    newFrame -= this.anim.frameCount;
  }
  if (newFrame === this.frame) {
    return;
  }
  this.frame = newFrame;

  for (var i = 0; i < this.anim.channels.length; ++i) {
    var channel = this.anim.channels[i];
    var frame = channel.frames[this.frame];

    if (channel.type === Animation.CHANNEL_TYPE.Position) {
      console.log('channel', i, 'frame', this.frame, 'position', frame);
      var attrib = this.geom.attributes['position'];
      attrib.array[channel.index * 3 + 0] = frame.x;
      attrib.array[channel.index * 3 + 1] = frame.y;
      attrib.array[channel.index * 3 + 2] = frame.z;
      attrib.needsUpdate = true;
    } else if (channel.type === Animation.CHANNEL_TYPE.Uv1) {
      var attrib = this.geom.attributes['uv'];
      attrib.array[channel.index * 2 + 0] = frame.x;
      attrib.array[channel.index * 2 + 1] = frame.y;
      attrib.needsUpdate = true;
    }
  }
  /*
  var posAttrib = this.geom.attributes['position'];
  posAttrib.array = this.frames[this.frame];
  posAttrib.needsUpdate = true;
  */
};
<commit_msg>Fix waterfall material blending information typo.<commit_after>'use strict';

/*
  Note that pretty much everything in this file is purpose built for doing
  vertex animation in such a way that all animations are always running, run
  in sync, and all copies of the same vertex animated mesh share the same data.
  This means it is not generalized at all, and abuses various object properties
  to store state information which would normally be abstracted elsewhere for
  non-shared animating, or controllable animations (play,pause,rewind).
 */

function MorphAnimManager() {
  this.anims = {};
  this.cache = new IndexedCache(this._loadOne.bind(this));
}

// Loads one
MorphAnimManager.prototype._loadOne = function(animIdx, callback) {
  var animInfo = this.anims[animIdx];

  var texture = ROSETexLoader.load(animInfo.texPath);
  texture.wrapT = THREE.RepeatWrapping;
  texture.wrapS = THREE.RepeatWrapping;
  var mat = new THREE.MeshBasicMaterial({color: 0xffffff, map: texture});

  if (animInfo.twoSided) {
    mat.side = THREE.DoubleSide;
  }
  if (animInfo.alphaTest) {
    mat.alphaTest = 0.5;
  }

  mat.transparent = true;
  mat.opacity = animInfo.alpha;
  mat.depthTest = animInfo.depthTest;
  mat.depthWrite = animInfo.depthWrite;
  mat.blending = THREE.CustomBlending;
  mat.blendEquation = convertZnzinBlendOp(animInfo.blendOp);
  mat.blendSrc = convertZnzinBlendType(animInfo.blendSrc);
  mat.blendDst = convertZnzinBlendType(animInfo.blendDst);

  Mesh.load(animInfo.meshPath, function(geom) {
    geom.dynamic = true;

    Animation.load(animInfo.animPath, function(animData) {
      // Validate the animation
      for (var l = 0; l < animData.channels.length; ++l) {
        var channel = animData.channels[l];
        if (channel.type === Animation.CHANNEL_TYPE.Position) {
        } else if (channel.type === Animation.CHANNEL_TYPE.Normal) {
        } else if (channel.type === Animation.CHANNEL_TYPE.Uv1) {
        } else {
          console.warn('Encountered unhandled morph animation channel type:', channel.type);
        }
      }

      console.log(animData);

      // Create an animator to tick every frame
      var anim = new _VertexAnimUpdater(geom, animData);
      THREE.AnimationHandler.play(anim);

      // Force an update now as the mesh does not always match frame 0
      anim.update(0);

      if (callback) {
        callback({
          geom: geom,
          mat: mat,
          anim: anim
        });
      }
    });
  });

};

MorphAnimManager.prototype.create = function(animIdx, callback) {
  var obj = new THREE.Object3D();

  this.cache.get(animIdx, function(data) {
    var mesh = new THREE.Mesh(data.geom, data.mat);
    obj.add(mesh);

    if (callback) {
      callback();
    }
  });

  return obj;
};

/**
 * Load helper so the MorphAnimManager can be controlled by the GDM.
 *
 * @param path Path to STB listing the morph objects
 * @param callback
 */
MorphAnimManager.load = function(path, callback) {
  var data = new MorphAnimManager();

  var waitAll = new MultiWait();
  var dataTableWait = waitAll.one();
  DataTable.load(path, function(qdata) {
    for (var i = 0; i < qdata.rows.length; ++i) {
      var animInfo = qdata.rows[i];
      if (animInfo[1] && animInfo[3]) {
        data.anims[i] = {
          meshPath: animInfo[1],
          animPath: animInfo[2],
          texPath: animInfo[3],
          alpha: parseFloat(animInfo[4]),
          twoSided: parseInt(animInfo[5]) !== 0,
          alphaTest: parseInt(animInfo[6]) !== 0,
          depthTest: parseInt(animInfo[7]) !== 0,
          depthWrite: parseInt(animInfo[8]) !== 0,
          blendSrc: parseInt(animInfo[9]),
          blendDst: parseInt(animInfo[10]),
          blendOp: parseInt(animInfo[11])
        };
      }
    }
    dataTableWait();
  });
  waitAll.wait(function() {
    callback(data);
  });
};

function _VertexAnimUpdater(geom, anim) {
  this.geom = geom;
  this.anim = anim;
  this.time = 0;
  this.frame = 0;
}

_VertexAnimUpdater.prototype.resetBlendWeights = function() {
};

_VertexAnimUpdater.prototype.update = function(delta) {
  this.time += delta;

  var newFrame = Math.floor(this.time * this.anim.fps);
  while (newFrame >= this.anim.frameCount) {
    this.time -= this.anim.frameCount / this.anim.fps;
    newFrame -= this.anim.frameCount;
  }
  if (newFrame === this.frame) {
    return;
  }
  this.frame = newFrame;

  for (var i = 0; i < this.anim.channels.length; ++i) {
    var channel = this.anim.channels[i];
    var frame = channel.frames[this.frame];

    if (channel.type === Animation.CHANNEL_TYPE.Position) {
      console.log('channel', i, 'frame', this.frame, 'position', frame);
      var attrib = this.geom.attributes['position'];
      attrib.array[channel.index * 3 + 0] = frame.x;
      attrib.array[channel.index * 3 + 1] = frame.y;
      attrib.array[channel.index * 3 + 2] = frame.z;
      attrib.needsUpdate = true;
    } else if (channel.type === Animation.CHANNEL_TYPE.Uv1) {
      var attrib = this.geom.attributes['uv'];
      attrib.array[channel.index * 2 + 0] = frame.x;
      attrib.array[channel.index * 2 + 1] = frame.y;
      attrib.needsUpdate = true;
    }
  }
  /*
  var posAttrib = this.geom.attributes['position'];
  posAttrib.array = this.frames[this.frame];
  posAttrib.needsUpdate = true;
  */
};
<|endoftext|>


<commit_before>'use strict';

var app = angular.module('isa.overview');

app.controller('OverviewController',
	['$scope', '$modal', '$meteor', '$state', 'growl',
	function($scope, $modal, $meteor, $state, growl) {

		$scope.modules = $scope.$meteorCollection(Modules);
		Deps.autorun(function() {
			var group = Partitioner.group();
			$scope.$meteorSubscribe("modules", group);
		});

		//setup filters for the data in the tabs on the overview page
		$scope.activeFilter = function(module) {
			return !module.inTrash && !module.isTemplate && !module.isArchived;
		}
		$scope.trashedFilter = function(module){
			return module.inTrash;
		}
		$scope.archivedFilter = function(module) {
			return !module.inTrash && module.isArchived;
		}
		$scope.templateFilter = function(module) {
			return !module.inTrash && !module.isArchived && module.isTemplate;
		}

	$scope.editModule = function(module) {

		$modal.open({
			templateUrl: 'client/module/module.ng.html',
			controller: 'ModuleController',
			resolve: {
				organisation: angular.noop,
				module: function () {
				  	return module;
				}
			}
		}).result.then(function(result) {

			switch (result.action) {
				case 'delete':
					//deleting is about setting the inTrash flag
					$scope.modules.save( result.context).then( function() {

						if (result.context.type == 'docwiki') {
							growl.success('Document "' + result.context.title + '" has been moved to the trash');
						} else {
							growl.success('The module "' + result.context.title + '" has been moved to the trash');
						}

					})
					break;

				case 'restore':

					//restoring is about setting the inTrash flag
					$scope.modules.save( result.context).then( function() {

						if (result.context.type == 'docwiki') {
							growl.success('Document "' + result.context.title + '" has been restored from the trash');
						} else {
							growl.success('The module "' + result.context.title + '" has been restored from the trash');
						}

					});
					break;

				case 'save':

					$scope.modules.save( result.context).then( function() {
						growl.success('Module settings have been updated');
					});
					break;

			}

		});

	};

	$scope.addModule = function() {

		$modal.open({
			templateUrl: 'client/module/module.ng.html',
			controller: 'ModuleController',
			resolve: {
				module : angular.noop,
			}
		}).result.then(function(result) {

				if (result.action === 'save') {

					//save the new/ updated module
					$scope.modules.save(result.context)
						.then( function() {
							growl.success('The module has been added');
						});
				}

		});

	};

}]);
<commit_msg>feature(core): Added note as to why we're using Deps.autorun<commit_after>'use strict';

var app = angular.module('isa.overview');

app.controller('OverviewController',
	['$scope', '$modal', '$meteor', '$state', 'growl',
	function($scope, $modal, $meteor, $state, growl) {

		$scope.modules = $scope.$meteorCollection(Modules);

		/**
		 * @see https://github.com/mizzao/meteor-partitioner#configuring-subscriptions
		 */
		Deps.autorun(function() {
			var group = Partitioner.group();
			$scope.$meteorSubscribe("modules", group);
		});

		//setup filters for the data in the tabs on the overview page
		$scope.activeFilter = function(module) {
			return !module.inTrash && !module.isTemplate && !module.isArchived;
		}
		$scope.trashedFilter = function(module){
			return module.inTrash;
		}
		$scope.archivedFilter = function(module) {
			return !module.inTrash && module.isArchived;
		}
		$scope.templateFilter = function(module) {
			return !module.inTrash && !module.isArchived && module.isTemplate;
		}

	$scope.editModule = function(module) {

		$modal.open({
			templateUrl: 'client/module/module.ng.html',
			controller: 'ModuleController',
			resolve: {
				organisation: angular.noop,
				module: function () {
				  	return module;
				}
			}
		}).result.then(function(result) {

			switch (result.action) {
				case 'delete':
					//deleting is about setting the inTrash flag
					$scope.modules.save( result.context).then( function() {

						if (result.context.type == 'docwiki') {
							growl.success('Document "' + result.context.title + '" has been moved to the trash');
						} else {
							growl.success('The module "' + result.context.title + '" has been moved to the trash');
						}

					})
					break;

				case 'restore':

					//restoring is about setting the inTrash flag
					$scope.modules.save( result.context).then( function() {

						if (result.context.type == 'docwiki') {
							growl.success('Document "' + result.context.title + '" has been restored from the trash');
						} else {
							growl.success('The module "' + result.context.title + '" has been restored from the trash');
						}

					});
					break;

				case 'save':

					$scope.modules.save( result.context).then( function() {
						growl.success('Module settings have been updated');
					});
					break;

			}

		});

	};

	$scope.addModule = function() {

		$modal.open({
			templateUrl: 'client/module/module.ng.html',
			controller: 'ModuleController',
			resolve: {
				module : angular.noop,
			}
		}).result.then(function(result) {

				if (result.action === 'save') {

					//save the new/ updated module
					$scope.modules.save(result.context)
						.then( function() {
							growl.success('The module has been added');
						});
				}

		});

	};

}]);
<|endoftext|>


<commit_before>// Copyright 2021 Google LLC

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     https://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { Loader } from '@googlemaps/js-api-loader';

const apiOptions = {
  "apiKey": "YOUR_API_KEY",
  "version": "beta"
};

const mapOptions = {
  "zoom": 18,
  "center": { lat: 35.6594945, lng: 139.6999859 },
  "mapId": "YOUR_MAP_ID"
}

async function initMap() {
  const mapDiv = document.getElementById("map");
  const apiLoader = new Loader(apiOptions);
  await apiLoader.load()
  return new google.maps.Map(mapDiv, mapOptions);
}

function initWebglOverlayView (map) {
  let scene, renderer, camera, loader;
  // WebGLOverlayView code goes here
}

(async () => {
  const map = await initMap();
})();<commit_msg>fixes typo<commit_after>// Copyright 2021 Google LLC

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     https://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { Loader } from '@googlemaps/js-api-loader';

const apiOptions = {
  "apiKey": "YOUR_API_KEY",
  "version": "beta"
};

const mapOptions = {
  "zoom": 18,
  "center": { lat: 35.6594945, lng: 139.6999859 },
  "mapId": "YOUR_MAP_ID"
}

async function initMap() {
  const mapDiv = document.getElementById("map");
  const apiLoader = new Loader(apiOptions);
  await apiLoader.load()
  return new google.maps.Map(mapDiv, mapOptions);
}

function initWebGLOverlayView (map) {
  let scene, renderer, camera, loader;
  // WebGLOverlayView code goes here
}

(async () => {
  const map = await initMap();
})();<|endoftext|>


<commit_before>function createContextMenu() {
  chrome.contextMenus.create({ id: 'bracketless', title: 'getAll().clearAll()' });
}
// function updateContextMenu(text) {
//   chrome.contextMenus.update('bracketless', { title: text });
// }

const tabState = {
  get(tabId) {
    return new Promise((resolve) => {
      chrome.storage.local.get(tabId.toString(), (state) => {
        resolve(state[tabId]);
      });
    });
  },
  set(tabId, value) {
    return new Promise((resolve) => {
      chrome.storage.local.set({ [tabId]: value }, () => resolve());
    });
  },
  remove(tabId) {
    return new Promise((resolve) => {
      chrome.storage.local.remove(tabId.toString(), () => resolve());
    });
  },
  clearAll() {
    chrome.storage.local.clear();
  },
  getAll() { // Dev QoL
    chrome.storage.local.get(null, (all) => {
      console.warn('local.get(null)');
      console.log(all);
      this.clearAll();
    });
  },
};

function load(tabId) {
  return new Promise((resolve) => {
    chrome.tabs.executeScript(tabId, { file: 'src/bracketless.js' }, () => {
      chrome.browserAction.setIcon({ tabId, path: 'icons/play.png' });
      chrome.browserAction.setTitle({ tabId, title: 'Collapse brackets' });
      // updateContextMenu('Collapse brackets');
      chrome.tabs.insertCSS(tabId, { file: 'css/action.css' });
      chrome.tabs.executeScript(tabId, { file: 'src/action.js' }, () => {
        tabState.set(tabId, false)
          .then(() => resolve('load resolved'));
      });
    });
  });
}

function activate(tabId, active) {
  return new Promise((resolve) => {
    const action = active === true ?
      { message: 'Pause collapsing', reverseIcon: 'pause' } :
      { message: 'Collapse brackets', reverseIcon: 'play' };
    chrome.browserAction.setIcon({ tabId, path: `icons/${action.reverseIcon}.png` });
    chrome.browserAction.setTitle({ tabId, title: action.message });
    // updateContextMenu(state.message);
    chrome.tabs.sendMessage(tabId, active, () => {
      tabState.set(tabId, active)
        .then(() => { resolve(`action resolved. enabled: ${active}`); });
    });
  });
}

function listenerAction(tabId) {
  tabState.get(tabId)
    .then((state) => {
      console.warn('getState.then()');
      console.log(state);

      if (state === undefined) {
        return load(tabId);
      } else if (state === false) {
        return activate(tabId, true);
      } else if (state === true) {
        return activate(tabId, false);
      }
      return Promise.reject(new Error('listenerAction if else didn\'t work'));
    })
    .then((action) => {
      console.log(action);
      console.log('------------------------');
    });
}

// function checkPermission() {
//   return new Promise((resolve, reject) => chrome.permissions.contains({
//     permissions: ['tabs'],
//     origins: ['http://*/', 'https://*/'],
//   }, (permission) => {
//     if (permission) resolve(permission);
//     else reject(new Error(`Bracketless. Tabs at any origins was denied. Permission: ${permission}`));
//   }));
// }

// function autoAction(tabId) {
//   chrome.storage.sync.get(null, (options) => {
//     if (options.autoLoad && options.autoPlay === false) load(tabId);
//     if (options.autoLoad && options.autoPlay) {
//       load(tabId)
//         .then(() => activate(tabId, true));
//     }
//   });
// }
function addOnUpdated() {
  chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
    // Works only with auto options. Chrome browser utility page check (requires tab permission)
    if (/(chrome)(?:[/:-])/.test(tab.url)) return;

    if (changeInfo.status === 'complete' && tab.active) {
      // no permission, either new tab or tab refresh
      if (tab.url === undefined) {
        tabState.get(tabId)
          .then((state) => {
            console.log('undefined check');
            // state loaded, no permission = page refresh
            if (typeof state === 'boolean') tabState.remove(tabId);
          });
      } else if (/#/.test(tab.url)) {
        console.log('its just a bookmark update, dont do anything stupid');
      }

      // autoAction(tabId);
    }
  });
}

function removedListener(tabId, info) {
  tabState.get(tabId).then((state) => {
    // act only if state is defined (obtained currentTab permission)
    if (state !== undefined) {
      console.warn('onRemoved IF');
      console.log(state, info);

      // tab is focused and tab gets closed
      tabState.remove(tabId);

      // tab is focused and browser window gets closed
      if (info.insWindowClosing) {
        tabState.clearAll();
      }
    } else {
      console.warn('onRemoved ELSE');
    }
  });
}
function addOnRemoved() {
  chrome.tabs.onRemoved.addListener((tabId, removeInfo) => {
    console.warn('onRemoved');
    removedListener(tabId, removeInfo);
  });
}

function syncDefault() {
  chrome.storage.sync.set({
    lowLimit: 13,
    upLimit: 255,
    autoLoad: false,
    autoPlay: false,
  });
}
function checkOptsUse(cb) {
  chrome.storage.sync.getBytesInUse(null, (bytes) => { if (bytes === 0) cb(); });
}

function onInstalled() {
  chrome.runtime.onInstalled.addListener(() => {
    checkOptsUse(syncDefault); // if not in use, sync default
    createContextMenu();

    // listeners
    chrome.browserAction.onClicked.addListener(tab => listenerAction(tab.id));
    chrome.contextMenus.onClicked.addListener((_, tab) => tabState.getAll());
    addOnUpdated();
    addOnRemoved();
    // checkPermission()
    //   .then(autoAction, e => console.warn(e)); // no permission, just ignore?
  });
}

onInstalled();
<commit_msg>Re-enable autoAction(), update addOnUpdated()<commit_after>function createContextMenu() {
  chrome.contextMenus.create({ id: 'bracketless', title: 'getAll().clearAll()' });
}
// function updateContextMenu(text) {
//   chrome.contextMenus.update('bracketless', { title: text });
// }

const tabState = {
  get(tabId) {
    return new Promise((resolve) => {
      chrome.storage.local.get(tabId.toString(), (state) => {
        resolve(state[tabId]);
      });
    });
  },
  set(tabId, value) {
    return new Promise((resolve) => {
      chrome.storage.local.set({ [tabId]: value }, () => resolve());
    });
  },
  remove(tabId) {
    return new Promise((resolve) => {
      chrome.storage.local.remove(tabId.toString(), () => resolve());
    });
  },
  clearAll() {
    chrome.storage.local.clear();
  },
  getAll() { // Dev QoL
    chrome.storage.local.get(null, (all) => {
      console.warn('local.get(null)');
      console.log(all);
      this.clearAll();
    });
  },
};

function load(tabId) {
  return new Promise((resolve) => {
    chrome.tabs.executeScript(tabId, { file: 'src/bracketless.js' }, () => {
      chrome.browserAction.setIcon({ tabId, path: 'icons/play.png' });
      chrome.browserAction.setTitle({ tabId, title: 'Collapse brackets' });
      // updateContextMenu('Collapse brackets');
      chrome.tabs.insertCSS(tabId, { file: 'css/action.css' });
      chrome.tabs.executeScript(tabId, { file: 'src/action.js' }, () => {
        tabState.set(tabId, false)
          .then(() => resolve('load resolved'));
      });
    });
  });
}

function activate(tabId, active) {
  return new Promise((resolve) => {
    const action = active === true ?
      { message: 'Pause collapsing', reverseIcon: 'pause' } :
      { message: 'Collapse brackets', reverseIcon: 'play' };
    chrome.browserAction.setIcon({ tabId, path: `icons/${action.reverseIcon}.png` });
    chrome.browserAction.setTitle({ tabId, title: action.message });
    // updateContextMenu(state.message);
    chrome.tabs.sendMessage(tabId, active, () => {
      tabState.set(tabId, active)
        .then(() => { resolve(`action resolved. enabled: ${active}`); });
    });
  });
}

function listenerAction(tabId) {
  tabState.get(tabId)
    .then((state) => {
      console.warn('getState.then()');
      console.log(state);

      if (state === undefined) {
        return load(tabId);
      } else if (state === false) {
        return activate(tabId, true);
      } else if (state === true) {
        return activate(tabId, false);
      }
      return Promise.reject(new Error('listenerAction if else didn\'t work'));
    })
    .then((action) => {
      console.log(action);
      console.log('------------------------');
    });
}

function autoAction(tabId) {
  // call fns directly to bypass listenerAction condition checks
  chrome.storage.sync.get(null, (options) => {
    if (options.autoPlay) {
      load(tabId).then(() => activate(tabId, true));
    } else if (options.autoLoad) {
      load(tabId);
    }
  });
}

function addOnUpdated() {
  chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
    // Works only with auto options. Chrome browser utility page check (requires tab permission)
    if (/(chrome)(?:[/:-])/.test(tab.url)) return;

    if (changeInfo.status === 'complete' && tab.active) {
      // no permission, either new tab or tab refresh
      if (tab.url === undefined) {
        tabState.get(tabId)
          .then((state) => {
            console.log('undefined check');
            // state loaded, no permission = page refresh
            if (typeof state === 'boolean') tabState.remove(tabId);
          });
      } else {
        if (/#/.test(tab.url)) {
          console.log('this test is inefficient as it will prevent autoload from working');
        }
        autoAction(tabId); // no permission, just ignore?
      }
    }
  });
}

function removedListener(tabId, info) {
  tabState.get(tabId).then((state) => {
    // act only if state is defined (obtained currentTab permission)
    if (state !== undefined) {
      console.warn('onRemoved IF');
      console.log(state, info);

      // tab is focused and tab gets closed
      tabState.remove(tabId);

      // tab is focused and browser window gets closed
      if (info.insWindowClosing) {
        tabState.clearAll();
      }
    } else {
      console.warn('onRemoved ELSE');
    }
  });
}
function addOnRemoved() {
  chrome.tabs.onRemoved.addListener((tabId, removeInfo) => {
    console.warn('onRemoved');
    removedListener(tabId, removeInfo);
  });
}

function syncDefault() {
  chrome.storage.sync.set({
    lowLimit: 13,
    upLimit: 255,
    autoLoad: false,
    autoPlay: false,
  });
}
function checkOptsUse(cb) {
  chrome.storage.sync.getBytesInUse(null, (bytes) => { if (bytes === 0) cb(); });
}

function onInstalled() {
  chrome.runtime.onInstalled.addListener(() => {
    checkOptsUse(syncDefault); // if not in use, sync default
    createContextMenu();

    // listeners
    chrome.browserAction.onClicked.addListener(tab => listenerAction(tab.id));
    chrome.contextMenus.onClicked.addListener((_, tab) => tabState.getAll());
    addOnUpdated();
    addOnRemoved();
  });
}

onInstalled();
<|endoftext|>


<commit_before>var assert = require('assert')
var crypto = require('crypto')
var os = require('os')
var path = require('path')
var fs = require(process.cwd())

/* global afterEach, beforeEach, describe, it */

var SIZE = 16 * 64 * 1024 + 7

describe('+ copySync()', function () {
  var TEST_DIR

  beforeEach(function (done) {
    TEST_DIR = path.join(os.tmpdir(), 'fs-extra', 'copy-sync')
    fs.emptyDir(TEST_DIR, done)
  })

  afterEach(function (done) {
    fs.remove(TEST_DIR, done)
  })

  describe('> when the source is a file', function () {
    it('should copy the file synchronously', function () {
      var fileSrc = path.join(TEST_DIR, 'TEST_fs-extra_src')
      var fileDest = path.join(TEST_DIR, 'TEST_fs-extra_copy')

      fs.writeFileSync(fileSrc, crypto.randomBytes(SIZE))

      var srcMd5 = crypto.createHash('md5').update(fs.readFileSync(fileSrc)).digest('hex')
      var destMd5 = ''

      fs.copySync(fileSrc, fileDest)

      destMd5 = crypto.createHash('md5').update(fs.readFileSync(fileDest)).digest('hex')
      assert.strictEqual(srcMd5, destMd5)
    })

    it('should follow symlinks', function () {
      var fileSrc = path.join(TEST_DIR, 'TEST_fs-extra_src')
      var fileDest = path.join(TEST_DIR, 'TEST_fs-extra_copy')
      var linkSrc = path.join(TEST_DIR, 'TEST_fs-extra_copy_link')

      fs.writeFileSync(fileSrc, crypto.randomBytes(SIZE))

      var srcMd5 = crypto.createHash('md5').update(fs.readFileSync(fileSrc)).digest('hex')
      var destMd5 = ''

      fs.symlinkSync(fileSrc, linkSrc)
      fs.copySync(linkSrc, fileDest)
      destMd5 = crypto.createHash('md5').update(fs.readFileSync(fileDest)).digest('hex')
      assert.strictEqual(srcMd5, destMd5)
    })

    it('should maintain file mode', function () {
      var fileSrc = path.join(TEST_DIR, 'TEST_fs-extra_src')
      var fileDest = path.join(TEST_DIR, 'TEST_fs-extra_copy')
      fs.writeFileSync(fileSrc, crypto.randomBytes(SIZE))

      fs.chmodSync(fileSrc, parseInt('750', 8))
      fs.copySync(fileSrc, fileDest)

      var statSrc = fs.statSync(fileSrc)
      var statDest = fs.statSync(fileDest)
      assert.strictEqual(statSrc.mode, statDest.mode)
    })

    it('should only copy files allowed by filter regex', function () {
      var srcFile1 = path.join(TEST_DIR, '1.html')
      var srcFile2 = path.join(TEST_DIR, '2.css')
      var srcFile3 = path.join(TEST_DIR, '3.jade')

      fs.writeFileSync(srcFile1, '')
      fs.writeFileSync(srcFile2, '')
      fs.writeFileSync(srcFile3, '')

      var destFile1 = path.join(TEST_DIR, 'dest1.html')
      var destFile2 = path.join(TEST_DIR, 'dest2.css')
      var destFile3 = path.join(TEST_DIR, 'dest3.jade')
      var filter = /.html$|.css$/i

      fs.copySync(srcFile1, destFile1, {filter: filter})
      fs.copySync(srcFile2, destFile2, {filter: filter})
      fs.copySync(srcFile3, destFile3, {filter: filter})

      assert(fs.existsSync(destFile1))
      assert(fs.existsSync(destFile2))
      assert(!fs.existsSync(destFile3))
    })

    it('should only copy files allowed by filter fn', function () {
      var srcFile1 = path.join(TEST_DIR, '1.html')
      var srcFile2 = path.join(TEST_DIR, '2.css')
      var srcFile3 = path.join(TEST_DIR, '3.jade')

      fs.writeFileSync(srcFile1, '')
      fs.writeFileSync(srcFile2, '')
      fs.writeFileSync(srcFile3, '')

      var destFile1 = path.join(TEST_DIR, 'dest1.html')
      var destFile2 = path.join(TEST_DIR, 'dest2.css')
      var destFile3 = path.join(TEST_DIR, 'dest3.jade')

      var filter = function (s) {return s.split('.').pop() !== 'css'}

      fs.copySync(srcFile1, destFile1, filter)
      fs.copySync(srcFile2, destFile2, filter)
      fs.copySync(srcFile3, destFile3, filter)

      assert(fs.existsSync(destFile1))
      assert(!fs.existsSync(destFile2))
      assert(fs.existsSync(destFile3))
    })

    describe('> when the destination dir does not exist', function () {
      it('should create the destination directory and copy the file', function () {
        var src = path.join(TEST_DIR, 'file.txt')
        var dest = path.join(TEST_DIR, 'this/path/does/not/exist/copied.txt')
        var data = 'did it copy?\n'

        fs.writeFileSync(src, data, 'utf8')
        fs.copySync(src, dest)

        var data2 = fs.readFileSync(dest, 'utf8')

        assert.strictEqual(data, data2)
      })
    })

    describe('> when clobber option is passed', function () {
      var src, dest
      var srcData = 'some src data'

      beforeEach(function () {
        src = path.join(TEST_DIR, 'src-file')
        dest = path.join(TEST_DIR, 'des-file')

        // source file must always exist in these cases
        fs.writeFileSync(src, srcData)
      })

      describe('> when destination file does NOT exist', function () {
        describe('> when clobber is true', function () {
          it('should copy the file and not throw an error', function () {
            fs.copySync(src, dest, {clobber: true})
            var destData = fs.readFileSync(dest, 'utf8')
            assert.strictEqual(srcData, destData)
          })
        })

        describe('> when clobber is false', function () {
          it('should copy the file and not throw an error', function () {
            fs.copySync(src, dest, {clobber: false})
            var destData = fs.readFileSync(dest, 'utf8')
            assert.strictEqual(srcData, destData)
          })
        })
      })

      describe('when destination file does exist', function () {
        var destData
        beforeEach(function () {
          destData = 'some dest data'
          fs.writeFileSync(dest, destData)
        })

        describe('> when clobber is true', function () {
          it('should copy the file and not throw an error', function () {
            fs.copySync(src, dest, {clobber: true})
            destData = fs.readFileSync(dest, 'utf8')
            assert.strictEqual(srcData, destData)
          })
        })

        describe('> when clobber is false', function () {
          it('should copy the file and THROW an error', function () {
            assert.throws(function () {
              fs.copySync(src, dest, {clobber: false})
            })

            // copy never happened
            var destDataNew = fs.readFileSync(dest, 'utf8')
            assert.strictEqual(destData, destDataNew)
          })
        })
      })
    })
  })

  describe('> when the source is a directory', function () {
    it('should copy the directory synchronously', function () {
      var FILES = 2
      var src = path.join(TEST_DIR, 'src')
      var dest = path.join(TEST_DIR, 'dest')

      var i, j

      fs.mkdirsSync(src)

      for (i = 0; i < FILES; ++i) {
        fs.writeFileSync(path.join(src, i.toString()), crypto.randomBytes(SIZE))
      }

      var subdir = path.join(src, 'subdir')

      fs.mkdirsSync(subdir)

      for (i = 0; i < FILES; ++i) {
        fs.writeFileSync(path.join(subdir, i.toString()), crypto.randomBytes(SIZE))
      }

      fs.copySync(src, dest)
      assert(fs.existsSync(dest))

      for (i = 0; i < FILES; ++i) {
        assert(fs.existsSync(path.join(dest, i.toString())))
      }

      var destSub = path.join(dest, 'subdir')
      for (j = 0; j < FILES; ++j) {
        assert(fs.existsSync(path.join(destSub, j.toString())))
      }
    })

    it('should preserve symbolic links', function () {
      var src = path.join(TEST_DIR, 'src')
      var dest = path.join(TEST_DIR, 'dest')

      fs.mkdirsSync(src)
      fs.symlinkSync('destination', path.join(src, 'symlink'))

      fs.copySync(src, dest)

      var link = fs.readlinkSync(path.join(dest, 'symlink'))
      assert.strictEqual(link, 'destination')
    })

    it('should should apply filter recursively', function () {
      var FILES = 2
      var src = path.join(TEST_DIR, 'src')
      var dest = path.join(TEST_DIR, 'dest')
      var filter = /0$/i

      fs.mkdirsSync(src)

      for (var i = 0; i < FILES; ++i) {
        fs.writeFileSync(path.join(src, i.toString()), crypto.randomBytes(SIZE))
      }

      var subdir = path.join(src, 'subdir')
      fs.mkdirsSync(subdir)

      for (i = 0; i < FILES; ++i) {
        fs.writeFileSync(path.join(subdir, i.toString()), crypto.randomBytes(SIZE))
      }

      fs.copySync(src, dest, filter)

      assert(fs.existsSync(dest))
      assert(FILES > 1)

      for (i = 0; i < FILES; ++i) {
        if (i === 0) {
          assert(fs.existsSync(path.join(dest, i.toString())))
        } else {
          assert(!fs.existsSync(path.join(dest, i.toString())))
        }
      }

      var destSub = path.join(dest, 'subdir')

      for (var j = 0; j < FILES; ++j) {
        if (j === 0) {
          assert(fs.existsSync(path.join(destSub, j.toString())))
        } else {
          assert(!fs.existsSync(path.join(destSub, j.toString())))
        }
      }
    })

    describe('> when the destination dir does not exist', function () {
      it('should create the destination directory and copy the file', function () {
        var src = path.join(TEST_DIR, 'data/')
        fs.mkdirSync(src)

        var d1 = 'file1'
        var d2 = 'file2'

        fs.writeFileSync(path.join(src, 'f1.txt'), d1)
        fs.writeFileSync(path.join(src, 'f2.txt'), d2)

        var dest = path.join(TEST_DIR, 'this/path/does/not/exist/outputDir')

        fs.copySync(src, dest)

        var o1 = fs.readFileSync(path.join(dest, 'f1.txt'), 'utf8')
        var o2 = fs.readFileSync(path.join(dest, 'f2.txt'), 'utf8')

        assert.strictEqual(d1, o1)
        assert.strictEqual(d2, o2)
      })
    })
  })

  describe('> modification option', function () {
    var SRC_FIXTURES_DIR = path.join(__dirname, '/../fixtures')
    var FILES = ['a-file', path.join('a-folder', 'another-file'), path.join('a-folder', 'another-folder', 'file3')]

    describe('> when modified option is turned off', function () {
      it('should have different timestamps on copy', function (done) {
        var from = path.join(SRC_FIXTURES_DIR)

        fs.copySync(from, TEST_DIR, {preserveTimestamps: false})

        FILES.forEach(testFile({preserveTimestamps: false}))
        done()
      })
    })

    describe('> when modified option is turned on', function () {
      it('should have the same timestamps on copy', function (done) {
        var from = path.join(SRC_FIXTURES_DIR)

        fs.copySync(from, TEST_DIR, {preserveTimestamps: true})

        FILES.forEach(testFile({preserveTimestamps: true}))

        done()
      })
    })

    function testFile (options) {
      return function (file) {
        var a = path.join(SRC_FIXTURES_DIR, file)
        var b = path.join(TEST_DIR, file)
        var fromStat = fs.statSync(a)
        var toStat = fs.statSync(b)
        if (options.preserveTimestamps) {
          assert.strictEqual(toStat.mtime.getTime(), fromStat.mtime.getTime())
          assert.strictEqual(toStat.atime.getTime(), fromStat.atime.getTime())
        } else {
          assert.notEqual(toStat.mtime.getTime(), fromStat.mtime.getTime())
          // the access time might actually be the same, so check only modification time
        }
      }
    }
  })
})
<commit_msg>lib/copy/__tests__/copy-sync.test: moved test fixture ref<commit_after>var assert = require('assert')
var crypto = require('crypto')
var os = require('os')
var path = require('path')
var fs = require(process.cwd())

/* global afterEach, beforeEach, describe, it */

var SIZE = 16 * 64 * 1024 + 7

describe('+ copySync()', function () {
  var TEST_DIR

  beforeEach(function (done) {
    TEST_DIR = path.join(os.tmpdir(), 'fs-extra', 'copy-sync')
    fs.emptyDir(TEST_DIR, done)
  })

  afterEach(function (done) {
    fs.remove(TEST_DIR, done)
  })

  describe('> when the source is a file', function () {
    it('should copy the file synchronously', function () {
      var fileSrc = path.join(TEST_DIR, 'TEST_fs-extra_src')
      var fileDest = path.join(TEST_DIR, 'TEST_fs-extra_copy')

      fs.writeFileSync(fileSrc, crypto.randomBytes(SIZE))

      var srcMd5 = crypto.createHash('md5').update(fs.readFileSync(fileSrc)).digest('hex')
      var destMd5 = ''

      fs.copySync(fileSrc, fileDest)

      destMd5 = crypto.createHash('md5').update(fs.readFileSync(fileDest)).digest('hex')
      assert.strictEqual(srcMd5, destMd5)
    })

    it('should follow symlinks', function () {
      var fileSrc = path.join(TEST_DIR, 'TEST_fs-extra_src')
      var fileDest = path.join(TEST_DIR, 'TEST_fs-extra_copy')
      var linkSrc = path.join(TEST_DIR, 'TEST_fs-extra_copy_link')

      fs.writeFileSync(fileSrc, crypto.randomBytes(SIZE))

      var srcMd5 = crypto.createHash('md5').update(fs.readFileSync(fileSrc)).digest('hex')
      var destMd5 = ''

      fs.symlinkSync(fileSrc, linkSrc)
      fs.copySync(linkSrc, fileDest)
      destMd5 = crypto.createHash('md5').update(fs.readFileSync(fileDest)).digest('hex')
      assert.strictEqual(srcMd5, destMd5)
    })

    it('should maintain file mode', function () {
      var fileSrc = path.join(TEST_DIR, 'TEST_fs-extra_src')
      var fileDest = path.join(TEST_DIR, 'TEST_fs-extra_copy')
      fs.writeFileSync(fileSrc, crypto.randomBytes(SIZE))

      fs.chmodSync(fileSrc, parseInt('750', 8))
      fs.copySync(fileSrc, fileDest)

      var statSrc = fs.statSync(fileSrc)
      var statDest = fs.statSync(fileDest)
      assert.strictEqual(statSrc.mode, statDest.mode)
    })

    it('should only copy files allowed by filter regex', function () {
      var srcFile1 = path.join(TEST_DIR, '1.html')
      var srcFile2 = path.join(TEST_DIR, '2.css')
      var srcFile3 = path.join(TEST_DIR, '3.jade')

      fs.writeFileSync(srcFile1, '')
      fs.writeFileSync(srcFile2, '')
      fs.writeFileSync(srcFile3, '')

      var destFile1 = path.join(TEST_DIR, 'dest1.html')
      var destFile2 = path.join(TEST_DIR, 'dest2.css')
      var destFile3 = path.join(TEST_DIR, 'dest3.jade')
      var filter = /.html$|.css$/i

      fs.copySync(srcFile1, destFile1, {filter: filter})
      fs.copySync(srcFile2, destFile2, {filter: filter})
      fs.copySync(srcFile3, destFile3, {filter: filter})

      assert(fs.existsSync(destFile1))
      assert(fs.existsSync(destFile2))
      assert(!fs.existsSync(destFile3))
    })

    it('should only copy files allowed by filter fn', function () {
      var srcFile1 = path.join(TEST_DIR, '1.html')
      var srcFile2 = path.join(TEST_DIR, '2.css')
      var srcFile3 = path.join(TEST_DIR, '3.jade')

      fs.writeFileSync(srcFile1, '')
      fs.writeFileSync(srcFile2, '')
      fs.writeFileSync(srcFile3, '')

      var destFile1 = path.join(TEST_DIR, 'dest1.html')
      var destFile2 = path.join(TEST_DIR, 'dest2.css')
      var destFile3 = path.join(TEST_DIR, 'dest3.jade')

      var filter = function (s) {return s.split('.').pop() !== 'css'}

      fs.copySync(srcFile1, destFile1, filter)
      fs.copySync(srcFile2, destFile2, filter)
      fs.copySync(srcFile3, destFile3, filter)

      assert(fs.existsSync(destFile1))
      assert(!fs.existsSync(destFile2))
      assert(fs.existsSync(destFile3))
    })

    describe('> when the destination dir does not exist', function () {
      it('should create the destination directory and copy the file', function () {
        var src = path.join(TEST_DIR, 'file.txt')
        var dest = path.join(TEST_DIR, 'this/path/does/not/exist/copied.txt')
        var data = 'did it copy?\n'

        fs.writeFileSync(src, data, 'utf8')
        fs.copySync(src, dest)

        var data2 = fs.readFileSync(dest, 'utf8')

        assert.strictEqual(data, data2)
      })
    })

    describe('> when clobber option is passed', function () {
      var src, dest
      var srcData = 'some src data'

      beforeEach(function () {
        src = path.join(TEST_DIR, 'src-file')
        dest = path.join(TEST_DIR, 'des-file')

        // source file must always exist in these cases
        fs.writeFileSync(src, srcData)
      })

      describe('> when destination file does NOT exist', function () {
        describe('> when clobber is true', function () {
          it('should copy the file and not throw an error', function () {
            fs.copySync(src, dest, {clobber: true})
            var destData = fs.readFileSync(dest, 'utf8')
            assert.strictEqual(srcData, destData)
          })
        })

        describe('> when clobber is false', function () {
          it('should copy the file and not throw an error', function () {
            fs.copySync(src, dest, {clobber: false})
            var destData = fs.readFileSync(dest, 'utf8')
            assert.strictEqual(srcData, destData)
          })
        })
      })

      describe('when destination file does exist', function () {
        var destData
        beforeEach(function () {
          destData = 'some dest data'
          fs.writeFileSync(dest, destData)
        })

        describe('> when clobber is true', function () {
          it('should copy the file and not throw an error', function () {
            fs.copySync(src, dest, {clobber: true})
            destData = fs.readFileSync(dest, 'utf8')
            assert.strictEqual(srcData, destData)
          })
        })

        describe('> when clobber is false', function () {
          it('should copy the file and THROW an error', function () {
            assert.throws(function () {
              fs.copySync(src, dest, {clobber: false})
            })

            // copy never happened
            var destDataNew = fs.readFileSync(dest, 'utf8')
            assert.strictEqual(destData, destDataNew)
          })
        })
      })
    })
  })

  describe('> when the source is a directory', function () {
    it('should copy the directory synchronously', function () {
      var FILES = 2
      var src = path.join(TEST_DIR, 'src')
      var dest = path.join(TEST_DIR, 'dest')

      var i, j

      fs.mkdirsSync(src)

      for (i = 0; i < FILES; ++i) {
        fs.writeFileSync(path.join(src, i.toString()), crypto.randomBytes(SIZE))
      }

      var subdir = path.join(src, 'subdir')

      fs.mkdirsSync(subdir)

      for (i = 0; i < FILES; ++i) {
        fs.writeFileSync(path.join(subdir, i.toString()), crypto.randomBytes(SIZE))
      }

      fs.copySync(src, dest)
      assert(fs.existsSync(dest))

      for (i = 0; i < FILES; ++i) {
        assert(fs.existsSync(path.join(dest, i.toString())))
      }

      var destSub = path.join(dest, 'subdir')
      for (j = 0; j < FILES; ++j) {
        assert(fs.existsSync(path.join(destSub, j.toString())))
      }
    })

    it('should preserve symbolic links', function () {
      var src = path.join(TEST_DIR, 'src')
      var dest = path.join(TEST_DIR, 'dest')

      fs.mkdirsSync(src)
      fs.symlinkSync('destination', path.join(src, 'symlink'))

      fs.copySync(src, dest)

      var link = fs.readlinkSync(path.join(dest, 'symlink'))
      assert.strictEqual(link, 'destination')
    })

    it('should should apply filter recursively', function () {
      var FILES = 2
      var src = path.join(TEST_DIR, 'src')
      var dest = path.join(TEST_DIR, 'dest')
      var filter = /0$/i

      fs.mkdirsSync(src)

      for (var i = 0; i < FILES; ++i) {
        fs.writeFileSync(path.join(src, i.toString()), crypto.randomBytes(SIZE))
      }

      var subdir = path.join(src, 'subdir')
      fs.mkdirsSync(subdir)

      for (i = 0; i < FILES; ++i) {
        fs.writeFileSync(path.join(subdir, i.toString()), crypto.randomBytes(SIZE))
      }

      fs.copySync(src, dest, filter)

      assert(fs.existsSync(dest))
      assert(FILES > 1)

      for (i = 0; i < FILES; ++i) {
        if (i === 0) {
          assert(fs.existsSync(path.join(dest, i.toString())))
        } else {
          assert(!fs.existsSync(path.join(dest, i.toString())))
        }
      }

      var destSub = path.join(dest, 'subdir')

      for (var j = 0; j < FILES; ++j) {
        if (j === 0) {
          assert(fs.existsSync(path.join(destSub, j.toString())))
        } else {
          assert(!fs.existsSync(path.join(destSub, j.toString())))
        }
      }
    })

    describe('> when the destination dir does not exist', function () {
      it('should create the destination directory and copy the file', function () {
        var src = path.join(TEST_DIR, 'data/')
        fs.mkdirSync(src)

        var d1 = 'file1'
        var d2 = 'file2'

        fs.writeFileSync(path.join(src, 'f1.txt'), d1)
        fs.writeFileSync(path.join(src, 'f2.txt'), d2)

        var dest = path.join(TEST_DIR, 'this/path/does/not/exist/outputDir')

        fs.copySync(src, dest)

        var o1 = fs.readFileSync(path.join(dest, 'f1.txt'), 'utf8')
        var o2 = fs.readFileSync(path.join(dest, 'f2.txt'), 'utf8')

        assert.strictEqual(d1, o1)
        assert.strictEqual(d2, o2)
      })
    })
  })

  describe('> modification option', function () {
    var SRC_FIXTURES_DIR = path.join(__dirname, './fixtures')
    var FILES = ['a-file', path.join('a-folder', 'another-file'), path.join('a-folder', 'another-folder', 'file3')]

    describe('> when modified option is turned off', function () {
      it('should have different timestamps on copy', function (done) {
        var from = path.join(SRC_FIXTURES_DIR)

        fs.copySync(from, TEST_DIR, {preserveTimestamps: false})

        FILES.forEach(testFile({preserveTimestamps: false}))
        done()
      })
    })

    describe('> when modified option is turned on', function () {
      it('should have the same timestamps on copy', function (done) {
        var from = path.join(SRC_FIXTURES_DIR)

        fs.copySync(from, TEST_DIR, {preserveTimestamps: true})

        FILES.forEach(testFile({preserveTimestamps: true}))

        done()
      })
    })

    function testFile (options) {
      return function (file) {
        var a = path.join(SRC_FIXTURES_DIR, file)
        var b = path.join(TEST_DIR, file)
        var fromStat = fs.statSync(a)
        var toStat = fs.statSync(b)
        if (options.preserveTimestamps) {
          assert.strictEqual(toStat.mtime.getTime(), fromStat.mtime.getTime())
          assert.strictEqual(toStat.atime.getTime(), fromStat.atime.getTime())
        } else {
          assert.notEqual(toStat.mtime.getTime(), fromStat.mtime.getTime())
          // the access time might actually be the same, so check only modification time
        }
      }
    }
  })
})
<|endoftext|>


<commit_before>process.on('uncaughtException', function(e){
  process.send({error: e.stack});
});

const constants = require('../../constants');
const Events = require('./eventsWrapper');

class ProcessWrapper {

  /**
   * Class from which process extend. Should not be instantiated alone.
   * Manages the log interception so that all console.* get sent back to the parent process
   * Also creates an Events instance. To use it, just do `this.events.[on|request]`
   *
   * @param {Options}     options    pingParent: true by default
   */
  constructor(argOptions = {}) {
    const defaultOptions = {pingParent: true}
    const options = {...defaultOptions, ...argOptions};
    this.interceptLogs();
    this.events = new Events();
    if(options.pingParent) {
      this.pingParent();
    }
  }

  // Ping parent to see if it is still alive. Otherwise, let's die
  pingParent() {
    const self = this;
    self.retries = 0;
    function error() {
      if (self.retries > 2) {
          self.kill();
          process.exit();
      }
      self.retries++;
    }
    setInterval(() => {
      try {
        let result = self.send({action: 'ping'});
        if (!result) {
          return error();
        }
        self.retries = 0;
      } catch (e) {
        error();
      }
    }, 500);
  }

  interceptLogs() {
    const context = {};
    context.console = console;

    context.console.log = this._log.bind(this, 'log');
    context.console.warn = this._log.bind(this, 'warn');
    context.console.error = this._log.bind(this, 'error');
    context.console.info = this._log.bind(this, 'info');
    context.console.debug = this._log.bind(this, 'debug');
    context.console.trace = this._log.bind(this, 'trace');
    context.console.dir = this._log.bind(this, 'dir');
  }

  _log(type, ...messages) {
    const isHardSource = messages.some(message => {
      return (typeof message === 'string' && message.indexOf('hardsource') > -1);
    });
    if (isHardSource) {
      return;
    }
    this.send({result: constants.process.log, message: messages, type});
  }

  send() {
    if (!process.connected) {
      return false;
    }
    return process.send(...arguments);
  }

  kill() {
    // Should be implemented by derived class
    console.log('Process killed');
  }
}

process.on('exit', () => {
  process.exit(0);
});

module.exports = ProcessWrapper;
<commit_msg>please linter<commit_after>process.on('uncaughtException', function(e){
  process.send({error: e.stack});
});

const constants = require('../../constants');
const Events = require('./eventsWrapper');

class ProcessWrapper {

  /**
   * Class from which process extend. Should not be instantiated alone.
   * Manages the log interception so that all console.* get sent back to the parent process
   * Also creates an Events instance. To use it, just do `this.events.[on|request]`
   *
   * @param {Options}     options    pingParent: true by default
   */
  constructor(options = {}) {
    this.options = Object.assign({pingParent: true}, options);
    this.interceptLogs();
    this.events = new Events();
    if(this.options.pingParent) {
      this.pingParent();
    }
  }

  // Ping parent to see if it is still alive. Otherwise, let's die
  pingParent() {
    const self = this;
    self.retries = 0;
    function error() {
      if (self.retries > 2) {
          self.kill();
          process.exit();
      }
      self.retries++;
    }
    setInterval(() => {
      try {
        let result = self.send({action: 'ping'});
        if (!result) {
          return error();
        }
        self.retries = 0;
      } catch (e) {
        error();
      }
    }, 500);
  }

  interceptLogs() {
    const context = {};
    context.console = console;

    context.console.log = this._log.bind(this, 'log');
    context.console.warn = this._log.bind(this, 'warn');
    context.console.error = this._log.bind(this, 'error');
    context.console.info = this._log.bind(this, 'info');
    context.console.debug = this._log.bind(this, 'debug');
    context.console.trace = this._log.bind(this, 'trace');
    context.console.dir = this._log.bind(this, 'dir');
  }

  _log(type, ...messages) {
    const isHardSource = messages.some(message => {
      return (typeof message === 'string' && message.indexOf('hardsource') > -1);
    });
    if (isHardSource) {
      return;
    }
    this.send({result: constants.process.log, message: messages, type});
  }

  send() {
    if (!process.connected) {
      return false;
    }
    return process.send(...arguments);
  }

  kill() {
    // Should be implemented by derived class
    console.log('Process killed');
  }
}

process.on('exit', () => {
  process.exit(0);
});

module.exports = ProcessWrapper;
<|endoftext|>


<commit_before>lingcod.Manipulator = function(gex, form, render_target, div){

    this.altitude = 100;
    var json = false;
    var data = form.find('.json').html();
    if(data){
        json = JSON.parse(data);
    }
    this.needed = true;
    // Return false if manipulations are not needed, else proceed.
    if(!json || !json.manipulators){
        this.needed = false;
        return false;
    }
    this.div = div;
    this.shape_;
    this.manipulators_ = json.manipulators;
    this.gex_ = gex;
    this.form_ = form;
    this.render_target_ = render_target;

    // Fill in the form with content from map.html
    this.render_target_.html($('#geopanel').html());

    var self = this;

    // Setup event listeners
    this.render_target_.find('.draw_shape').click(function(){
        if(!$(this).hasClass('disabled')){
            $(this).addClass('disabled');
            self.drawNewShape_();
        }
    });

    this.render_target_.find('div.manipulated .edit_shape').click(function(){
        if(!$(this).hasClass('disabled')){
            $(this).addClass('disabled');
            self.editExistingShape_();
        }
    });

    this.render_target_.find('.done_editing').click(function(){
        self.render_target_.find('.done_editing').addClass('disabled');
        self.finishedEditingCallback_();
    });

    this.render_target_.find('div.edit .edit_shape').click(function(){
        if(!$(this).hasClass('disabled')){
            $(this).addClass('disabled');
            self.editExistingShape_();
        }
    });

    // Figure out if there is an existing shape in the form, or if a new one
    // needs to be drawn
    if(this.form_.find('#id_geometry_orig').val()){
        this.enterExistingShapeState_();
    }else{
        this.enterNewState_();
    }
}

lingcod.Manipulator.prototype.drawNewShape_ = function(){
    this.is_defining_shape_ = true;
    this.is_defining_new_shape_ = true;
    this.addNewShape_();
    var bounds = this.shape_.getGeometry().getOuterBoundary();
    var self = this;
    this.gex_.edit.drawLineString(bounds, {
        bounce: false,
        finishCallback: function(){
            self.finishedEditingCallback_();
        },
        drawCallback: function(i){
            var coords = bounds.getCoordinates();
            var coord = coords.get(i);
            coord.setAltitude(self.altitude);
            coords.set(i, coord);
        },
        ensureCounterClockwise: false
    });
}

lingcod.Manipulator.prototype.addNewShape_ = function(kml){
    this.clearShape_();
    if(kml){
        this.shape_ = this.gex_.pluginInstance.parseKml(kml);
        this.gex_.pluginInstance.getFeatures().appendChild(this.shape_);
    }else{
        this.shape_ = this.gex_.dom.addPlacemark({
            visibility: true,
            polygon: [],
            style: {
                line: { width: 2, color: 'ffffffff' },
                poly: { color: '8000ff00' }
            }
        });
        this.setZ(this.shape_, this.altitude);
    }
    return this.shape_;
}

lingcod.Manipulator.prototype.setZ = function(kmlObject, z){
    var geo = kmlObject.getGeometry();
    geo.setAltitudeMode(ge.ALTITUDE_ABSOLUTE);
    geo.setExtrude(true);
    var coords = geo.getOuterBoundary().getCoordinates();
    var length = coords.getLength();
    for(var i =0; i<length;i++){
        var coord = coords.get(i)
        coord.setAltitude(z);
        coords.set(i, coord);
    }
    return kmlObject;
}

lingcod.Manipulator.prototype.finishedEditingCallback_ = function(){
    var self = this;
    this.process(this.shape_.getKml(), this.manipulators_, function(data){
        if(data.success === '1'){
            var kmlObject = self.addNewShape_(data.final_shape_kml);
            self.gex_.util.flyToObject(kmlObject, {
                boundsFallback: true, aspectRatio: $(this.div).width() / $(this.div).height()});
            self.setGeometryFields_(data.user_shape, data.submitted, data.final_shape, data.final_shape_kml);
            self.enterManipulatedState_(data.html, true);
        }else{
            self.setGeometryFields_('', data.submitted, '', '');
            self.addNewShape_(data.submitted);
            self.gex_.util.flyToObject(self.shape_, {
                boundsFallback: true, aspectRatio: $(this.div).width() / $(this.div).height()});
            self.enterManipulatedState_(data.html, false);
        }
    });
}

lingcod.Manipulator.prototype.setGeometryFields_ = function(original_wkt, original_kml, final_wkt, final_kml){
    this.form_.find('#id_geometry_orig').val(original_wkt);
    $('#geometry_final_kml').text(final_kml);
    $('#geometry_orig_kml').text(original_kml);
}

lingcod.Manipulator.prototype.hideStates_ = function(){
    this.render_target_.find('div.new, div.edit, div.manipulated, div.editing').hide();
}

lingcod.Manipulator.prototype.enterManipulatedState_ = function(html, success){
    this.hideStates_();
    if(success === true){
        this.render_target_.find('div.manipulated').removeClass('error');
        this.is_invalid_geometry = false;
        this.is_defining_shape_ = false;
        this.is_defining_new_shape_ = false;
    }else{
        this.is_invalid_geometry = true;
        this.render_target_.find('div.manipulated').addClass('error');
    }
    this.render_target_.find('div.manipulated a.edit_shape').removeClass('disabled');
    this.render_target_.find('div.manipulated').show().find('>p')
        .html(html);
}

lingcod.Manipulator.prototype.isInvalidGeometry = function(){
    return this.is_invalid_geometry;
}

lingcod.Manipulator.prototype.enterNewState_ = function(){
    this.hideStates_();
    // this.is_defining_shape_ = true;
    this.render_target_.find('div.new').show();
    this.render_target_.find('a.draw_shape').removeClass('disabled');
}

lingcod.Manipulator.prototype.isDefiningNewShape = function(){
    return this.is_defining_new_shape_;
}

lingcod.Manipulator.prototype.enterEditingState_ = function(){
    this.hideStates_();
    this.is_invalid_geometry = false;
    this.is_defining_shape_ = true;
    this.is_defining_new_shape_ = false;
    this.render_target_.find('.done_editing').removeClass('disabled');
    this.render_target_.find('div.editing').show();
}

lingcod.Manipulator.prototype.enterExistingShapeState_ = function(){
    this.hideStates_();
    this.is_defining_shape = false;
    this.render_target_.find('div.edit .edit_shape').removeClass('disabled');
    this.render_target_.find('div.edit').show();
    var kml = jQuery.trim($('#geometry_final_kml').text());
    if(!kml){
        var kml = jQuery.trim($('#geometry_orig_kml').text());
    }
    this.addNewShape_(kml);
    this.gex_.util.flyToObject(this.shape_, {
        boundsFallback: true, aspectRatio: $(this.div).width() / $(this.div).height()});
    var self = this;
    this.process(kml, this.manipulators_, function(data){
        if(data.success === '1'){
            var kmlObject = self.addNewShape_(data.final_shape_kml);
            self.gex_.util.flyToObject(kmlObject, {
                boundsFallback: true, aspectRatio: $(this.div).width() / $(this.div).height()});
        }else{
            // do nothing
        }
    });
}

lingcod.Manipulator.prototype.isShapeDefined = function(){
    return !!this.form_.find('#id_geometry_orig').val();
}

lingcod.Manipulator.prototype.isDefiningShape = function(){
    return this.is_defining_shape_;
}

lingcod.Manipulator.prototype.process = function(wkt, url, callback){
    $.ajax({
        url: url,
        type: 'POST',
        data: { target_shape: wkt },
        success: function(data, status){
            if(status === 'success'){
                callback(JSON.parse(data));
            }else{
                $(this).trigger('error', "There was an error processing your shape.");
                callback({success: false, html: $('#manipulators_server_error')});
            }
        },
        error: function(data, status){
            $(this).trigger('error', 'There was an error processing your shape.');
            callback({success: false, html: $('#manipulators_server_error').html()});
        }
    });
}

lingcod.Manipulator.prototype.editExistingShape_ = function(){
    var kml = jQuery.trim($('#geometry_orig_kml').text());
    this.addNewShape_(kml);
    this.gex_.util.flyToObject(this.shape_, {
        boundsFallback: true, aspectRatio: $(this.div).width() / $(this.div).height()});
    this.gex_.edit.editLineString(this.shape_.getGeometry().getOuterBoundary());
    this.enterEditingState_();

}

lingcod.Manipulator.prototype.clearShape_ = function(){
    if(this.shape_ && this.shape_.getParentNode()){
        this.gex_.edit.endEditLineString(this.shape_.getGeometry().getOuterBoundary());
        gex.dom.removeObject(this.shape_);
        this.shape_ = false;
    }
}

lingcod.Manipulator.prototype.destroy = function(){
    this.clearShape_();
}<commit_msg>manipulators process() method would go into an infinite loop when responding to a server error. Fixed.<commit_after>lingcod.Manipulator = function(gex, form, render_target, div){

    this.altitude = 100;
    var json = false;
    var data = form.find('.json').html();
    if(data){
        json = JSON.parse(data);
    }
    this.needed = true;
    // Return false if manipulations are not needed, else proceed.
    if(!json || !json.manipulators){
        this.needed = false;
        return false;
    }
    this.div = div;
    this.shape_;
    this.manipulators_ = json.manipulators;
    this.gex_ = gex;
    this.form_ = form;
    this.render_target_ = render_target;

    // Fill in the form with content from map.html
    this.render_target_.html($('#geopanel').html());

    var self = this;

    // Setup event listeners
    this.render_target_.find('.draw_shape').click(function(){
        if(!$(this).hasClass('disabled')){
            $(this).addClass('disabled');
            self.drawNewShape_();
        }
    });

    this.render_target_.find('div.manipulated .edit_shape').click(function(){
        if(!$(this).hasClass('disabled')){
            $(this).addClass('disabled');
            self.editExistingShape_();
        }
    });

    this.render_target_.find('.done_editing').click(function(){
        self.render_target_.find('.done_editing').addClass('disabled');
        self.finishedEditingCallback_();
    });

    this.render_target_.find('div.edit .edit_shape').click(function(){
        if(!$(this).hasClass('disabled')){
            $(this).addClass('disabled');
            self.editExistingShape_();
        }
    });

    // Figure out if there is an existing shape in the form, or if a new one
    // needs to be drawn
    if(this.form_.find('#id_geometry_orig').val()){
        this.enterExistingShapeState_();
    }else{
        this.enterNewState_();
    }
}

lingcod.Manipulator.prototype.drawNewShape_ = function(){
    this.is_defining_shape_ = true;
    this.is_defining_new_shape_ = true;
    this.addNewShape_();
    var bounds = this.shape_.getGeometry().getOuterBoundary();
    var self = this;
    this.gex_.edit.drawLineString(bounds, {
        bounce: false,
        finishCallback: function(){
            self.finishedEditingCallback_();
        },
        drawCallback: function(i){
            var coords = bounds.getCoordinates();
            var coord = coords.get(i);
            coord.setAltitude(self.altitude);
            coords.set(i, coord);
        },
        ensureCounterClockwise: false
    });
}

lingcod.Manipulator.prototype.addNewShape_ = function(kml){
    this.clearShape_();
    if(kml){
        this.shape_ = this.gex_.pluginInstance.parseKml(kml);
        this.gex_.pluginInstance.getFeatures().appendChild(this.shape_);
    }else{
        this.shape_ = this.gex_.dom.addPlacemark({
            visibility: true,
            polygon: [],
            style: {
                line: { width: 2, color: 'ffffffff' },
                poly: { color: '8000ff00' }
            }
        });
        this.setZ(this.shape_, this.altitude);
    }
    return this.shape_;
}

lingcod.Manipulator.prototype.setZ = function(kmlObject, z){
    var geo = kmlObject.getGeometry();
    geo.setAltitudeMode(ge.ALTITUDE_ABSOLUTE);
    geo.setExtrude(true);
    var coords = geo.getOuterBoundary().getCoordinates();
    var length = coords.getLength();
    for(var i =0; i<length;i++){
        var coord = coords.get(i)
        coord.setAltitude(z);
        coords.set(i, coord);
    }
    return kmlObject;
}

lingcod.Manipulator.prototype.finishedEditingCallback_ = function(){
    var self = this;
    this.process(this.shape_.getKml(), this.manipulators_, function(data){
        if(data.success === '1'){
            var kmlObject = self.addNewShape_(data.final_shape_kml);
            self.gex_.util.flyToObject(kmlObject, {
                boundsFallback: true, aspectRatio: $(this.div).width() / $(this.div).height()});
            self.setGeometryFields_(data.user_shape, data.submitted, data.final_shape, data.final_shape_kml);
            self.enterManipulatedState_(data.html, true);
        }else{
			console.log('error!!!');
            self.setGeometryFields_('', data.submitted, '', '');
            self.addNewShape_(data.submitted);
            self.gex_.util.flyToObject(self.shape_, {
                boundsFallback: true, aspectRatio: $(this.div).width() / $(this.div).height()});
            self.enterManipulatedState_(data.html, false);
        }
    });
}

lingcod.Manipulator.prototype.setGeometryFields_ = function(original_wkt, original_kml, final_wkt, final_kml){
    this.form_.find('#id_geometry_orig').val(original_wkt);
    $('#geometry_final_kml').text(final_kml);
    $('#geometry_orig_kml').text(original_kml);
}

lingcod.Manipulator.prototype.hideStates_ = function(){
    this.render_target_.find('div.new, div.edit, div.manipulated, div.editing').hide();
}

lingcod.Manipulator.prototype.enterManipulatedState_ = function(html, success){
    this.hideStates_();
    if(success === true){
        this.render_target_.find('div.manipulated').removeClass('error');
        this.is_invalid_geometry = false;
        this.is_defining_shape_ = false;
        this.is_defining_new_shape_ = false;
    }else{
        this.is_invalid_geometry = true;
        this.render_target_.find('div.manipulated').addClass('error');
    }
    this.render_target_.find('div.manipulated a.edit_shape').removeClass('disabled');
    this.render_target_.find('div.manipulated').show().find('>p')
        .html(html);
}

lingcod.Manipulator.prototype.isInvalidGeometry = function(){
    return this.is_invalid_geometry;
}

lingcod.Manipulator.prototype.enterNewState_ = function(){
    this.hideStates_();
    // this.is_defining_shape_ = true;
    this.render_target_.find('div.new').show();
    this.render_target_.find('a.draw_shape').removeClass('disabled');
}

lingcod.Manipulator.prototype.isDefiningNewShape = function(){
    return this.is_defining_new_shape_;
}

lingcod.Manipulator.prototype.enterEditingState_ = function(){
    this.hideStates_();
    this.is_invalid_geometry = false;
    this.is_defining_shape_ = true;
    this.is_defining_new_shape_ = false;
    this.render_target_.find('.done_editing').removeClass('disabled');
    this.render_target_.find('div.editing').show();
}

lingcod.Manipulator.prototype.enterExistingShapeState_ = function(){
    this.hideStates_();
    this.is_defining_shape = false;
    this.render_target_.find('div.edit .edit_shape').removeClass('disabled');
    this.render_target_.find('div.edit').show();
    var kml = jQuery.trim($('#geometry_final_kml').text());
    if(!kml){
        var kml = jQuery.trim($('#geometry_orig_kml').text());
    }
    this.addNewShape_(kml);
    this.gex_.util.flyToObject(this.shape_, {
        boundsFallback: true, aspectRatio: $(this.div).width() / $(this.div).height()});
    var self = this;
    this.process(kml, this.manipulators_, function(data){
        if(data.success === '1'){
            var kmlObject = self.addNewShape_(data.final_shape_kml);
            self.gex_.util.flyToObject(kmlObject, {
                boundsFallback: true, aspectRatio: $(this.div).width() / $(this.div).height()});
        }else{
            // do nothing
        }
    });
}

lingcod.Manipulator.prototype.isShapeDefined = function(){
    return !!this.form_.find('#id_geometry_orig').val();
}

lingcod.Manipulator.prototype.isDefiningShape = function(){
    return this.is_defining_shape_;
}

lingcod.Manipulator.prototype.process = function(wkt, url, callback){
	var self = this;
    $.ajax({
        url: url,
        type: 'POST',
        data: { target_shape: wkt },
        success: function(data, status){
            if(status === 'success'){
                callback(JSON.parse(data));
            }else{
                $(self).trigger('error', "There was an error processing your shape.");
                callback({success: false, html: $('#manipulators_server_error')});
            }
        },
        error: function(data, status){
            $(self).trigger('error', 'There was an error processing your shape.');
            callback({success: false, html: $('#manipulators_server_error').html()});
        }
    });
}

lingcod.Manipulator.prototype.editExistingShape_ = function(){
    var kml = jQuery.trim($('#geometry_orig_kml').text());
    this.addNewShape_(kml);
    this.gex_.util.flyToObject(this.shape_, {
        boundsFallback: true, aspectRatio: $(this.div).width() / $(this.div).height()});
    this.gex_.edit.editLineString(this.shape_.getGeometry().getOuterBoundary());
    this.enterEditingState_();

}

lingcod.Manipulator.prototype.clearShape_ = function(){
    if(this.shape_ && this.shape_.getParentNode()){
        this.gex_.edit.endEditLineString(this.shape_.getGeometry().getOuterBoundary());
        gex.dom.removeObject(this.shape_);
        this.shape_ = false;
    }
}

lingcod.Manipulator.prototype.destroy = function(){
    this.clearShape_();
}<|endoftext|>


<commit_before>if (typeof jQuery === 'undefined') { throw new Error('Starscream JavaScript requires jQuery') }

   var j$ = jQuery.noConflict();

j$(document).ready(function () {
    // style all buttons
    j$('button').addClass("btn btn-default");
    //style all form controls
    j$('input').addClass("form-control");
    // try to style the select lists
    j$('select').addClass("dropdown-toggle");
    //try text areas
    j$('textarea').addClass("form-control");

    //redo the detail table into an unordered list
    j$('div.pbSubsection table').each(function () {
        var list = j$("
").addClass("list-group");

        j$(this).find("tr").each(function () {
            var p = j$(this).children().map(function () {
                if (j$(this).find('table').length > 0) {
                    var subList = j$("
").addClass("list-group");
                    subList.attr("id", j$(this).find('table').attr("id")) // assign the id from the table
                    // remove the flow ".empty" table cells
                    j$(".empty").remove();
                    j$("td:empty").remove();

                    var sP = j$(this).find('table').children().map(function () {
                        var tmpPara = "
" + j$(this).html().trim() + "
";
                        tmpPara.addClass(this.attr("class"));

                        if (tmpPara.trim() ===  "

"){
                            tmpPara = "";
                        }
                        return tmpPara;
                    });

                    subList.append("
" + j$.makeArray(sP).join("") + "
");

                    return j$('
').append(j$('
').append(subList)).html();
                }
                else {
                    return "
" + j$(this).html().trim() + "
";
                }
            });

            list.append("
" + j$.makeArray(p).join("") + "
");
        });
        // remove empty paragraphs
        list.find('p:empty').remove();

        j$(this).replaceWith(list);
    });
});<commit_msg>One more time on removing blank paragraphs<commit_after>if (typeof jQuery === 'undefined') { throw new Error('Starscream JavaScript requires jQuery') }

   var j$ = jQuery.noConflict();

j$(document).ready(function () {
    // style all buttons
    j$('button').addClass("btn btn-default");
    //style all form controls
    j$('input').addClass("form-control");
    // try to style the select lists
    j$('select').addClass("dropdown-toggle");
    //try text areas
    j$('textarea').addClass("form-control");

    //redo the detail table into an unordered list
    j$('div.pbSubsection table').each(function () {
        var list = j$("
").addClass("list-group");

        j$(this).find("tr").each(function () {
            var p = j$(this).children().map(function () {
                if (j$(this).find('table').length > 0) {
                    var subList = j$("
").addClass("list-group");
                    subList.attr("id", j$(this).find('table').attr("id")) // assign the id from the table
                    // remove the flow ".empty" table cells
                    j$(".empty").remove();
                    j$("td:empty").remove();

                    var sP = j$(this).find('table').children().map(function () {
                        var tmpPara = "
" + j$(this).html().trim() + "
";
                        tmpPara.addClass(this.attr("class"));

                        if (tmpPara.trim() ===  "

"){
                            tmpPara = "";
                        }
                        return tmpPara;
                    });

                    subList.append("
" + j$.makeArray(sP).join("") + "
");

                    return j$('
').append(j$('
').append(subList)).html();
                }
                else {
                    return "
" + j$(this).html().trim() + "
";
                }
            });

            list.append("
" + j$.makeArray(p).join("") + "
");
        });
        // remove empty paragraphs
        list.find('p:empty').remove();
        list.$('p').each(function(index, item) {
            if($.trim($(item).text()) === "") {
                $(item).slideUp(); // $(item).remove();
            }
        });

        j$(this).replaceWith(list);
    });
});<|endoftext|>


<commit_before>window.onload = function () {

    var buttons = document.getElementsByClassName('btn');
    for (var i=0; i<buttons.length; i++) {
        addEventListenerToSection(buttons, i);
    }
}

function hideSections () {
    document.getElementById('section-0').style.display = "none";

    var sections = document.getElementsByClassName("hidden-section");

    for (var i=0; i<sections.length; i++) {
        sections[i].style.display = "none";
    }
}

function addEventListenerToSection (buttons, i) {
    buttons[i].addEventListener('click', function (event) {
        event.preventDefault();
        hideSections(); // To hide previously displayed section
        document.getElementById('section-'+i).style.display = "block";
    }, false);
}<commit_msg>Removed redundant JS<commit_after>var onDisplay = document.getElementById('section-0');

window.onload = function () {

    var buttons = document.getElementsByClassName('btn');
    for (var i=0; i<buttons.length; i++) {
        addEventListenerToSection(buttons, i);
    }
}

function addEventListenerToSection (buttons, i) {
    buttons[i].addEventListener('click', function (event) {
        event.preventDefault();
        onDisplay.style.display = 'none';
        document.getElementById('section-'+i).style.display = "block";
        onDisplay = document.getElementById('section-'+i);
    }, false);
}<|endoftext|>