<commit_before>import { timeCode } from './time-code';

/**
 * Various helpers for dealing with the profile as a data structure.
 */

export const resourceTypes = {
  unknown: 0,
  library: 1,
  addon: 2,
  webhost: 3,
  otherhost: 4,
  url: 5
};

/**
 * Takes the stack table and the frame table, creates a func stack table and
 * fixes up the funcStack field in the samples data.
 * @return object  The funcStackTable and the new samples object.
 */
export function getFuncStackInfo(stackTable, frameTable, funcTable, samples) {
return timeCode('getFuncStackInfo', () => {
  let stackIndexToFuncStackIndex = new Map();
  const funcCount = funcTable.length;
  let prefixFuncStackAndFuncToFuncStackMap = new Map(); // prefixFuncStack * funcCount + func => funcStack
  let funcStackTable = { length: 0, prefix: [], func: [], depth: [] };
  function addFuncStack(prefix, func) {
    const index = funcStackTable.length++;
    funcStackTable.prefix[index] = prefix;
    funcStackTable.func[index] = func;
    if (prefix === -1) {
      funcStackTable.depth[index] = 0;
    } else {
      funcStackTable.depth[index] = funcStackTable.depth[prefix] + 1;
    }
  }
  for (let stackIndex = 0; stackIndex < stackTable.length; stackIndex++) {
    const prefixStack = stackTable.prefix[stackIndex];
    const prefixFuncStack = (prefixStack === null) ? -1 :
       stackIndexToFuncStackIndex.get(prefixStack);
    const frameIndex = stackTable.frame[stackIndex];
    const funcIndex = frameTable.func[frameIndex];
    const prefixFuncStackAndFuncIndex = prefixFuncStack * funcCount + funcIndex;
    let funcStackIndex = prefixFuncStackAndFuncToFuncStackMap.get(prefixFuncStackAndFuncIndex);
    if (funcStackIndex === undefined) {
      funcStackIndex = funcStackTable.length;
      addFuncStack(prefixFuncStack, funcIndex);
      prefixFuncStackAndFuncToFuncStackMap.set(prefixFuncStackAndFuncIndex, funcStackIndex);
    }
    stackIndexToFuncStackIndex.set(stackIndex, funcStackIndex);
  }
  funcStackTable.prefix = new Int32Array(funcStackTable.prefix);
  funcStackTable.func = new Int32Array(funcStackTable.func);
  funcStackTable.depth = funcStackTable.depth;

  return {
    funcStackTable,
    sampleFuncStacks: samples.stack.map(stack => stackIndexToFuncStackIndex.get(stack))
  };
});
}

function getTimeRangeForThread(thread, interval) {
  return { start: thread.samples.time[0], end: thread.samples.time[thread.samples.length - 1] + interval};
}

export function getTimeRangeIncludingAllThreads(profile) {
  const completeRange = { start: Infinity, end: -Infinity };
  profile.threads.forEach(thread => {
    const threadRange = getTimeRangeForThread(thread, profile.meta.interval);
    completeRange.start = Math.min(completeRange.start, threadRange.start);
    completeRange.end = Math.max(completeRange.end, threadRange.end);
  });
  return completeRange;
}

export function defaultThreadOrder(threads) {
  // Put the compositor thread last.
  let threadOrder = threads.map((thread, i) => i);
  threadOrder.sort((a, b) => {
    const nameA = threads[a].name;
    const nameB = threads[b].name;
    if (nameA === nameB) {
      return a - b;
    }
    return (nameA === 'Compositor') ? 1 : -1;
  });
  return threadOrder;
}

export function filterThreadToJSOnly(thread) {
return timeCode('filterThreadToJSOnly', () => {
  const { stackTable, funcTable, frameTable, samples } = thread;

  // frameTable will be equal to funcTable
  const newFrameTable = {
    length: 0,
    func: [],
    address: [],
  };
  const newFuncTable = {
    length: 0,
    name: [],
    resource: [],
    address: [],
    isJS: [],
  };
  function addFrameAndFunc(oldFuncIndex) {
    const newFuncIndex = newFuncTable.length++;
    newFuncTable.name[newFuncIndex] = funcTable.name[oldFuncIndex];
    newFuncTable.resource[newFuncIndex] = funcTable.resource[oldFuncIndex];
    newFuncTable.isJS[newFuncIndex] = true;
    const newFrameIndex = newFrameTable.length++;
    newFrameTable.func[newFrameIndex] = newFuncIndex;
    return newFrameIndex;
  }
  const newStackTable = {
    length: 0,
    frame: [],
    prefix: [],
  };

  const oldStackToNewStack = new Map();
  const funcCount = funcTable.length;
  let prefixStackAndFuncToStack = new Map(); // prefixNewStack * funcCount + func => newStackIndex

  function convertStack(stackIndex) {
    if (stackIndex === null) {
      return null;
    }
    let newStack = oldStackToNewStack.get(stackIndex);
    if (newStack === undefined) {
      const prefixNewStack = convertStack(stackTable.prefix[stackIndex]);
      const frameIndex = stackTable.frame[stackIndex];
      const funcIndex = frameTable.func[frameIndex];
      if (!funcTable.isJS[funcIndex]) {
        newStack = prefixNewStack;
      } else {
        const prefixStackAndFuncIndex = (prefixNewStack === null ? -1 : prefixNewStack) * funcCount + funcIndex;
        newStack = prefixStackAndFuncToStack.get(prefixStackAndFuncIndex);
        if (newStack === undefined) {
          const newFrameIndex = addFrameAndFunc(funcIndex);
          newStack = newStackTable.length++;
          newStackTable.prefix[newStack] = prefixNewStack;
          newStackTable.frame[newStack] = newFrameIndex;
        }
        oldStackToNewStack.set(stackIndex, newStack);
        prefixStackAndFuncToStack.set(prefixStackAndFuncIndex, newStack);
      }
    }
    return newStack;
  }

  const newSamples = Object.assign({}, samples, {
    stack: samples.stack.map(oldStack => convertStack(oldStack))
  });

  return Object.assign({}, thread, {
    samples: newSamples,
    stackTable: newStackTable,
    funcTable: newFuncTable,
    frameTable: newFrameTable,
  });
});
}

export function getFuncStackFromFuncArray(funcArray, funcStackTable) {
  let fs = -1;
  for (let i = 0; i < funcArray.length; i++) {
    const func = funcArray[i];
    let nextFS = -1;
    for (let funcStackIndex = fs + 1; funcStackIndex < funcStackTable.length; funcStackIndex++) {
      if (funcStackTable.prefix[funcStackIndex] === fs &&
          funcStackTable.func[funcStackIndex] === func) {
        nextFS = funcStackIndex;
        break;
      }
    }
    if (nextFS === -1) {
      return null;
    }
    fs = nextFS;
  }
  return fs;
}

export function getStackAsFuncArray(funcStackIndex, funcStackTable) {
  if (funcStackIndex === null) {
    return [];
  }
  const funcArray = [];
  let fs = funcStackIndex;
  while (fs !== -1) {
    funcArray.push(funcStackTable.func[fs]);
    fs = funcStackTable.prefix[fs];
  }
  funcArray.reverse();
  return funcArray;
}

export function invertCallstack(thread) {
return timeCode('invertCallstack', () => {
  const { stackTable, funcTable, frameTable, samples } = thread;

  const newStackTable = {
    length: 0,
    frame: [],
    prefix: [],
  };
  const frameCount = frameTable.length;
  let prefixAndFrameToStack = new Map(); // prefix * frameCount + frame => stackIndex
  function stackFor(prefix, frame) {
    const prefixAndFrameIndex = (prefix === null ? -1 : prefix) * frameCount + frame;
    let stackIndex = prefixAndFrameToStack.get(prefixAndFrameIndex);
    if (stackIndex === undefined) {
      stackIndex = newStackTable.length++;
      newStackTable.prefix[stackIndex] = prefix;
      newStackTable.frame[stackIndex] = frame;
      prefixAndFrameToStack.set(prefixAndFrameIndex, stackIndex);
    }
    return stackIndex;
  }

  const oldStackToNewStack = new Map();

  function convertStack(stackIndex) {
    if (stackIndex === null) {
      return null;
    }
    let newStack = oldStackToNewStack.get(stackIndex);
    if (newStack === undefined) {
      newStack = null;
      for (let currentStack = stackIndex; currentStack !== null; currentStack = stackTable.prefix[currentStack]) {
        newStack = stackFor(newStack, stackTable.frame[currentStack]);
      }
      oldStackToNewStack.set(stackIndex, newStack);
    }
    return newStack;
  }

  const newSamples = Object.assign({}, samples, {
    stack: samples.stack.map(oldStack => convertStack(oldStack))
  });

  return Object.assign({}, thread, {
    samples: newSamples,
    stackTable: newStackTable,
  });
});
}
<commit_msg>Remove unused variable.<commit_after>import { timeCode } from './time-code';

/**
 * Various helpers for dealing with the profile as a data structure.
 */

export const resourceTypes = {
  unknown: 0,
  library: 1,
  addon: 2,
  webhost: 3,
  otherhost: 4,
  url: 5
};

/**
 * Takes the stack table and the frame table, creates a func stack table and
 * fixes up the funcStack field in the samples data.
 * @return object  The funcStackTable and the new samples object.
 */
export function getFuncStackInfo(stackTable, frameTable, funcTable, samples) {
return timeCode('getFuncStackInfo', () => {
  let stackIndexToFuncStackIndex = new Map();
  const funcCount = funcTable.length;
  let prefixFuncStackAndFuncToFuncStackMap = new Map(); // prefixFuncStack * funcCount + func => funcStack
  let funcStackTable = { length: 0, prefix: [], func: [], depth: [] };
  function addFuncStack(prefix, func) {
    const index = funcStackTable.length++;
    funcStackTable.prefix[index] = prefix;
    funcStackTable.func[index] = func;
    if (prefix === -1) {
      funcStackTable.depth[index] = 0;
    } else {
      funcStackTable.depth[index] = funcStackTable.depth[prefix] + 1;
    }
  }
  for (let stackIndex = 0; stackIndex < stackTable.length; stackIndex++) {
    const prefixStack = stackTable.prefix[stackIndex];
    const prefixFuncStack = (prefixStack === null) ? -1 :
       stackIndexToFuncStackIndex.get(prefixStack);
    const frameIndex = stackTable.frame[stackIndex];
    const funcIndex = frameTable.func[frameIndex];
    const prefixFuncStackAndFuncIndex = prefixFuncStack * funcCount + funcIndex;
    let funcStackIndex = prefixFuncStackAndFuncToFuncStackMap.get(prefixFuncStackAndFuncIndex);
    if (funcStackIndex === undefined) {
      funcStackIndex = funcStackTable.length;
      addFuncStack(prefixFuncStack, funcIndex);
      prefixFuncStackAndFuncToFuncStackMap.set(prefixFuncStackAndFuncIndex, funcStackIndex);
    }
    stackIndexToFuncStackIndex.set(stackIndex, funcStackIndex);
  }
  funcStackTable.prefix = new Int32Array(funcStackTable.prefix);
  funcStackTable.func = new Int32Array(funcStackTable.func);
  funcStackTable.depth = funcStackTable.depth;

  return {
    funcStackTable,
    sampleFuncStacks: samples.stack.map(stack => stackIndexToFuncStackIndex.get(stack))
  };
});
}

function getTimeRangeForThread(thread, interval) {
  return { start: thread.samples.time[0], end: thread.samples.time[thread.samples.length - 1] + interval};
}

export function getTimeRangeIncludingAllThreads(profile) {
  const completeRange = { start: Infinity, end: -Infinity };
  profile.threads.forEach(thread => {
    const threadRange = getTimeRangeForThread(thread, profile.meta.interval);
    completeRange.start = Math.min(completeRange.start, threadRange.start);
    completeRange.end = Math.max(completeRange.end, threadRange.end);
  });
  return completeRange;
}

export function defaultThreadOrder(threads) {
  // Put the compositor thread last.
  let threadOrder = threads.map((thread, i) => i);
  threadOrder.sort((a, b) => {
    const nameA = threads[a].name;
    const nameB = threads[b].name;
    if (nameA === nameB) {
      return a - b;
    }
    return (nameA === 'Compositor') ? 1 : -1;
  });
  return threadOrder;
}

export function filterThreadToJSOnly(thread) {
return timeCode('filterThreadToJSOnly', () => {
  const { stackTable, funcTable, frameTable, samples } = thread;

  // frameTable will be equal to funcTable
  const newFrameTable = {
    length: 0,
    func: [],
    address: [],
  };
  const newFuncTable = {
    length: 0,
    name: [],
    resource: [],
    address: [],
    isJS: [],
  };
  function addFrameAndFunc(oldFuncIndex) {
    const newFuncIndex = newFuncTable.length++;
    newFuncTable.name[newFuncIndex] = funcTable.name[oldFuncIndex];
    newFuncTable.resource[newFuncIndex] = funcTable.resource[oldFuncIndex];
    newFuncTable.isJS[newFuncIndex] = true;
    const newFrameIndex = newFrameTable.length++;
    newFrameTable.func[newFrameIndex] = newFuncIndex;
    return newFrameIndex;
  }
  const newStackTable = {
    length: 0,
    frame: [],
    prefix: [],
  };

  const oldStackToNewStack = new Map();
  const funcCount = funcTable.length;
  let prefixStackAndFuncToStack = new Map(); // prefixNewStack * funcCount + func => newStackIndex

  function convertStack(stackIndex) {
    if (stackIndex === null) {
      return null;
    }
    let newStack = oldStackToNewStack.get(stackIndex);
    if (newStack === undefined) {
      const prefixNewStack = convertStack(stackTable.prefix[stackIndex]);
      const frameIndex = stackTable.frame[stackIndex];
      const funcIndex = frameTable.func[frameIndex];
      if (!funcTable.isJS[funcIndex]) {
        newStack = prefixNewStack;
      } else {
        const prefixStackAndFuncIndex = (prefixNewStack === null ? -1 : prefixNewStack) * funcCount + funcIndex;
        newStack = prefixStackAndFuncToStack.get(prefixStackAndFuncIndex);
        if (newStack === undefined) {
          const newFrameIndex = addFrameAndFunc(funcIndex);
          newStack = newStackTable.length++;
          newStackTable.prefix[newStack] = prefixNewStack;
          newStackTable.frame[newStack] = newFrameIndex;
        }
        oldStackToNewStack.set(stackIndex, newStack);
        prefixStackAndFuncToStack.set(prefixStackAndFuncIndex, newStack);
      }
    }
    return newStack;
  }

  const newSamples = Object.assign({}, samples, {
    stack: samples.stack.map(oldStack => convertStack(oldStack))
  });

  return Object.assign({}, thread, {
    samples: newSamples,
    stackTable: newStackTable,
    funcTable: newFuncTable,
    frameTable: newFrameTable,
  });
});
}

export function getFuncStackFromFuncArray(funcArray, funcStackTable) {
  let fs = -1;
  for (let i = 0; i < funcArray.length; i++) {
    const func = funcArray[i];
    let nextFS = -1;
    for (let funcStackIndex = fs + 1; funcStackIndex < funcStackTable.length; funcStackIndex++) {
      if (funcStackTable.prefix[funcStackIndex] === fs &&
          funcStackTable.func[funcStackIndex] === func) {
        nextFS = funcStackIndex;
        break;
      }
    }
    if (nextFS === -1) {
      return null;
    }
    fs = nextFS;
  }
  return fs;
}

export function getStackAsFuncArray(funcStackIndex, funcStackTable) {
  if (funcStackIndex === null) {
    return [];
  }
  const funcArray = [];
  let fs = funcStackIndex;
  while (fs !== -1) {
    funcArray.push(funcStackTable.func[fs]);
    fs = funcStackTable.prefix[fs];
  }
  funcArray.reverse();
  return funcArray;
}

export function invertCallstack(thread) {
return timeCode('invertCallstack', () => {
  const { stackTable, frameTable, samples } = thread;

  const newStackTable = {
    length: 0,
    frame: [],
    prefix: [],
  };
  const frameCount = frameTable.length;
  let prefixAndFrameToStack = new Map(); // prefix * frameCount + frame => stackIndex
  function stackFor(prefix, frame) {
    const prefixAndFrameIndex = (prefix === null ? -1 : prefix) * frameCount + frame;
    let stackIndex = prefixAndFrameToStack.get(prefixAndFrameIndex);
    if (stackIndex === undefined) {
      stackIndex = newStackTable.length++;
      newStackTable.prefix[stackIndex] = prefix;
      newStackTable.frame[stackIndex] = frame;
      prefixAndFrameToStack.set(prefixAndFrameIndex, stackIndex);
    }
    return stackIndex;
  }

  const oldStackToNewStack = new Map();

  function convertStack(stackIndex) {
    if (stackIndex === null) {
      return null;
    }
    let newStack = oldStackToNewStack.get(stackIndex);
    if (newStack === undefined) {
      newStack = null;
      for (let currentStack = stackIndex; currentStack !== null; currentStack = stackTable.prefix[currentStack]) {
        newStack = stackFor(newStack, stackTable.frame[currentStack]);
      }
      oldStackToNewStack.set(stackIndex, newStack);
    }
    return newStack;
  }

  const newSamples = Object.assign({}, samples, {
    stack: samples.stack.map(oldStack => convertStack(oldStack))
  });

  return Object.assign({}, thread, {
    samples: newSamples,
    stackTable: newStackTable,
  });
});
}
<|endoftext|>


<commit_before>(function (factory) {
	var L, proj4;
	if (typeof define === 'function' && define.amd) {
		// AMD
		define(['leaflet', 'proj4'], factory);
	} else if (typeof module !== 'undefined') {
		// Node/CommonJS
		L = require('leaflet');
		proj4 = require('proj4');
		module.exports = factory(L, proj4);
	} else {
		// Browser globals
		if (typeof window.L === 'undefined' || typeof window.proj4 === 'undefined')
			throw 'Leaflet and proj4 must be loaded first';
		factory(window.L, window.proj4);
	}
}(function (L, proj4) {

	L.Proj = {};

	L.Proj._isProj4Obj = function(a) {
		return (typeof a.inverse !== 'undefined' &&
			typeof a.forward !== 'undefined');
	};

	L.Proj.Projection = L.Class.extend({
		initialize: function(code, def, bounds) {
			var isP4 = L.Proj._isProj4Obj(code);
			this._proj = isP4 ? code : this._projFromCodeDef(code, def);
			this.bounds = isP4 ? def : bounds;
		},

		project: function (latlng) {
			var point = this._proj.forward([latlng.lng, latlng.lat]);
			return new L.Point(point[0], point[1]);
		},

		unproject: function (point, unbounded) {
			var point2 = this._proj.inverse([point.x, point.y]);
			return new L.LatLng(point2[1], point2[0], unbounded);
		},

		_projFromCodeDef: function(code, def) {
			if (def) {
				proj4.defs(code, def);
			} else if (proj4.defs[code] === undefined) {
				var urn = code.split(':');
				if (urn.length > 3) {
					code = urn[urn.length - 3] + ':' + urn[urn.length - 1];
				}
				if (proj4.defs[code] === undefined) {
					throw 'No projection definition for code ' + code;
				}
			}

			return proj4(code);
		}
	});

	L.Proj.CRS = L.Class.extend({
		includes: L.CRS,

		options: {
			transformation: new L.Transformation(1, 0, -1, 0)
		},

		initialize: function(a, b, c) {
			var code,
			    proj,
			    def,
			    options;

			if (L.Proj._isProj4Obj(a)) {
				proj = a;
				code = proj.srsCode;
				options = b || {};

				this.projection = new L.Proj.Projection(proj, options.bounds);
			} else {
				code = a;
				def = b;
				options = c || {};
				this.projection = new L.Proj.Projection(code, def, options.bounds);
			}

			L.Util.setOptions(this, options);
			this.code = code;
			this.transformation = this.options.transformation;

			if (this.options.origin) {
				this.transformation =
					new L.Transformation(1, -this.options.origin[0],
						-1, this.options.origin[1]);
			}

			if (this.options.scales) {
				this._scales = this.options.scales;
			} else if (this.options.resolutions) {
				this._scales = [];
				for (var i = this.options.resolutions.length - 1; i >= 0; i--) {
					if (this.options.resolutions[i]) {
						this._scales[i] = 1 / this.options.resolutions[i];
					}
				}
			}

			this.infinite = !this.options.bounds;
		},

		scale: function(zoom) {
			var iZoom = Math.floor(zoom),
				baseScale,
				nextScale,
				scaleDiff,
				zDiff;
			if (zoom === iZoom) {
				return this._scales[zoom];
			} else {
				// Non-integer zoom, interpolate
				baseScale = this._scales[iZoom];
				nextScale = this._scales[iZoom + 1];
				scaleDiff = nextScale - baseScale;
				zDiff = (zoom - iZoom);
				return baseScale + scaleDiff * zDiff;
			}
		},

		zoom: function(scale) {
			// Find closest number in this._scales, down
			var downScale = this._closestElement(this._scales, scale),
				downZoom = this._scales.indexOf(downScale),
				nextZoom,
				scaleDiff;
			// Check if scale is downScale => return array index
			if (scale === downScale) {
				return downZoom;
			}
			// Interpolate
			nextZoom = downZoom + 1;
			scaleDiff = this._scales[nextZoom] - downScale;
			return (scale - downScale) / scaleDiff + downZoom;
		},

		/* Get the closest lowest element in an array */
		_closestElement: function(array, element) {
			var low;
			for (var i = array.length; i--;) {
				if (array[i] <= element && (low === undefined || low < array[i])) {
					low = array[i];
				}
			}
			return low;
		}
	});

	L.Proj.GeoJSON = L.GeoJSON.extend({
		initialize: function(geojson, options) {
			if (geojson.crs && geojson.crs.type === 'name') {
				var crs = new L.Proj.CRS(geojson.crs.properties.name);
				options = options || {};
				options.coordsToLatLng = function(coords) {
					var point = L.point(coords[0], coords[1]);
					return crs.projection.unproject(point);
				};
			}
			L.GeoJSON.prototype.initialize.call(this, geojson, options);
		}
	});

	L.Proj.geoJson = function(geojson, options) {
		return new L.Proj.GeoJSON(geojson, options);
	};

	return L.Proj;
}));
<commit_msg>Fix GeoJSON.initialize when no data<commit_after>(function (factory) {
	var L, proj4;
	if (typeof define === 'function' && define.amd) {
		// AMD
		define(['leaflet', 'proj4'], factory);
	} else if (typeof module !== 'undefined') {
		// Node/CommonJS
		L = require('leaflet');
		proj4 = require('proj4');
		module.exports = factory(L, proj4);
	} else {
		// Browser globals
		if (typeof window.L === 'undefined' || typeof window.proj4 === 'undefined')
			throw 'Leaflet and proj4 must be loaded first';
		factory(window.L, window.proj4);
	}
}(function (L, proj4) {

	L.Proj = {};

	L.Proj._isProj4Obj = function(a) {
		return (typeof a.inverse !== 'undefined' &&
			typeof a.forward !== 'undefined');
	};

	L.Proj.Projection = L.Class.extend({
		initialize: function(code, def, bounds) {
			var isP4 = L.Proj._isProj4Obj(code);
			this._proj = isP4 ? code : this._projFromCodeDef(code, def);
			this.bounds = isP4 ? def : bounds;
		},

		project: function (latlng) {
			var point = this._proj.forward([latlng.lng, latlng.lat]);
			return new L.Point(point[0], point[1]);
		},

		unproject: function (point, unbounded) {
			var point2 = this._proj.inverse([point.x, point.y]);
			return new L.LatLng(point2[1], point2[0], unbounded);
		},

		_projFromCodeDef: function(code, def) {
			if (def) {
				proj4.defs(code, def);
			} else if (proj4.defs[code] === undefined) {
				var urn = code.split(':');
				if (urn.length > 3) {
					code = urn[urn.length - 3] + ':' + urn[urn.length - 1];
				}
				if (proj4.defs[code] === undefined) {
					throw 'No projection definition for code ' + code;
				}
			}

			return proj4(code);
		}
	});

	L.Proj.CRS = L.Class.extend({
		includes: L.CRS,

		options: {
			transformation: new L.Transformation(1, 0, -1, 0)
		},

		initialize: function(a, b, c) {
			var code,
			    proj,
			    def,
			    options;

			if (L.Proj._isProj4Obj(a)) {
				proj = a;
				code = proj.srsCode;
				options = b || {};

				this.projection = new L.Proj.Projection(proj, options.bounds);
			} else {
				code = a;
				def = b;
				options = c || {};
				this.projection = new L.Proj.Projection(code, def, options.bounds);
			}

			L.Util.setOptions(this, options);
			this.code = code;
			this.transformation = this.options.transformation;

			if (this.options.origin) {
				this.transformation =
					new L.Transformation(1, -this.options.origin[0],
						-1, this.options.origin[1]);
			}

			if (this.options.scales) {
				this._scales = this.options.scales;
			} else if (this.options.resolutions) {
				this._scales = [];
				for (var i = this.options.resolutions.length - 1; i >= 0; i--) {
					if (this.options.resolutions[i]) {
						this._scales[i] = 1 / this.options.resolutions[i];
					}
				}
			}

			this.infinite = !this.options.bounds;
		},

		scale: function(zoom) {
			var iZoom = Math.floor(zoom),
				baseScale,
				nextScale,
				scaleDiff,
				zDiff;
			if (zoom === iZoom) {
				return this._scales[zoom];
			} else {
				// Non-integer zoom, interpolate
				baseScale = this._scales[iZoom];
				nextScale = this._scales[iZoom + 1];
				scaleDiff = nextScale - baseScale;
				zDiff = (zoom - iZoom);
				return baseScale + scaleDiff * zDiff;
			}
		},

		zoom: function(scale) {
			// Find closest number in this._scales, down
			var downScale = this._closestElement(this._scales, scale),
				downZoom = this._scales.indexOf(downScale),
				nextZoom,
				scaleDiff;
			// Check if scale is downScale => return array index
			if (scale === downScale) {
				return downZoom;
			}
			// Interpolate
			nextZoom = downZoom + 1;
			scaleDiff = this._scales[nextZoom] - downScale;
			return (scale - downScale) / scaleDiff + downZoom;
		},

		/* Get the closest lowest element in an array */
		_closestElement: function(array, element) {
			var low;
			for (var i = array.length; i--;) {
				if (array[i] <= element && (low === undefined || low < array[i])) {
					low = array[i];
				}
			}
			return low;
		}
	});

	L.Proj.GeoJSON = L.GeoJSON.extend({
		initialize: function(geojson, options) {
			this._callLevel = 0;
			L.GeoJSON.prototype.initialize.call(this, geojson, options);
		},

		addData: function(geojson) {
			var crs;

			if (geojson) {
				if (geojson.crs && geojson.crs.type === 'name') {
					crs = new L.Proj.CRS(geojson.crs.properties.name);
				} else if (geojson.crs && geojson.crs.type) {
					crs = new L.Proj.CRS(geojson.crs.type + ':' + geojson.crs.properties.code);
				}

				if (crs !== undefined) {
					this.options.coordsToLatLng = function(coords) {
						var point = L.point(coords[0], coords[1]);
						return crs.projection.unproject(point);
					};
				}
			}

			// Base class' addData might call us recursively, but
			// CRS shouldn't be cleared in that case, since CRS applies
			// to the whole GeoJSON, inluding sub-features.
			this._callLevel++;
			try {
				L.GeoJSON.prototype.addData.call(this, geojson);
			} finally {
				this._callLevel--;
				if (this._callLevel === 0) {
					delete this.options.coordsToLatLng;
				}
			}
		}
	});

	L.Proj.geoJson = function(geojson, options) {
		return new L.Proj.GeoJSON(geojson, options);
	};

	return L.Proj;
}));
<|endoftext|>


<commit_before>(function() {

  var pageX = 0, pageY  = 0;
  document.addEventListener('mousemove', function(e) {
    pageX = e.pageX;
    pageY = e.pageY;
  });

  var vertexShader = 'attribute vec2 pos;void main(){gl_Position=vec4(pos.x,pos.y,0.0,1.00);}',
      header = [
        '#ifdef GL_ES\n',
        'precision highp float;\n',
        '#endif\n',
        'uniform vec3 resolution;\n',
        'uniform float time;\n',
        'uniform float millis;\n',
        'uniform vec2 mouse;\n',
        'uniform sampler2D tex0;\n'].join('');

  // Some of this code is based off of this pen http://codepen.io/jaburns/pen/hHuLI
  // by Jeremy Burns https://github.com/jaburns

  // seen variations on this basic code floating around a bunch
  // may even originally be from http://shadertoy.com

  window.QuickShader = function(params) {

    if (!params.shader){
      console.warn('You must specify a fragment shader');
    }

    this.width = params.width || 400;
    this.height = params.height || 400;
    this.shader = header + params.shader;

    this.canvas = document.createElement('canvas');
    this.canvas.width = this.width;
    this.canvas.height = this.height;

    if (params.parentNode) {
      this.parentNode = typeof params.parentNode === 'object' ?
        params.parentNode : document.querySelector(params.parentNode);

      this.parentNode.appendChild(this.canvas);
    }

    this.pauseOffset = 0;
    this.totalPauseTime = 0;

    this.init();
  };

  QuickShader.prototype = {

    constructor: QuickShader,

    init: function() {
      var gl, vertices, error;

      gl = this.gl = this.ctx = this.canvas.getContext('experimental-webgl');

      vertices = new Float32Array([ -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0 ]);

      this.quadVBO = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVBO);
      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

      error = this.configureShader();

      if (error) {
        this.destroy();
        if (this.parentNode) {
         var pre = document.createElement('pre');
         pre.innerHTML = error;
         this.parentNode.appendChild(pre);
        }
        return;
      }

      this.size(this.width, this.height);
      this.millis = new Date().getMilliseconds() / 1000;
    },

    destroy: function() {
      this.reset();
      if (this.canvas.parentNode) {
        this.canvas.parentNode.removeChild(this.canvas);
      }
    },

    reset: function() {
      this.startTime = null;
      cancelAnimationFrame(this.animationId);
    },

    play: function() {
      if (this.error) return;

      this.totalPauseTime += this.pauseOffset;
      this.paused = false;

      if (this.startTime) { return; }

      this.startTime = +new Date();
      this.run();
    },

    run: function() {
      var time = (+new Date() - this.startTime - this.totalPauseTime) / 1000;
      this.render(time)
      this.animationId = requestAnimationFrame( this.run.bind(this) );
    },

    pause: function() {
      this.paused = true;
      this.pauseTime = +new Date();
    },

    size: function(width, height) {
      this.width = width;
      this.height = height
      this.canvas.width = width;
      this.canvas.height = height;
      this.gl.viewport( 0, 0, this.width, this.height );
    },

    configureShader: function() {
      var gl = this.gl,
          tempProgram = gl.createProgram(),
          vs = gl.createShader(gl.VERTEX_SHADER),
          fs = gl.createShader(gl.FRAGMENT_SHADER),
          infoLog;

      gl.shaderSource(vs, vertexShader);
      gl.shaderSource(fs, this.shader);

      gl.compileShader(vs);
      gl.compileShader(fs);

      if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {
        infoLog = gl.getShaderInfoLog(fs);
        gl.deleteProgram( tempProgram );
        this.error = true;
        return 'shader-error: \n' + infoLog;
      }

      gl.attachShader(tempProgram, vs);
      gl.attachShader(tempProgram, fs);

      gl.deleteShader(vs);
      gl.deleteShader(fs);

      gl.linkProgram(tempProgram);

      if (this.shaderProgram) {
        gl.deleteProgram(this.shaderProgram);
      }

      this.shaderProgram = tempProgram;
    },

    render: function(time) {
      var gl = this.gl, inputs = [], rect;

      time = time || 0;

      if (this.paused){
        this.pauseOffset = +new Date() - this.pauseTime;
        return;
      }

      gl.viewport(0, 0, this.width, this.height);

      gl.useProgram(this.shaderProgram);

      inputs[0] = gl.getAttribLocation(this.shaderProgram, 'pos');
      inputs[1] = gl.getUniformLocation(this.shaderProgram, 'time');
      inputs[2] = gl.getUniformLocation(this.shaderProgram, 'resolution');
      inputs[3] = gl.getUniformLocation(this.shaderProgram, 'millis');
      inputs[4] = gl.getUniformLocation(this.shaderProgram, 'mouse');

      // t0 = gl.getUniformLocation(this.shaderProgram, 'tex0');

      gl.uniform1f(inputs[1], time);
      gl.uniform3f(inputs[2], this.width, this.height, 1.0);
      gl.uniform1f(inputs[3], this.millis);

      rect = this.canvas.getBoundingClientRect();
      mouseX = pageX - rect.left;
      mouseY = pageY - rect.top;

      gl.uniform2f(inputs[4], mouseX, mouseY);

      gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVBO);
      gl.vertexAttribPointer(inputs[0], 2, gl.FLOAT, false, 0, 0);

      gl.enableVertexAttribArray(inputs[0]);

      /*
      if (t0 !== null) {
        gl.uniform1i(t0, 0 );
        gl.activeTexture(gl.TEXTURE0);
        gl.bindTexture(gl.TEXTURE_2D, this.mTexture);
      }
      */

      gl.drawArrays(gl.TRIANGLES, 0, 6);
      gl.disableVertexAttribArray(inputs[0]);
    }

  };

})();

<commit_msg>texture functionality<commit_after>(function() {

  var pageX = 0, pageY  = 0;
  document.addEventListener('mousemove', function(e) {
    pageX = e.pageX;
    pageY = e.pageY;
  });

  var vertexShader = 'attribute vec2 pos;void main(){gl_Position=vec4(pos.x,pos.y,0.0,1.00);}',
      header = [
        '#ifdef GL_ES\n',
        'precision highp float;\n',
        '#endif\n',
        'uniform vec3 resolution;\n',
        'uniform float time;\n',
        'uniform float millis;\n',
        'uniform vec2 mouse;\n',
        'uniform sampler2D tex0;\n'].join('');

  // Some of this code is based off of this pen http://codepen.io/jaburns/pen/hHuLI
  // by Jeremy Burns https://github.com/jaburns

  // seen variations on this basic code floating around a bunch on github and elsewhere
  // may even originally be from http://shadertoy.com

  window.QuickShader = function(params) {

    if (!params.shader){
      console.warn('You must specify a fragment shader');
    }

    this.width = params.width || 400;
    this.height = params.height || 400;
    this.shader = params.shader;

    this.textureCode = '';
    this.texturesIn = params.textures;
    this.textures = [];

    this.canvas = document.createElement('canvas');
    this.canvas.width = this.width;
    this.canvas.height = this.height;

    if (params.parentNode) {
      this.parentNode = typeof params.parentNode === 'object' ?
        params.parentNode : document.querySelector(params.parentNode);

      this.parentNode.appendChild(this.canvas);
    }

    this.pauseOffset = 0;
    this.totalPauseTime = 0;

    this.init();
  };

  QuickShader.prototype = {

    constructor: QuickShader,

    init: function() {
      var gl, vertices, error;

      gl = this.gl = this.ctx = this.canvas.getContext('experimental-webgl');

      vertices = new Float32Array([ -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0 ]);

      this.quadVBO = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVBO);
      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

      this.texturesIn.forEach(this.addTexture.bind(this));

      this.shader = [header, this.textureCode, this.shader].join('');

      error = this.configureShader();

      if (error) {
        this.destroy();
        if (this.parentNode) {
         var pre = document.createElement('pre');
         pre.innerHTML = error;
         this.parentNode.appendChild(pre);
        }
        return;
      }

      this.size(this.width, this.height);
      this.millis = new Date().getMilliseconds() / 1000;
    },

    destroy: function() {
      this.reset();
      if (this.canvas.parentNode) {
        this.canvas.parentNode.removeChild(this.canvas);
      }
    },

    reset: function() {
      this.startTime = null;
      cancelAnimationFrame(this.animationId);
    },

    play: function() {
      if (this.error) return;

      this.totalPauseTime += this.pauseOffset;
      this.paused = false;

      if (this.startTime) { return; }

      this.startTime = +new Date();
      this.run();
    },

    run: function() {
      var time = (+new Date() - this.startTime - this.totalPauseTime) / 1000;
      this.render(time)
      this.animationId = requestAnimationFrame( this.run.bind(this) );
    },

    pause: function() {
      this.paused = true;
      this.pauseTime = +new Date();
    },

    size: function(width, height) {
      this.width = width;
      this.height = height
      this.canvas.width = width;
      this.canvas.height = height;
      this.gl.viewport( 0, 0, this.width, this.height );
    },

    configureShader: function() {
      var gl = this.gl,
          tempProgram = gl.createProgram(),
          vs = gl.createShader(gl.VERTEX_SHADER),
          fs = gl.createShader(gl.FRAGMENT_SHADER),
          infoLog;

      gl.shaderSource(vs, vertexShader);
      gl.shaderSource(fs, this.shader);

      gl.compileShader(vs);
      gl.compileShader(fs);

      if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {
        infoLog = gl.getShaderInfoLog(fs);
        gl.deleteProgram( tempProgram );
        this.error = true;
        return 'shader-error: \n' + infoLog;
      }

      gl.attachShader(tempProgram, vs);
      gl.attachShader(tempProgram, fs);

      gl.deleteShader(vs);
      gl.deleteShader(fs);

      gl.linkProgram(tempProgram);

      if (this.shaderProgram) {
        gl.deleteProgram(this.shaderProgram);
      }

      this.shaderProgram = tempProgram;
    },

    render: function(time) {
      var gl = this.gl, inputs = [], rect, textureNum, texureInputs = [];

      time = time || 0;

      if (this.paused){
        this.pauseOffset = +new Date() - this.pauseTime;
        return;
      }

      gl.viewport(0, 0, this.width, this.height);

      gl.useProgram(this.shaderProgram);

      inputs[0] = gl.getAttribLocation(this.shaderProgram, 'pos');
      inputs[1] = gl.getUniformLocation(this.shaderProgram, 'time');
      inputs[2] = gl.getUniformLocation(this.shaderProgram, 'resolution');
      inputs[3] = gl.getUniformLocation(this.shaderProgram, 'millis');
      inputs[4] = gl.getUniformLocation(this.shaderProgram, 'mouse');

      // t0 = gl.getUniformLocation(this.shaderProgram, 'tex0');

      textureNum = this.textures.length;

      for (var i = 0; i < textureNum; i++){
        texureInputs[i] = gl.getUniformLocation(this.shaderProgram,  this.textures[i].name);
      }

      gl.uniform1f(inputs[1], time);
      gl.uniform3f(inputs[2], this.width, this.height, 1.0);
      gl.uniform1f(inputs[3], this.millis);

      rect = this.canvas.getBoundingClientRect();
      mouseX = pageX - rect.left;
      mouseY = pageY - rect.top;

      gl.uniform2f(inputs[4], mouseX, mouseY);

      gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVBO);
      gl.vertexAttribPointer(inputs[0], 2, gl.FLOAT, false, 0, 0);

      gl.enableVertexAttribArray(inputs[0]);

      /*
      if (t0 !== null) {
        gl.uniform1i(t0, 0 );
        gl.activeTexture(gl.TEXTURE0);
        gl.bindTexture(gl.TEXTURE_2D, this.mTexture);
      }
      */

      for (var i = 0; i < textureNum; i++){
        gl.uniform1i(texureInputs[i], i);
        gl.activeTexture(gl['TEXTURE' + i]);
        gl.bindTexture(gl.TEXTURE_2D, this.textures[i].texture);
      }

      gl.drawArrays(gl.TRIANGLES, 0, 6);
      gl.disableVertexAttribArray(inputs[0]);
    },

    addTexture: function(info) {

      var gl = this.gl,
          img = info.src,
          name = info.name,
          texture = gl.createTexture();

      this.textureCode += [ 'uniform sampler2D ', name, ';\n' ].join('');

      gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);

      gl.bindTexture(gl.TEXTURE_2D, texture);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
      gl.generateMipmap(gl.TEXTURE_2D);

      gl.bindTexture(gl.TEXTURE_2D, null);
      this.textures.push({name: name, texture: texture});
    }

  };

})();

<|endoftext|>


<commit_before>import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';

import { Icon, Button, Modal } from 'antd';

import FilesystemBrowser from './Filesystem/FilesystemBrowser';
import IDFileModal from './ID/IDFileModal';
import TrashModal from './Filesystem/TrashModal';

import { getSettingsForCategory } from '../actions/settings.actions';

class FileManager extends Component {
    VIDEO_FILE_REGX = /(\.mp4|\.mkv|\.avi)$/;
    constructor(props){
        super(props);

        this.state = {
            currentToplevelDirSetting: {},
            currentToplevelDirectory: "",
            currentPath: "",
            currentPathInfo: {},
            dirList: [],
            idModalFilename: "",
            isReloading: false,
            isTrashVisible: false,
            isIDModalVisible: false,
            itemsToTrash: [],
            selectedRows: []
        };
    }

    componentWillMount(){
        this.props.getSettingsForCategory('directories');
    }

    _reloadDirList(){
        this.setState({
            isReloading: true
        });
    }

    _handleChangeDirectory(newDir, dirList){
        const { currentToplevelDirectory, currentPathInfo } = this.state;

        const subpath = newDir.slice(currentToplevelDirectory.length + 1);
        currentPathInfo.subpath = subpath;
        this.setState({
            currentPathInfo,
            currentPath: newDir,
            dirList,
            selectedRows: [],
            isReloading: false
        })
    }

    _handleSelectTopLevelDir(dir) {
        const pathInfo = {
            setting_id: dir.id,
            subpath: ""
        };
        this.setState({
            currentPathInfo: pathInfo,
            currentToplevelDirectory: dir.value,
            currentPath: dir.value
        });
    }

    _handleSelectionChange(selectedRows){
        this.setState({
            selectedRows
        });
    }

    _handleClickTrash(evt){
        let itemsToTrash = [];
        if(evt.currentTarget.tagName === "BUTTON"){
            itemsToTrash = [...this.state.selectedRows];
        } else {
            const item = evt.currentTarget.getAttribute('data-item-name');
            itemsToTrash = [item];
        }

        this.setState({
            isTrashVisible: true,
            itemsToTrash
        });
    }

    _handleTrashComplete(){
        this.setState({
            isReloading: true,
            isTrashVisible: false,
            itemsToTrash: []
        });
    }

    _handleCancelTrash(){
        this.setState({
            isTrashVisible: false,
            itemsToTrash: []
        });
    }

    _handleClickIDFile(filename){
        this.setState({
            idModalFilename: filename,
            isIDModalVisible: true
        });
    }

    _handleIDModalCancel(){
        this.setState({
            isIDModalVisible: false,
            idModalFilename: ""
        });
    }

    _handleIDModalComplete(){
        this.setState({
            isIDModalVisible: false,
            isReloading: true,
            idModalFilename: ""
        });
    }

    _handleSelectVideos(){
        const { dirList } = this.state;

        let selected = [];
        dirList.forEach((item)=>{
            if(item.name.search(this.VIDEO_FILE_REGX) > -1){
                selected.push(item.name);
            }
        });

        this.setState({
            selectedRows: selected
        });
    }

    _handleClickUntag(id, mediaType){

    }

    _buildActionColumns(){

        return [
            {
                title: "",
                dataIndex: "",
                render: (text,record)=>{
                    const { assocData } = record;

                    let tag = "";
                    if(record.name.search(this.VIDEO_FILE_REGX) > -1){
                        if(!'id' in assocData){
                            tag =
                                        <Icon type="tag"/>
                                    ;
                        }
                    }

                    let untag = "";
                    if('id' in assocData){
                        untag =
                                    <Icon type="disconnect" className="ib-filebrowser-media-play"/>
                                ;
                    }
                    return (

                                <Icon type="delete"/>
                             {tag}{untag}

                    );
                }
            }
        ];
    }

    _buildFileManager(){
        const {
            currentPath,
            currentPathInfo,
            currentToplevelDirectory,
            idModalFilename,
            isReloading,
            isIDModalVisible,
            isTrashVisible,
            itemsToTrash,
            selectedRows } = this.state;

        const hasSelected = (selectedRows.length > 0) ? true : false;
        const buttonDisabled = !hasSelected;

        return (

                    <Button
                        type="primary"
                        icon="video-camera"
                        onClick={this._handleSelectVideos.bind(this)}
                    >Select Videos</Button>
                    <Button.Group>
                        <Button type="primary" icon="search" disabled={buttonDisabled}>ID</Button>
                        <Button
                            type="danger"
                            icon="delete"
                            disabled={buttonDisabled}
                            onClick={this._handleClickTrash.bind(this)}
                        >Trash</Button>
                    </Button.Group>

                <FilesystemBrowser
                    actionColumns={this._buildActionColumns()}
                    forceReload={isReloading}
                    hasCheckboxes={true}
                    initialPath={currentToplevelDirectory}
                    onChangeDirectory={this._handleChangeDirectory.bind(this)}
                    parentHandleSelectChange={this._handleSelectionChange.bind(this)}
                    selectedRowKeys={selectedRows}
                    showDirectories={true}
                    showFiles={true}
                />
                <TrashModal
                    currentPath={currentPath}
                    isVisible={isTrashVisible}
                    itemsToTrash={itemsToTrash}
                    onTrashComplete={this._handleTrashComplete.bind(this)}
                    onCancel={this._handleCancelTrash.bind(this)}
                />
                <IDFileModal
                    key={idModalFilename}
                    isVisible={isIDModalVisible}
                    onIDComplete={this._handleIDModalComplete.bind(this)}
                    onCancel={this._handleIDModalCancel.bind(this)}
                    currentFilename={idModalFilename}
                    currentPathInfo={currentPathInfo}
                    currentToplevelDirectory={currentToplevelDirectory}
                />

        );
    }

    _buildDirectoryButtons(){
        const { toplevelDirectories } = this.props;
        const { currentToplevelDirectory } = this.state;

        const buttonList = [];
        toplevelDirectories.forEach((dir)=>{
            const activeClass = (dir.value === currentToplevelDirectory) ? "ib-filemanager-button ib-filemanager-button-active" : "ib-filemanager-button";
            buttonList.push(
                <Button
                    key={dir.key}
                    onClick={this._handleSelectTopLevelDir.bind(this, dir)}
                    className={activeClass}
                >{dir.key}</Button>
            );
        });

        return (<Button.Group>{buttonList}</Button.Group>);
    }

    render() {
        const { currentToplevelDirectory } = this.state;

        let directoryButtons = this._buildDirectoryButtons();
        let output = "";
        if(currentToplevelDirectory){
            output = this._buildFileManager();
        }
        return (

                    {directoryButtons}

                {output}

        );
    }
}

const mapStateToProps = (state)=>{
    const { settings } = state;

    return {
        toplevelDirectories: settings.settings.directories
    };
}

const mapDispatchToProps = (dispatch)=>{
    return {
        getSettingsForCategory: (category)=>dispatch(getSettingsForCategory(category))
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(FileManager);<commit_msg>Added untag methods.<commit_after>import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';

import { Icon, Button, Modal } from 'antd';

import FilesystemBrowser from './Filesystem/FilesystemBrowser';
import IDFileModal from './ID/IDFileModal';
import TrashModal from './Filesystem/TrashModal';
import UntagModal from './ID/UntagModal';

import { getSettingsForCategory } from '../actions/settings.actions';

class FileManager extends Component {
    VIDEO_FILE_REGX = /(\.mp4|\.mkv|\.avi)$/;
    constructor(props){
        super(props);

        this.state = {
            currentToplevelDirSetting: {},
            currentToplevelDirectory: "",
            currentPath: "",
            currentPathInfo: {},
            dirList: [],
            idModalFilename: "",
            isReloading: false,
            isTrashVisible: false,
            isIDModalVisible: false,
            itemsToTrash: [],
            selectedRows: [],
            untagIsModalVisible: false,
            untagIDinfo: []
        };
    }

    componentWillMount(){
        this.props.getSettingsForCategory('directories');
    }

    _reloadDirList(){
        this.setState({
            isReloading: true
        });
    }

    _handleChangeDirectory(newDir, dirList){
        const { currentToplevelDirectory, currentPathInfo } = this.state;

        const subpath = newDir.slice(currentToplevelDirectory.length + 1);
        currentPathInfo.subpath = subpath;
        this.setState({
            currentPathInfo,
            currentPath: newDir,
            dirList,
            selectedRows: [],
            isReloading: false
        })
    }

    _handleSelectTopLevelDir(dir) {
        const pathInfo = {
            setting_id: dir.id,
            subpath: ""
        };
        this.setState({
            currentPathInfo: pathInfo,
            currentToplevelDirectory: dir.value,
            currentPath: dir.value
        });
    }

    _handleSelectionChange(selectedRows){
        console.log(selectedRows);
        this.setState({
            selectedRows
        });
    }

    _handleClickTrash(evt){
        let itemsToTrash = [];
        if(evt.currentTarget.tagName === "BUTTON"){
            itemsToTrash = [...this.state.selectedRows];
        } else {
            const item = evt.currentTarget.getAttribute('data-item-name');
            itemsToTrash = [item];
        }

        this.setState({
            isTrashVisible: true,
            itemsToTrash
        });
    }

    _handleTrashComplete(){
        this.setState({
            isReloading: true,
            isTrashVisible: false,
            itemsToTrash: []
        });
    }

    _handleCancelTrash(){
        this.setState({
            isTrashVisible: false,
            itemsToTrash: []
        });
    }

    _handleClickIDFile(filename){
        this.setState({
            idModalFilename: filename,
            isIDModalVisible: true
        });
    }

    _handleIDModalCancel(){
        this.setState({
            isIDModalVisible: false,
            idModalFilename: ""
        });
    }

    _handleIDModalComplete(){
        this.setState({
            isIDModalVisible: false,
            isReloading: true,
            idModalFilename: ""
        });
    }

    _handleSelectVideos(){
        const { dirList } = this.state;

        let selected = [];
        dirList.forEach((item)=>{
            if(item.name.search(this.VIDEO_FILE_REGX) > -1){
                selected.push(item.name);
            }
        });

        this.setState({
            selectedRows: selected
        });
    }

    _handleClickUntag(evt){
        const { dirList } = this.state;

        let filenamesToUntag = [];
        if(evt.currentTarget.tagName === "BUTTON"){
            filenamesToUntag = [...this.state.selectedRows];
        } else {
            const item = evt.currentTarget.getAttribute('data-item-name');
            filenamesToUntag = [item];
        }

        const untagItems = [];
        filenamesToUntag.forEach((filename)=>{
            dirList.forEach((item)=>{
                if(item.name === filename && item.assocData.hasOwnProperty('type')){
                    untagItems.push(item);
                }
            })
        });

        if(untagItems.length > 0){
            this.setState({
                untagIsModalVisible: true,
                untagIDinfo: untagItems
            });
        }
    }

    _handleUntagModalComplete(){
        this.setState({
            isReloading: true,
            untagIsModalVisible: false,
            untagIDinfo: []
        });
    }

    _handleUntagCancel(){
        this.setState({
            untagIsModalVisible: false,
            untagIDinfo: []
        });
    }

    _buildActionColumns(){

        return [
            {
                title: "",
                dataIndex: "",
                render: (text,record)=>{
                    const { assocData } = record;

                    let tag = "";
                    if(record.name.search(this.VIDEO_FILE_REGX) > -1){
                        if(!('type' in assocData)){
                            tag =
                                        <Icon type="tag"/>
                                    ;
                        }
                    }

                    let untag = "";
                    if('type' in assocData){
                        untag =
                                    <Icon type="disconnect" className="ib-filebrowser-media-play"/>
                                ;
                    }
                    return (

                                <Icon type="delete"/>
                             {tag}{untag}

                    );
                }
            }
        ];
    }

    _buildFileManager(){
        const {
            currentPath,
            currentPathInfo,
            currentToplevelDirectory,
            idModalFilename,
            isReloading,
            isIDModalVisible,
            isTrashVisible,
            itemsToTrash,
            selectedRows,
            untagIDinfo,
            untagIsModalVisible
        } = this.state;

        const hasSelected = (selectedRows.length > 0) ? true : false;
        const buttonDisabled = !hasSelected;

        return (

                    <Button
                        type="primary"
                        icon="video-camera"
                        onClick={this._handleSelectVideos.bind(this)}
                    >Select Videos</Button>
                    <Button.Group>
                        <Button type="primary" icon="search" disabled={buttonDisabled}>ID</Button>
                        <Button
                            type="danger"
                            icon="delete"
                            disabled={buttonDisabled}
                            onClick={this._handleClickTrash.bind(this)}
                        >Trash</Button>
                        <Button
                            type="danger"
                            icon="disconnect"
                            disabled={buttonDisabled}
                            onClick={this._handleClickUntag.bind(this)}
                        >Remove ID</Button>
                    </Button.Group>

                <FilesystemBrowser
                    actionColumns={this._buildActionColumns()}
                    forceReload={isReloading}
                    hasCheckboxes={true}
                    initialPath={currentToplevelDirectory}
                    onChangeDirectory={this._handleChangeDirectory.bind(this)}
                    parentHandleSelectChange={this._handleSelectionChange.bind(this)}
                    selectedRowKeys={selectedRows}
                    showDirectories={true}
                    showFiles={true}
                />
                <TrashModal
                    currentPath={currentPath}
                    isVisible={isTrashVisible}
                    itemsToTrash={itemsToTrash}
                    onTrashComplete={this._handleTrashComplete.bind(this)}
                    onCancel={this._handleCancelTrash.bind(this)}
                />
                <IDFileModal
                    key={idModalFilename}
                    isVisible={isIDModalVisible}
                    onIDComplete={this._handleIDModalComplete.bind(this)}
                    onCancel={this._handleIDModalCancel.bind(this)}
                    currentFilename={idModalFilename}
                    currentPathInfo={currentPathInfo}
                    currentToplevelDirectory={currentToplevelDirectory}
                />
                <UntagModal
                    isVisible={untagIsModalVisible}
                    onUntagComplete={this._handleUntagModalComplete.bind(this)}
                    onCancel={this._handleUntagCancel.bind(this)}
                    itemsToUntag={untagIDinfo}
                />

        );
    }

    _buildDirectoryButtons(){
        const { toplevelDirectories } = this.props;
        const { currentToplevelDirectory } = this.state;

        const buttonList = [];
        toplevelDirectories.forEach((dir)=>{
            const activeClass = (dir.value === currentToplevelDirectory) ? "ib-filemanager-button ib-filemanager-button-active" : "ib-filemanager-button";
            buttonList.push(
                <Button
                    key={dir.key}
                    onClick={this._handleSelectTopLevelDir.bind(this, dir)}
                    className={activeClass}
                >{dir.key}</Button>
            );
        });

        return (<Button.Group>{buttonList}</Button.Group>);
    }

    render() {
        const { currentToplevelDirectory } = this.state;

        let directoryButtons = this._buildDirectoryButtons();
        let output = "";
        if(currentToplevelDirectory){
            output = this._buildFileManager();
        }
        return (

                    {directoryButtons}

                {output}

        );
    }
}

const mapStateToProps = (state)=>{
    const { settings } = state;

    return {
        toplevelDirectories: settings.settings.directories
    };
}

const mapDispatchToProps = (dispatch)=>{
    return {
        getSettingsForCategory: (category)=>dispatch(getSettingsForCategory(category))
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(FileManager);<|endoftext|>


<commit_before>const Timer = React.createClass({
  getInitialState: function () {
    return { secondsToWait: this.props.secondsToWait };
  },
  runTimer: function () {
    let timer = setInterval(() => {
      if (this.state.secondsToWait === 0) clearInterval(timer);

      this.setState({ secondsToWait: this.state.secondsToWait - 1 });
    }, 1000);
  },
  componentDidMount: function () {
    this.runTimer();
  },
  render: function () {
    if (this.state.secondsToWait > 0) {
      let unit = (this.state.secondsToWait > 1)? 'seconds': 'second';
      return
 Waiting {this.state.secondsToWait} {unit}...
;
    }

    return
Done!
;
  }
});
<commit_msg>Correct the timer element issue<commit_after>const Timer = React.createClass({
  getInitialState: function () {
    return { secondsToWait: this.props.secondsToWait };
  },
  runTimer: function () {
    this.setState({
      timer: setInterval(() => {
        if (this.state.secondsToWait === 0) clearInterval(timer);

        this.setState({ secondsToWait: this.state.secondsToWait - 1 });
      }, 1000)
    });
  },
  stopTimer: function () {
    clearInterval(this.state.timer);
  },
  componentDidMount: function () {
    this.runTimer();
  },
  componentWillUnmount: function () {
    this.stopTimer();
  },
  render: function () {
    if (this.state.secondsToWait > 0) {
      let unit = (this.state.secondsToWait > 1)? 'seconds': 'second';
      return
 Waiting {this.state.secondsToWait} {unit}...
;
    }

    return
Done!
;
  }
});
<|endoftext|>


<commit_before>"use strict";

const { Type } = require("typelib");
const { assertType } = require("misc");
const singleton = require("singleton");

/* Keep reference to ServiceMgr instance in order to get rid of
 * circular dependency that would happen if we were to
 * require manager in this file. */
let serviceMgr;

class State extends Type {
    constructor(data) {
        super();

        if (data) {
            this.set(data);
        }
    }

    static async validate(event, data) {
        assertType(data.state, "data.state", "string");
        assertType(data.uses, "data.uses", "object");
        assertType(data.provides, "data.provides", "object");
    }

    static setManager(mgr) {
        serviceMgr = mgr;
    }

    static get serviceName() {
        return serviceMgr.serviceName;
    }

    static get typeName() {
        return "state";
    }

    static async _getMb() {
        return serviceMgr.msgBus;
    }

    /** Implement read operations without database backend.
     * Since every service only has one state the implementation is trivial.
     * @override
     */
    static async findMany() {
        return [ instance ];
    }

    /** Implement read operations without database backend
     * Since every service only has one state the implementation is trivial.
     * @override
     */
    static async findOne() {
        return instance;
    }

    /** Restart service
     * @public
     * @return {undefined}
     */
    restart(...args) {
        return serviceMgr.restart(...args);
    }

    /** Distributes a snapshot event which only sets newdata
     * @public
     * @param {Array} parentIds Parent ids
     * @return {Object} message sent
     */
    async notifyUpdate(parentIds = []) {
        return this.notifyEvent("snapshot", null, this.serialize(), parentIds);
    }
}

module.exports = singleton(State);
<commit_msg>service: A fix for the last commit<commit_after>"use strict";

const { Type } = require("typelib");
const { assertType } = require("misc");
const singleton = require("singleton");

/* Keep reference to ServiceMgr instance in order to get rid of
 * circular dependency that would happen if we were to
 * require manager in this file. */
let serviceMgr;

class State extends Type {
    constructor(data) {
        super();

        if (data) {
            this.set(data);
        }
    }

    static async validate(event, data) {
        assertType(data.state, "data.state", "string");
        assertType(data.uses, "data.uses", "object");
        assertType(data.provides, "data.provides", "object");
    }

    static setManager(mgr) {
        serviceMgr = mgr;
    }

    static get serviceName() {
        return serviceMgr.serviceName;
    }

    static get typeName() {
        return "state";
    }

    static async _getMb() {
        return serviceMgr.msgBus;
    }

    /** Implement read operations without database backend.
     * Since every service only has one state the implementation is trivial.
     * @override
     */
    static async findMany() {
        return [ State.instance ];
    }

    /** Implement read operations without database backend
     * Since every service only has one state the implementation is trivial.
     * @override
     */
    static async findOne() {
        return State.instance;
    }

    /** Restart service
     * @public
     * @return {undefined}
     */
    restart(...args) {
        return serviceMgr.restart(...args);
    }

    /** Distributes a snapshot event which only sets newdata
     * @public
     * @param {Array} parentIds Parent ids
     * @return {Object} message sent
     */
    async notifyUpdate(parentIds = []) {
        return this.notifyEvent("snapshot", null, this.serialize(), parentIds);
    }
}

module.exports = singleton(State);
<|endoftext|>


<commit_before>import { h, Component } 				from 'preact/preact';
//import ShallowCompare	 				from 'shallow-compare/index';

import NavSpinner						from 'com/nav-spinner/spinner';
import NavLink 							from 'com/nav-link/link';
import SVGIcon 							from 'com/svg-icon/icon';
import IMG2 							from 'com/img2/img2';

import ContentFooterButtonComments		from 'com/content-footer/footer-button-comments';

import ContentCommentsMarkup			from 'comments-markup';

import ContentCommentsComment			from 'comments-comment';

import $Note							from '../../shrub/js/note/note';
import $Node							from '../../shrub/js/node/node';

export default class ContentComments extends Component {
	constructor( props ) {
		super(props);

		this.state = {
			'comments': null,
			'tree': null,
			'authors': null,

			'newcomment': null,
		};

		this.onPublish = this.onPublish.bind(this);
	}

	componentWillMount() {
		this.getComments(this.props.node);
	}

	genComment() {
		return {
			'parent': 0,
			'node': this.props.node.id,
			'author': this.props.user.id,
			'body': '',
			'love': 0,
		};
	}

	getComments( node ) {
		$Note.Get( node.id )
		.then(r => {
			// Has comments
			if ( r.note && r.note.length ) {
				this.setState({ 'comments': r.note, 'tree': null, 'authors': null });
			}
			// Does not have comments
			else if ( r.note ) {
				this.setState({ 'comments': [], 'tree': null, 'authors': null });
			}

			// Async first
			this.getAuthors().then( rr => {
				this.setState({'newcomment': this.genComment()});
			});

			// Sync last
			this.setState({'tree': this.buildTree()});
		})
		.catch(err => {
			this.setState({ 'error': err });
		});
	}

	buildTree() {
		var comments = this.state.comments;

		// Only supports single level deep trees
		var tree = {};
		for ( var idx = 0; idx < comments.length; idx++ ) {
			if ( comments[idx].parent === 0 ) {
				tree[comments[idx].id] = {
					'node': comments[idx],
				};
			}
			else if ( comments[idx].parent && tree[comments[idx].parent] ) {
				if (!tree[comments[idx].parent].child) {
					tree[comments[idx].parent].child = {};
				}

				tree[comments[idx].parent].child[comments[idx].id] = {
					'node': comments[idx],
				};
			}
			else {
				console.log('[Comments] Unable to find parent for '+comments[idx].id);
			}
		}

		return tree;
	}

	getAuthors() {
		var user = this.props.user;
		var comments = this.state.comments;

		if ( comments ) {
			var Authors = [];
			// Extract a list of all authors from comments
			for ( var idx = 0; idx < comments.length; idx++ ) {
				Authors.push(comments[idx].author);
			}
			// Add self (in case we start making comments
			if ( user && user.id ) {
				Authors.push(user.id);
			}
			// http://stackoverflow.com/a/23282067/5678759
			// Remove Duplicates
			Authors = Authors.filter(function(item, i, ar){ return ar.indexOf(item) === i; });

			// Fetch authors

			return $Node.GetKeyed( Authors )
			.then(r => {
				this.setState({ 'authors': r.node });
			})
			.catch(err => {
				this.setState({ 'error': err });
			});
		}
	}

	renderComments( tree, indent = 0 ) {
		var user = this.props.user;
		var authors = this.state.authors;

		var ret = [];

		for ( var item in tree ) {
			var comment = tree[item].node;
			var author = authors[comment.author];
			ret.push(<ContentCommentsComment user={user} comment={comment} author={author} indent={indent} />);

			if ( tree[item].child ) {
				ret.push(
{this.renderComments(tree[item].child, indent+1)}
);
			}
		}

		return ret;
	}

	renderPostNew() {
		var user = this.props.user;
		var authors = this.state.authors;
		var comment = this.state.newcomment;
		var author = authors[comment.author];

		return
<ContentCommentsComment user={user} comment={comment} author={author} indent={0} editing publish onpublish={this.onPublish}/>
;
	}

	onPublish( e ) {
		var node = this.props.node;
		var newcomment = this.state.newcomment;

		$Note.Add( newcomment.parent, newcomment.node, newcomment.body )
		.then(r => {
			if ( r.note ) {
				var comment = Object.assign({'id': r.note},	newcomment);

				// TODO: insert properly
				this.state.comments.push(comment);

				// Reset newcomment
				newcomment.parent = 0;
				newcomment.body = '';

				this.setState({'tree': this.buildTree()});
			}
			else {
				this.setState({ 'error': err });
			}
		})
		.catch(err => {
			this.setState({ 'error': err });
		});
	}

	render( props, {comments, tree, authors, newcomment} ) {
		var node = props.node;
		var user = props.user;
		var path = props.path;
		var extra = props.extra;

//		var FooterItems = [];
//		if ( !props['no_comments'] )
//			FooterItems.push(<ContentFooterButtonComments href={path} node={node} wedge_left_bottom />);

		var ShowComments = <NavSpinner />;
		if ( comments && tree && authors ) {
			if ( comments.length )
				ShowComments = this.renderComments(tree);
			else
				ShowComments =

No Comments.

;
		}

		var ShowPostNew = null;
		if ( user && user['id'] && newcomment ) {
			ShowPostNew = this.renderPostNew();
		}

		return (

COMMENTS

				{ShowComments}
				{ShowPostNew}

		);
	}

//

//

//

//

//			  			{FooterItems}
//

//

}
<commit_msg>now with signin to comment message<commit_after>import { h, Component } 				from 'preact/preact';
//import ShallowCompare	 				from 'shallow-compare/index';

import NavSpinner						from 'com/nav-spinner/spinner';
import NavLink 							from 'com/nav-link/link';
import SVGIcon 							from 'com/svg-icon/icon';
import IMG2 							from 'com/img2/img2';

import ContentFooterButtonComments		from 'com/content-footer/footer-button-comments';

import ContentCommentsMarkup			from 'comments-markup';

import ContentCommentsComment			from 'comments-comment';

import $Note							from '../../shrub/js/note/note';
import $Node							from '../../shrub/js/node/node';

export default class ContentComments extends Component {
	constructor( props ) {
		super(props);

		this.state = {
			'comments': null,
			'tree': null,
			'authors': null,

			'newcomment': null,
		};

		this.onPublish = this.onPublish.bind(this);
	}

	componentWillMount() {
		this.getComments(this.props.node);
	}

	genComment() {
		return {
			'parent': 0,
			'node': this.props.node.id,
			'author': this.props.user.id,
			'body': '',
			'love': 0,
		};
	}

	getComments( node ) {
		$Note.Get( node.id )
		.then(r => {
			// Has comments
			if ( r.note && r.note.length ) {
				this.setState({ 'comments': r.note, 'tree': null, 'authors': null });
			}
			// Does not have comments
			else if ( r.note ) {
				this.setState({ 'comments': [], 'tree': null, 'authors': null });
			}

			// Async first
			this.getAuthors().then( rr => {
				this.setState({'newcomment': this.genComment()});
			});

			// Sync last
			this.setState({'tree': this.buildTree()});
		})
		.catch(err => {
			this.setState({ 'error': err });
		});
	}

	buildTree() {
		var comments = this.state.comments;

		// Only supports single level deep trees
		var tree = {};
		for ( var idx = 0; idx < comments.length; idx++ ) {
			if ( comments[idx].parent === 0 ) {
				tree[comments[idx].id] = {
					'node': comments[idx],
				};
			}
			else if ( comments[idx].parent && tree[comments[idx].parent] ) {
				if (!tree[comments[idx].parent].child) {
					tree[comments[idx].parent].child = {};
				}

				tree[comments[idx].parent].child[comments[idx].id] = {
					'node': comments[idx],
				};
			}
			else {
				console.log('[Comments] Unable to find parent for '+comments[idx].id);
			}
		}

		return tree;
	}

	getAuthors() {
		var user = this.props.user;
		var comments = this.state.comments;

		if ( comments ) {
			var Authors = [];
			// Extract a list of all authors from comments
			for ( var idx = 0; idx < comments.length; idx++ ) {
				Authors.push(comments[idx].author);
			}
			// Add self (in case we start making comments
			if ( user && user.id ) {
				Authors.push(user.id);
			}
			// http://stackoverflow.com/a/23282067/5678759
			// Remove Duplicates
			Authors = Authors.filter(function(item, i, ar){ return ar.indexOf(item) === i; });

			// Fetch authors

			return $Node.GetKeyed( Authors )
			.then(r => {
				this.setState({ 'authors': r.node });
			})
			.catch(err => {
				this.setState({ 'error': err });
			});
		}
	}

	renderComments( tree, indent = 0 ) {
		var user = this.props.user;
		var authors = this.state.authors;

		var ret = [];

		for ( var item in tree ) {
			var comment = tree[item].node;
			var author = authors[comment.author];
			ret.push(<ContentCommentsComment user={user} comment={comment} author={author} indent={indent} />);

			if ( tree[item].child ) {
				ret.push(
{this.renderComments(tree[item].child, indent+1)}
);
			}
		}

		return ret;
	}

	renderPostNew() {
		var user = this.props.user;
		var authors = this.state.authors;
		var comment = this.state.newcomment;
		var author = authors[comment.author];

		return
<ContentCommentsComment user={user} comment={comment} author={author} indent={0} editing publish onpublish={this.onPublish}/>
;
	}

	onPublish( e ) {
		var node = this.props.node;
		var newcomment = this.state.newcomment;

		$Note.Add( newcomment.parent, newcomment.node, newcomment.body )
		.then(r => {
			if ( r.note ) {
				var comment = Object.assign({'id': r.note},	newcomment);

				// TODO: insert properly
				this.state.comments.push(comment);

				// Reset newcomment
				newcomment.parent = 0;
				newcomment.body = '';

				this.setState({'tree': this.buildTree()});
			}
			else {
				this.setState({ 'error': err });
			}
		})
		.catch(err => {
			this.setState({ 'error': err });
		});
	}

	render( props, {comments, tree, authors, newcomment} ) {
		var node = props.node;
		var user = props.user;
		var path = props.path;
		var extra = props.extra;

//		var FooterItems = [];
//		if ( !props['no_comments'] )
//			FooterItems.push(<ContentFooterButtonComments href={path} node={node} wedge_left_bottom />);

		var ShowComments = <NavSpinner />;
		if ( comments && tree && authors ) {
			if ( comments.length )
				ShowComments = this.renderComments(tree);
			else
				ShowComments =

No Comments.

;
		}

		var ShowPostNew = null;
		if ( user && user['id'] && newcomment ) {
			ShowPostNew = this.renderPostNew();
		}
		else {
			ShowPostNew =

Sign in to post a comment

;
		}

		return (

COMMENTS

				{ShowComments}
				{ShowPostNew}

		);
	}

//

//

//

//

//			  			{FooterItems}
//

//

}
<|endoftext|>


<commit_before>const { Command } = require('discord.js-commando')
const { escapeMarkdown } = require('discord.js')
const { oneLineCommaListsAnd } = require('common-tags')
const si = require('systeminformation')
const moment = require('moment')
require('moment-duration-format')

module.exports = class UserInfoCommand extends Command {
  constructor (client) {
    super(client, {
      name: 'userinfo',
      memberName: 'userinfo',
      group: 'information',
      description: 'Displays info about a user.',
      aliases: [
        'memberinfo'
      ],
      clientPermissions: [
        'EMBED_LINKS'
      ],
      throttling: {
        usages: 2,
        duration: 10
      },
      args: [
        {
          key: 'user',
          prompt: 'What user would you like to lookup?',
          type: 'member'
        }
      ],
      guildOnly: true
    })
  }

  run (message, args) {
    let user = args.user.user

    var userColor = (args.user).displayHexColor
    if (userColor === '#000000') { userColor = 0x7289DA } else { userColor = Number(userColor.replace('#', '0x')) }

    var userStatus
    if (user.presence.activity !== null) {
      if (user.presence.activity.type === 'PLAYING') {
        userStatus = `Playing **${escapeMarkdown(user.presence.activity.name)}**`
      } else if (user.presence.activity.type === 'STREAMING') {
        userStatus = `Streaming **${escapeMarkdown(user.presence.activity.name)}**`
      } else if (user.presence.activity.type === 'LISTENING') {
        userStatus = `Listening to **${escapeMarkdown(user.presence.activity.name)}**`
      } else if (user.presence.activity.type === 'WATCHING') {
        userStatus = `Watching **${escapeMarkdown(user.presence.activity.name)}**`
      }
      if (user.presence.activity.url !== null) { userStatus = `[${userStatus}](${user.presence.activity.url})` }
    } else {
      userStatus = '*User is not doing anything at this time.*'
    }

    var userRoles
    if (args.user.roles.size > 1) {
      userRoles = oneLineCommaListsAnd`${args.user.roles.array().slice(1).sort((a, b) => a.comparePositionTo(b)).reverse().map(role => `**\`${role.name}\`**`)}`
    } else {
      userRoles = 'N/A'
    }

    message.embed({
      author: { name: this.client.user.tag, icon_url: this.client.user.displayAvatarURL() },
      footer: { text: message.author.tag, icon_url: message.author.displayAvatarURL() },
      timestamp: new Date(),
      title: `Information for ${escapeMarkdown(user.tag)}${user.bot === true ? ' **[BOT]**' : ''}`,
      description: userStatus,
      thumbnail: { url: user.avatarURL() !== null ? user.avatarURL() : 'http://cdn.discordapp.com/embed/avatars/0.png' },
      fields: [
        {
          'name': '📇 Tag',
          'value': escapeMarkdown(user.tag),
          'inline': true
        },
        {
          'name': '🌐 ID',
          'value': user.id,
          'inline': true
        },
        {
          'name': '📱 Status',
          'value': user.presence.status,
          'inline': true
        },
        {
          'name': '🤖 Bot',
          'value': user.bot,
          'inline': true
        },
        {
          'name': `🔧 Account Created - (${moment(user.createdAt).fromNow()})`,
          'value': `${moment(user.createdAt).format('llll')} ${si.time().timezone}`,
          'inline': false
        },
        {
          'name': `📥 Joined Guild - (${moment(args.user.joinedAt).fromNow()})`,
          'value': `${moment(args.user.joinedAt).format('llll')} ${si.time().timezone}`,
          'inline': false
        },
        {
          'name': `🔖 Roles - (${args.user.roles.size - 1})`,
          'value': userRoles,
          'inline': false
        }
      ],
      color: userColor
    })
  }
}
<commit_msg>Commands: Enhancements to userinfo.<commit_after>const { Command } = require('discord.js-commando')
const { escapeMarkdown } = require('discord.js')
const { oneLineCommaListsAnd } = require('common-tags')
const si = require('systeminformation')
const moment = require('moment')
require('moment-duration-format')

module.exports = class UserInfoCommand extends Command {
  constructor (client) {
    super(client, {
      name: 'userinfo',
      memberName: 'userinfo',
      group: 'information',
      description: 'Displays info about a user.',
      aliases: [
        'memberinfo'
      ],
      clientPermissions: [
        'EMBED_LINKS'
      ],
      throttling: {
        usages: 2,
        duration: 10
      },
      args: [
        {
          key: 'user',
          prompt: 'What user would you like to lookup?',
          type: 'member'
        }
      ],
      guildOnly: true
    })
  }

  run (message, args) {
    let user = args.user.user

    var userColor = (args.user).displayHexColor
    if (userColor === '#000000') { userColor = 0x7289DA } else { userColor = Number(userColor.replace('#', '0x')) }

    var userStatus
    if (user.presence.activity !== null) {
      if (user.presence.activity.type === 'PLAYING') {
        userStatus = `Playing **${escapeMarkdown(user.presence.activity.name)}**`
      } else if (user.presence.activity.type === 'STREAMING') {
        userStatus = `Streaming **${escapeMarkdown(user.presence.activity.name)}**`
      } else if (user.presence.activity.type === 'LISTENING') {
        userStatus = `Listening to **${escapeMarkdown(user.presence.activity.name)}**`
      } else if (user.presence.activity.type === 'WATCHING') {
        userStatus = `Watching **${escapeMarkdown(user.presence.activity.name)}**`
      }
      if (user.presence.activity.url !== null) { userStatus = `[${userStatus}](${user.presence.activity.url})` }
    } else {
      userStatus = '*User is not doing anything at this time.*'
    }

    var userRoles
    if (args.user.roles.size > 1) {
      userRoles = oneLineCommaListsAnd`${args.user.roles.array().slice(1).sort((a, b) => a.comparePositionTo(b)).reverse().map(role => `**\`${role.name}\`**`)}`
    } else {
      userRoles = 'N/A'
    }

    message.embed({
      author: { name: this.client.user.tag, icon_url: this.client.user.displayAvatarURL() },
      footer: { text: message.author.tag, icon_url: message.author.displayAvatarURL() },
      timestamp: new Date(),
      title: `Information for ${escapeMarkdown(user.tag)}${user.bot === true ? ' **[BOT]**' : ''}`,
      description: userStatus,
      thumbnail: { url: user.avatarURL() !== null ? user.avatarURL() : 'http://cdn.discordapp.com/embed/avatars/0.png' },
      fields: [
        {
          'name': '📇 Tag',
          'value': escapeMarkdown(user.tag),
          'inline': true
        },
        {
          'name': '🌐 ID',
          'value': user.id,
          'inline': true
        },
        {
          'name': '📱 Status',
          'value': user.presence.status,
          'inline': true
        },
        {
          'name': '🔎 Identity',
          'value': user.bot === true ? 'Bot' : 'User',
          'inline': true
        },
        {
          'name': `🔧 Account Created - (${moment(user.createdAt).fromNow()})`,
          'value': `${moment(user.createdAt).format('llll')} ${si.time().timezone}`,
          'inline': false
        },
        {
          'name': `📥 Joined Guild - (${moment(args.user.joinedAt).fromNow()})`,
          'value': `${moment(args.user.joinedAt).format('llll')} ${si.time().timezone}`,
          'inline': false
        },
        {
          'name': `🔖 Roles - (${args.user.roles.size - 1})`,
          'value': userRoles,
          'inline': false
        }
      ],
      color: userColor
    })
  }
}
<|endoftext|>


<commit_before>const he = require('he');
const Sentry = require('@sentry/node');

const LyricBase = require('../include/lyric-base');

const keyword = 'mojim';

class Lyric extends LyricBase {
  get_lang(url) {
    const pattern = /com\/([a-z]{2})y/;
    return this.get_first_group_by_pattern(url, pattern);
  }

  filter_ad(lyric) {
    const separator = '
';
    const lines = lyric.split(separator);
    const filtered = lines.filter((line) => !line.includes('Mojim.com'));
    return filtered.join(separator);
  }

  filter_thank(lyric) {
    const pattern = /
.*?<\/ol>/;
    return lyric.replace(pattern, '');
  }

  async find_lyric(url, html) {
    const prefix = "<dt id='fsZx2'";
    const suffix = '
';
    const lyricPrefix = '

';

    const block = this.find_string_by_prefix_suffix(html, prefix, suffix, true);
    let lyric = this.find_string_by_prefix_suffix(
      block,
      lyricPrefix,
      suffix,
      false
    );
    lyric = this.filter_ad(lyric);
    lyric = this.filter_thank(lyric);
    lyric = lyric.replace(/
/g, '\n');
    lyric = this.sanitize_html(lyric);

    this.lyric = lyric;
    return true;
  }

  async find_info(url, html) {
    const prefix = " {
      scope.setLevel('info');
      scope.setExtra(block);
      Sentry.captureMessage('Mojim.com info block');
    });

    const keys = {
      lyricist: '作詞',
      composer: '作曲',
      arranger: '編曲',
    };

    const lang = this.get_lang(url);
    if (lang === 'cn') {
      keys.lyricist = '作词';
      keys.arranger = '编曲';
    } else if (lang === 'us') {
      keys.lyricist = 'Lyricist';
      keys.composer = 'Composer';
      keys.arranger = 'Arranger';
    }

    const patterns = {
      title: "
(.+?)<br",
      artist: "
(.+?)<br",
      lyricist: `${keys.lyricist}：(.+?)<br`,
      composer: `${keys.composer}：(.+?)<br`,
      arranger: `${keys.arranger}：(.+?)<br`,
    };

    this.fill_song_info(block, patterns);
  }

  async parse_page() {
    let { url } = this;

    if (url.startsWith('https://')) {
      url = url.replace(/^https:/, 'http:');
    }

    const raw = await this.get_html(url);
    const html = he.decode(raw);

    this.find_lyric(url, html);
    this.find_info(url, html);

    return true;
  }
}

exports.keyword = keyword;
exports.Lyric = Lyric;

if (require.main === module) {
  (async () => {
    const url = 'https://mojim.com/twy105842x18x5.htm';
    const object = new Lyric(url);
    const lyric = await object.get();
    console.log(lyric);
  })();
}
<commit_msg>remove he in mojim<commit_after>const Sentry = require('@sentry/node');

const LyricBase = require('../include/lyric-base');

const keyword = 'mojim';

class Lyric extends LyricBase {
  get_lang(url) {
    const pattern = /com\/([a-z]{2})y/;
    return this.get_first_group_by_pattern(url, pattern);
  }

  filter_ad(lyric) {
    const separator = '
';
    const lines = lyric.split(separator);
    const filtered = lines.filter((line) => !line.includes('Mojim.com'));
    return filtered.join(separator);
  }

  filter_thank(lyric) {
    const pattern = /
.*?<\/ol>/;
    return lyric.replace(pattern, '');
  }

  async find_lyric(url, html) {
    const prefix = "<dt id='fsZx2'";
    const suffix = '
';
    const lyricPrefix = '

';

    const block = this.find_string_by_prefix_suffix(html, prefix, suffix, true);
    let lyric = this.find_string_by_prefix_suffix(
      block,
      lyricPrefix,
      suffix,
      false
    );
    lyric = this.filter_ad(lyric);
    lyric = this.filter_thank(lyric);
    lyric = lyric.replace(/
/g, '\n');
    lyric = this.sanitize_html(lyric);

    this.lyric = lyric;
    return true;
  }

  async find_info(url, html) {
    const prefix = " {
      scope.setLevel('info');
      scope.setExtra(block);
      Sentry.captureMessage('Mojim.com info block');
    });

    const keys = {
      lyricist: '作詞',
      composer: '作曲',
      arranger: '編曲',
    };

    const lang = this.get_lang(url);
    if (lang === 'cn') {
      keys.lyricist = '作词';
      keys.arranger = '编曲';
    } else if (lang === 'us') {
      keys.lyricist = 'Lyricist';
      keys.composer = 'Composer';
      keys.arranger = 'Arranger';
    }

    const patterns = {
      title: "
(.+?)<br",
      artist: "
(.+?)<br",
      lyricist: `${keys.lyricist}：(.+?)<br`,
      composer: `${keys.composer}：(.+?)<br`,
      arranger: `${keys.arranger}：(.+?)<br`,
    };

    this.fill_song_info(block, patterns);
  }

  async parse_page() {
    let { url } = this;

    if (url.startsWith('https://')) {
      url = url.replace(/^https:/, 'http:');
    }

    const html = await this.get_html(url);

    this.find_lyric(url, html);
    this.find_info(url, html);

    return true;
  }
}

exports.keyword = keyword;
exports.Lyric = Lyric;

if (require.main === module) {
  (async () => {
    const url = 'https://mojim.com/twy105842x18x5.htm';
    const object = new Lyric(url);
    const lyric = await object.get();
    console.log(lyric);
  })();
}
<|endoftext|>


<commit_before>var sfConstants = require('./../../constants');
angular.module('sf.services.partner', [
  sfConstants,
])

.service("Partner", function(localStorageService) {
  var partner = this;
  var key = "PartnerURL";
  var puidKey = "PartnerUID";
  var partnerKey = "IAMPARTNER";
  partner.setPartnerURL = function(purl) {
    localStorageService.set(key, purl);
  }
  partner.getPartnerURL = function() {
    return localStorageService.get(key);
  }
  partner.setPartnerUID = function(puid) {
    localStorageService.set(puidKey, puid);
  }
  partner.getPartnerUID = function() {
    return localStorageService.get(puidKey);
  };
  partner.setIAmPartner = function(val) {
    localStorageService.set(partnerKey, val);
  };
  partner.IAmPartner = function() {
    var sv = localStorageService.get(partnerKey);
    return sv === 'true';
  };
})

module.exports = 'sf.services.partner';
<commit_msg>Partner service comments<commit_after>var sfConstants = require('./../../constants');
angular.module('sf.services.partner', [
  sfConstants,
])

/*
 * This Partner service provides convenience methods to
 * store things into local storage.
 */
.service("Partner", function(localStorageService) {
  var partner = this;
  var key = "PartnerURL";
  var puidKey = "PartnerUID";
  var partnerKey = "IAMPARTNER";
  partner.setPartnerURL = function(purl) {
    localStorageService.set(key, purl);
  }
  partner.getPartnerURL = function() {
    return localStorageService.get(key);
  }
  partner.setPartnerUID = function(puid) {
    localStorageService.set(puidKey, puid);
  }
  partner.getPartnerUID = function() {
    return localStorageService.get(puidKey);
  };
  partner.setIAmPartner = function(val) {
    localStorageService.set(partnerKey, val);
  };
  partner.IAmPartner = function() {
    var sv = localStorageService.get(partnerKey);
    return sv === 'true';
  };
})

module.exports = 'sf.services.partner';
<|endoftext|>