var $aa = $aa || { 'ready': [] },
mustache = null,
render = null;
function Controllers() { }
function coreController(userID, brand) {
setMustache();
initializeReady();
function setMustache() {
mustache = new itsMustache();
render = mustache.render;
}
function initializeReady() {
if ($aa && $aa.ready && $aa.ready instanceof Array && $aa.ready.length > 0) readyCall($aa.ready);
function readyCall(a) { for (var i = 0, l = a.length; i < l; i++) { if (isFunction(a[i])) a[i](userID, brand); } }
}
}
var TagContainer = function (target, obj, returnCB) {
var events = new EventManager,
template = '',
element = getElementFromString(template),
data = obj.data,
label = obj.label || 'Enter label name',
filterFn = typeof obj.filter === 'function' ? obj.filter : null,
keywordsObj = {},
tagsObj = {},
tagsCount = 0,
limit = !isDefined(obj.limit) ? -1 : obj.limit,
addContainer = undefined,
initialized = false;
function initialize() {
if (data.length > 0) processData(data);
initializeAddContainer();
initialized = true;
target.appendChild(element);
}
function processData(d) {
var fragment = getFragment();
for (var i = 0, l = d.length; i < l; i++) { var t = processTag(d[i]); if (!!t && t instanceof Node) fragment.appendChild(t); }
element.appendChild(fragment);
}
function processTag(name) {
if (!keywordsObj[name]) {
var obj = { 'name': name },
tag = new Tag(obj, update);
tagsObj[name] = obj;
keywordsObj[name] = true;
if (initialized) returnCB(getKeywords());
return tag;
}
return null;
}
function initializeAddContainer() { addContainer = new AddTagContainer(addTag); element.appendChild(addContainer.container); if (!isUnderLimit()) addContainer.hide(); }
function addTag(e) {
loop(e, p);
function p(k, v) {
if (!isUnderLimit()) {
addContainer.hide();
return true;
} else if (isValidTag(v)) {
run(v);
}
return false;
}
function run(v) { var tag = processTag(v); if (tag !== null) insertTag(tag); }
}
function isUnderLimit() { return limit === -1 || tagsCount < limit; }
function isValidTag(e) { return typeof e == 'string' && e.length > 0 && (!filterFn || filterFn(e)); }
function insertTag(tag) { element.insertBefore(tag, addContainer.container); }
function update(e) { if (e.status == false) closeTag(e); }
function closeTag(e) { delete tagsObj[e.name]; if (isUnderLimit()) addContainer.show(); }
function getKeywords() { var a = []; for (var k in keywordsObj) { a.push(k); } return a; }
var AddTagContainer = function (cb) {
var container = undefined,
input = undefined,
button = undefined;
initialize();
this.show = show;
this.hide = hide;
this.container = container;
function initialize() {
button = createButton();
input = createInput();
container = createContainer(button, input);
}
function createButton() { var t = document.createElement('div'); t.className = 'add'; bindButton(t); return t; }
function createInput() { var t = document.createElement('input'); t.type = 'text'; t.placeholder = label; bindInput(t); return t; }
function createContainer(b, i) { var c = document.createElement('div'); c.className = 'addContainer'; c.appendChild(i); c.appendChild(b); return c; }
function bindButton(t) { events.add(t, 'click', updateAction); }
function bindInput(t) { events.add(t, 'focus', bindWindow); events.add(t, 'blur', unbindWindow); }
function bindWindow() { events.add(window, 'keydown', enterCheck); }
function unbindWindow() { events.removeAll(window); }
function enterCheck(e) { if (e.keyCode == '13') updateAction(); }
function updateAction(e) {
preventDefault(e);
var a = input.value.split(/[\s]{0,}[,][\s]{0,}/g);
input.value = '';
cb(a);
}
function show() { container.classList.remove('noDisplay'); }
function hide() { container.classList.add('noDisplay'); }
};
var Tag = function (obj, cb) {
var name = undefined,
tag = undefined,
close = undefined,
className = '';
if (obj) initialize();
return tag;
function initialize() {
name = obj.name;
close = createClose();
tag = createTag(close);
obj.tag = tag;
}
function createTag(c) {
var t = document.createElement('tag'),
p = document.createElement('p');
p.textContent = name;
if (obj.className) className += ' ' + obj.className;
t.className = className;
t.appendChild(p);
t.appendChild(c);
tagsCount++;
return t;
}
function createClose() { var t = document.createElement('div'); t.className = 'close'; bindClose(t); return t; }
function bindClose(t) { events.add(t, 'click', closeTag); }
function unbindClose() { events.removeAll(close); }
function closeTag() { obj.status = false; unbindClose(); tag.parentNode.removeChild(tag); handleKeywords(); tagsCount--; cb(obj); }
function handleKeywords() { delete keywordsObj[name]; if (initialized) returnCB(getKeywords()); }
};
initialize();
};
var ColumnSquares = function (target, dataObj) {
var main = new MainObj,
sizeReference = {
'one': { 'width': 1, 'height': 1 },
'two': { 'width': 2, 'height': 1 },
'three': { 'width': 2, 'height': 2 },
};
function initialize(m, o) {
setSquares(m, o.squares);
setColumns(m);
refreshPlacement(m);
}
function MainObj() {
this.widthMetric = 180;
this.heightMetric = 180;
this.margin = [0, 8, 8, 0];
this.squares = [];
this.columns = [];
this.targetRects = target.getClientRects()[0];
this.maxColumns = getSizeUnits(!!this.targetRects ? this.targetRects.width : 0);
this.template = getTemplate();
}
function Square(o, m, i) {
var drag = null,
element = null;
this.squareIndex = i;
this.column = o.column;
this.columnIndex = null;
this.rects = getColumnSquareRects(o.size);
this.templateData = getTemplateData(o);
this.element = element = getElementFromString(render(m.template, this.templateData));
this.setOffsets = setOffsets;
this.setPositioning = setPositioning;
if (o.element) element.querySelector('content').appendChild(o.element);
//var dC = function(t){ return function(e){ dragEnd(t, e); } }(this);
//setTimeout(setDrag, 1);
function dragStart(e) { }
function dragEnd(t, e) { updateSquarePositioning(e, t.squareIndex); }
function setDrag() { drag = new DragController(element, dragStart, dC); }
function setOffsets() {
return false;
/* Disabling this function for now
drag.setOffsets();
*/
}
function setPositioning(l, t) { setTimeout(setOffsets, 300); element.style.position = 'absolute'; element.style.left = l; element.style.top = t; }
}
function updateSquarePositioning(e, i) {
var t = e.target,
m = main,
square = m.squares[i],
columns = m.columns,
oldColumn = square ? columns[square.column] : null,
matchColumnIndex = getColumnByOffset(t.offsetLeft, t.offsetWidth).i,
matchColumn = columns[matchColumnIndex],
position = matchColumn ? getColumnPosition(t.offsetTop, t.offsetHeight, matchColumn) : null;
switchColumns(square, oldColumn, matchColumn, position);
square.column = matchColumnIndex;
refreshSquaresArray(m);
refreshColumnsArray(m);
refreshPlacement(m);
}
function switchColumns(square, o, n, p) { n.splice(p, 0, o.splice(square.columnIndex, 1)[0]); updateColumnIndexes(o); updateColumnIndexes(n); }
function updateColumnIndexes(a) { for (var i = 0, l = a.length; i < l; i++) { if (a[i] != 0 && a[i] != undefined) a[i].columnIndex = i; } }
function getColumnByOffset(oL, oW) {
var wEnd = oL + oW,
m = main,
width = m.widthMetric,
margin = m.margin,
uMargin = margin[1] + margin[3],
v = 0,
match = false;
for (var i = 0, c = m.columns, l = c.length; i < l; i++) {
var cStart = v,
cEnd = ((i + 1) * width) + uMargin;
if (cStart < wEnd && cEnd > oL) match = getColumnMatch(match, i, cStart - oL);
v = cEnd;
}
return match;
}
function getColumnPosition(oT, oH, c) {
var hEnd = oT + oH,
m = main,
height = m.heightMetric,
margin = m.margin,
uMargin = margin[0] + margin[2],
v = 0,
match = false;
for (var i = 0, l = c.length; i < l; i++) {
var pStart = v,
pEnd = ((i + 1) * height) + uMargin;
if (c[i] !== 0 && pStart < hEnd && pEnd > oT) match = getColumnMatch(match, i, pStart - oT);
v = pEnd;
}
return match == false ? c.length : match.i;
}
function getColumnMatch(match, i, d) { if (d < 0) d = d * -1; if (match == false || match.delta > d) return { 'i': i, 'delta': d }; else return match; }
function refreshSquaresArray(m) {
var columns = m.columns,
a = [],
row = 0,
maxRow = 1;
for (var i = 0; i < maxRow; i++) { processRow(); }
m.squares = a;
function processRow() {
for (var i = 0, l = columns.length; i < l; i++) {
if (row == 0) {
setMaxRow(columns[i].length);
}
var t = columns[i][row];
if (t !== 0 && t !== undefined) pushSquare(a, t);
}
if (row == 0) maxRow++;
row++;
}
function setMaxRow(l) { if (l > maxRow) maxRow = l; }
function pushSquare(a, t) {
var aL = a.length;
t.squareIndex = aL;
a[aL] = t;
}
}
function refreshColumnsArray(m) { m.columns = []; setColumns(m); }
function refreshPlacement(m) {
var c = m.columns,
w = 0,
margin = main.margin,
leftMargin = margin[3],
rightMargin = margin[1];
for (var i = 0, l = c.length; i < l; i++) {
w += leftMargin;
var t = c[i],
lP = null
if (i === 0) lP = w;
else lP = getSquareLeftPositioning(w, i);
refreshColumn(t, i, lP);
w = lP + rightMargin;
}
refreshTarget();
}
function refreshColumn(c, cI, lP) {
var h = 0,
margin = main.margin,
topMargin = margin[0],
bottomMargin = margin[2];
for (var i = 0, l = c.length; i < l; i++) {
var t = c[i],
tP = null;
h += topMargin;
if (i === 0) tP = h;
else tP = getSquareTopPositioning(h, i);
if (t !== 0 && t != undefined) t.setPositioning(lP + 'px', tP + 'px');
h = tP + bottomMargin;
}
}
function refreshTarget() {
var v = 0;
for (var i = 0, c = main.columns, l = c.length; i < l; i++) {
var t = getSizePixels(c[i].length);
if (t > v) v = t;
}
target.style.height = v + 20 + 'px';
}
function getSquareLeftPositioning(v, i) { return (v + main.widthMetric); }
function getSquareTopPositioning(v, i) { return (v + main.heightMetric); }
function getTemplate() {
var h = '
{{ title }}
',
c = '';
classString = 'size="{{ size }}" class="{{^ status }}off{{/ status }}"';
return '' + h + c + '';
}
function setSquares(m, s) { var f = document.createDocumentFragment(); for (var i = 0, l = s.length; i < l; i++) { var sq = new Square(s[i], m, i); m.squares[i] = sq; f.appendChild(sq.element) } target.appendChild(f); }
function setColumns(m) {
var max = m.maxColumns,
s = m.squares,
c = m.columns;
populateEmptyColumns(c, max);
processSquares(s, c);
function populateEmptyColumns(c, max) { for (var i = 0; i < max; i++) { c[i] = []; } }
function processSquares(s, c) { for (var i = 0, l = s.length; i < l; i++) { addToColumn(c, s[i], s[i].column); } }
function addToColumn(c, o, i) { var p = findPlace(c, o, i); if (p != false) { c[i].push(o); stretchOut(c, i, o.rects); } }
function findPlace(c, o, i) {
var w = i + o.rects.width - 1,
s = c[i] != undefined,
e = c[w] != undefined;
if (s && e) {
var sV = c[i].length;
var eV = c[w].length;
var d = sV - eV;
if (d < 0) fillZeros(c[i], d * -1);
else if (d > 0) fillZeros(c[w], d);
return true;
}
else return false;
}
function fillZeros(t, c) { for (var i = 0; i < c; i++) { t.push(0); } }
function isValidPlace(c, i) { return c[i] != undefined; }
}
function stretchOut(c, cI, r) {
var tCol = c[cI],
tI = tCol.length - 1,
h = r.height,
w = r.width;
for (var i = tI, l = tI + h; i < l; i++) {
if (i != tI) tCol[i] = 0;
if (w > 1) stretchRight(c, cI + 1, i, w - 1);
}
tCol[tI].columnIndex = tI;
}
function stretchRight(c, cI, i, w) { for (var l = cI + w; cI < l; cI++) { c[cI][i] = 0; } }
function getTemplateData(o) { return { 'title': o.title, 'status': o.status === undefined ? true : o.status, 'size': o.size }; }
function getSizeUnits(px) { return Math.floor(px / 180); }
function getSizePixels(units) { return Math.floor(units * 180); }
function getColumnSquareRects(s) { return sizeReference[s]; }
initialize(main, dataObj);
};
var DragController = function (t, dragStart, dragEnd, dragMove, config) {
var events = new EventManager,
startX = null,
startY = null,
cX = null,
cY = null,
oL = null,
oT = null,
scrollTop = null,
scrollEvent = undefined,
scrollTimer = null,
xOnly = config && config.xOnly ? true : false,
yOnly = config && config.yOnly ? true : false,
inBounds = config && config.inBounds ? true : false,
autoSet = config && config.autoSet ? true : false,
parentNode = t.parentNode,
parentRects = null,
targetRects = null,
originalTransition = getOriginalTransition();
this.setOffsets = setOffsets;
this.exit = exit;
setOffsets();
bindTarget();
function mouseDownAction(e) { stopDefaultAction(e); startDrag(e); }
function mouseUpAction(e) { stopDefaultAction(e); endDrag(e); }
function stopDefaultAction(e) { if (e && e.preventDefault) e.preventDefault(); }
function startDrag(e) { setScrollTop(); setStartPoint(e); setTargetStyle(); bindWindow(); bindScroll(); dragStart(e); }
function endDrag(e) { unbindWindow(); removeTargetStyle(); unbindScroll(); dragEnd(e); if (autoSet) setOffsets(); }
function scrollAction(e) { setDifference(getFauxEvent()); }
function setScrollTimer() { if (scrollTimer) clearTimeout(scrollTimer); scrollTimer = setTimeout(scrollAction, 100); }
function setOffsets() { oL = t.offsetLeft; oT = t.offsetTop; }
function setStartPoint(e) { var oT = (e.target == t) ? t : e.target.parentNode; setStartPointX(e, oT); setStartPointY(e, oT); }
function setStartPointX(e, oT) { startX = e.clientX; }
function setStartPointY(e, oT) { startY = e.clientY; }
function setScrollTop() { scrollTop = window.scrollY; }
function setTargetStyle() { t.style.zIndex = '10000'; t.setAttribute('cssTransition', 'none'); }
function setDifference(e) { setRects(); setPosition(e, getLeftValue(e), getTopValue(e)); }
function setPosition(e, left, top) { t.style.position = 'absolute'; left = getLeftPosition(left + oL); top = getTopPosition(top + oT); if (!dragMove || (dragMove && dragMove(e, left, top) !== false)) { setLeftPosition(left); setTopPosition(top); } }
function setLeftPosition(left) { if (left !== null) t.style.left = left + 'px'; }
function setTopPosition(top) { if (top !== null) t.style.top = top + 'px'; }
function getLeftPosition(left) {
if ((!inBounds && !yOnly) || (left >= 0 && left + targetRects.width <= parentRects.width)) return left;
else if (yOnly) return null;
else if (left < 0) return 0;
else if (left > parentRects.width) return parentRects.width - targetRects.width;
}
function getTopPosition(top) {
if ((!inBounds && !xOnly) || (top >= 0 && top + targetRects.height <= parentRects.height)) return top;
else if (xOnly) return null;
else if (top < 0) return 0;
else if (top > parentRects.height) return parentRects.height - targetRects.height;
}
function getLeftValue(e) { cX = e.clientX; return cX - startX; }
function getTopValue(e) { cY = e.clientY; return cY - startY - (scrollTop - window.scrollY); }
function getFauxEvent() { return { 'clientX': cX, 'clientY': cY }; }
function getOriginalTransition() { return t.getAttribute('cssTransition') || ''; }
function setRects() { setParentRects(); setTargetRects(); }
function setParentRects() { if (!parentRects) parentRects = { 'width': parentNode.offsetWidth, 'height': parentNode.offsetHeight }; }
function setTargetRects() { if (!targetRects) targetRects = { 'width': t.offsetWidth, 'height': t.offsetHeight }; }
function bindTarget() { events.add(t, 'mousedown', mouseDownAction); }
function bindWindow() { wal('mousemove', setDifference); wal('mouseup', mouseUpAction); }
function unbindWindow() { wrl(); }
function bindScroll() { scrollEvent = new MouseScrollEvent(setScrollTimer); }
function unbindScroll() { scrollEvent.unbind(); }
function wal(eT, fn) { events.add(window, eT, fn, 'window'); }
function wrl() { events.removeByTag('window'); }
function removeTargetStyle() { t.style.zIndex = ''; t.setAttribute('cssTransition', originalTransition); }
function exit() { if (events) events.reset(); housekeeping(); }
function housekeeping() {
t = dragStart = dragEnd = dragMove = config = events = startX = startY = null;
cX = cY = oL = oT = scrollTop = scrollEvent = srollTimer = xOnly = yOnly = null;
inBounds = autoSet = parentNode = parentRects = targetRects = originalTransition = null;
}
};
var MouseScrollEvent = function (cb) {
var events = new EventManager;
mozillaBind();
defaultBind();
this.unbind = unbind;
function mozillaBind() { events.add(window, 'DOMMouseScroll', cb); }
function mozillaCB(e, cb) { e.delta = e.detail * -40; cb(e); }
function defaultBind() { events.add(document, 'mousewheel', cb); }
function unbind() { events.reset(); }
};
var CheckboxListContainer = function (target, data, returnCB) {
window['__listCount'] = 0;
var template = '
',
element = getElementFromString(template),
lists = [],
navigation = [],
toggle = null;
refresh();
insertElement();
this.setAll = setAll;
this.unsetAll = unsetAll;
this.reset = unsetAll;
this.getLists = getLists;
this.exit = exit;
function refresh() { forEach(data, processList); }
function insertElement() {
toggle = new ToggleNavigation(element.querySelector('header'), { 'data': lists, 'className': 'toggle' }, updateToggle);
target.appendChild(element);
}
function getLists() { var a = []; forEach(lists, p); return a; function p(t, lists, i) { a[i] = t; } }
function processList(t) { lists.push(new List(t)); }
function updateToggle(e) { forEach(lists, process); function process(t) { if (t.title == e.title) t.show(); else t.hide(); } }
function setAll() { forEach(lists, p); function p(t) { t.setAll(); } }
function unsetAll() { forEach(lists, p); function p(t) { t.unsetAll(); } }
function exitAll() { forEach(lists, p); function p(t) { if (t.exit) t.exit(); } }
function List(o) {
var lO = { 'title': o.title, 'data': o.data, 'api': o.api, 'apiData': o.apiData, 'apiFn': o.apiFn, 'config': o.config },
list = new CheckboxList(element, lO, update),
e = list.getElement();
this.data = o.data;
this.title = o.title;
this.value = o.title;
this.list = list;
this.show = show;
this.hide = hide;
this.exit = exit;
this.setAll = list.setAll;
this.unsetAll = list.unsetAll;
function update(e) { if (returnCB) returnCB({ 'key': o.key, 'value': e }); }
function hide() { e.classList.add('noDisplay'); }
function show() { e.classList.remove('noDisplay'); }
function exit() { if (list && list.exit) list.exit(); list = null; }
}
function exit() { if (lists) exitAll(); if (toggle) toggle.exit(); housekeeping(); }
function housekeeping() { target = data = returnCB = template = element = lists = navigation = toggle = null; }
};
function BenchTimer() {
var s = new Date;
this.check = function () { return new Date - s; };
}
var CheckboxList = function (target, obj, returnCB) {
var search = null,
template = '
{{ title }}:
{{# data }}
{{ . }}{{#data}}{{name}}{{/data}}
{{/ data }}',
element = getElementFromString(render(template, obj)),
listElement = element.querySelector('list'),
listItems = listElement.querySelectorAll('item'),
pagination = null,
pageSize = obj.pageSize || 10,
currentMatches = null,
currentPage = 0,
currentPageCount = 0,
list = [],
dynamicObj = {}
dynamicList = [];
this.getElement = getElement;
this.setAll = setAll;
this.unsetAll = unsetAll;
this.getList = getList;
this.reset = unsetAll;
this.exit = exit;
if (isDefined(obj.data)) initStaticData();
else if (isDefined(obj.api)) initDynamicData();
target.appendChild(element);
function initStaticData() {
forEach(obj.data, processCheckbox);
initializePagination();
initializeSearch(processMatches)
}
function initDynamicData() {
initializeSearch(processDynamic);
}
function initializeSearch(fn) {
if (obj.searchable !== false) {
search = new SearchContainer(element.querySelector('header'), obj, fn);
}
}
function initializePagination() {
var d = obj.data,
dL = d.length;
if (obj.pagination !== false && dL > pageSize) pagination = new Pagination(element, Math.ceil(dL / pageSize), 5, paginationUpdate);
}
function getItemElement(title) {
var template = '
{{ . }}
';
return getElementFromString(render(template, title));
}
function setAll() { forEach(list, p); function p(t) { t.set(); }; }
function unsetAll() { forEach(list, p); function p(t) { t.unset(); }; }
function processMatches(e) {
currentMatches = e;
refresh(getSimpleJSONCopy(e), 1);
}
function paginationUpdate(e, t) {
var d = currentMatches ? getSimpleJSONCopy(currentMatches) : null;
refresh(d, e);
}
function paginationReduce(a, e) {
var s = pageSize * (e - 1),
e = s + pageSize - 1;
forEach(a, reduce, true);
function reduce(t, d, i) { if (i < s || i > e) a.splice(i, 1); }
}
function getPlaceholderArray(c) { var a = []; for (var i = 0; i < c; i++) { a.push({ 'index': i }); } return a; }
function refresh(a, page) {
var arr = isDefined(a) ? a : getPlaceholderArray(list.length),
nLength = arr.length,
cPage = isDefined(page) ? page : 1;
if (currentPage !== cPage) currentPage = cPage;
if (!!pagination) {
if (nLength !== currentPageCount) {
currentPageCount = nLength;
pagination.updatePageCount(nLength, pageSize);
}
paginationReduce(arr, cPage);
}
insertItems(arr);
}
function insertItems(a) {
removeItems();
var f = getFragment();
forEach(a, insert);
listElement.appendChild(f);
function insert(t) { f.appendChild(list[t.index].getElement()) }
}
function removeItems() { forEach(list, remove); function remove(t) { removeChild(listElement, t.getElement()); } }
function processDynamic(e) {
var a = [];
forEach(e, p);
refresh(a, 1);
function p(t, d, i) {
if(!t) return;
if (!dynamicObj[t.title]) {
dynamicObj[t.title] = new Item(t.title, t.value || t.id, list.length, true);
list.push(dynamicObj[t.title]);
if (isDynamicMatch(t.title, t.value)) dynamicObj[t.title].set();
}
a.push({ 'index': dynamicObj[t.title].getIndex() });
}
}
function isDynamicMatch(title, value) {
var isMatch = false;
forEach(obj.apiData, p);
return isMatch;
function p(t) {
if (t === title || t === value) isMatch = true;
return true;
}
}
function isMatch(val) {
var m = false;
loop(obj.apiData, p);
return m;
function p(k, v) {
if (v === val) {
m = true;
return true;
}
}
}
function processCheckbox(t, d, i) {
if (typeof t === 'string') return list.push(new Item(t, t, i));
if (!!t.title && !!t.value) return list.push(new Item(t.title, t.value, i));
if (!!t.data) return list.push(new Item(!!t.data.name ? t.name : t.value, t.value, i));
}
function Item(t, v, i, create) {
var element = create !== true ? listItems[i] : getItemElement(t),
checkbox = new Checkbox(element, checkCB, true),
state = false;
if (isMatch(t)) {
checkbox.set();
state = true;
}
this.getTitle = getTitle;
this.getValue = getValue;
this.getName = getName;
this.getState = getState;
this.getElement = getElement;
this.getIndex = getIndex;
this.unset = function () { state = false; checkbox.unset(); };
this.set = function () { state = true; checkbox.set(); };
this.exit = exit;
function getIndex() { return i; }
function getName() {
console.error('Warning, getName has been depreciated. Please update the calling function to use getTitle or getValue instead!');
return getTitle();
}
function getTitle() { return t; }
function getValue() { return v; }
function getState() { return state; }
function getElement() { return element; }
function checkCB(e) { state = e; notify(); }
function exit() { if (checkbox) checkbox.exit(); checkbox = null; }
};
function getList() { var a = []; forEach(list, p); return a; function p(t) { a.push(t); } }
function getElement() { return element; }
function getSelectedItems() {
var a = []; forEach(list, processItem); return a;
function processItem(t, d, i) { if (t.getState() === true) a.push({ 'title': t.getTitle(), 'value': t.getValue() }); }
}
function notify() { if (returnCB) returnCB(getSelectedItems()); }
function exit() { if (list) exitAll(); if (pagination) pagination.exit(); if (search) search.exit(); housekeeping(); }
function exitAll() { forEach(list, p); function p(t) { if (t.exit) t.exit(); }; }
function housekeeping() { target = obj = returnCB = search = template = element = listElement = listItems = pageSize = currentMatches = list = null; }
};
var Checkbox = function (target, cb, prepend) {
var state = false,
events = new EventManager,
element = document.createElement('m-checkbox');
bindElement(element);
if (prepend !== true) target.appendChild(element);
else prependChild(target, element);
this.unset = unset;
this.set = set;
this.exit = exit;
function toggle() { if (state) unset(); else set(); if (cb) cb(state); }
function set() { state = true; element.classList.add('active'); }
function unset() { state = false; element.classList.remove('active'); }
function bindElement(t) { events.add(t, 'click', toggle); }
function exit() { if (events) events.reset(); target = cb = prepend = state = events = element = null; }
};
var Notification = function (t, html, obj, closeCallback) {
var events = new EventManager,
data = obj.data,
notification = null,
closeButton = null;
if (t && html && obj) initNotification();
this.getElement = getElement;
this.exit = exit;
function initNotification() {
notification = document.createElement('notification');
closeButton = getCloseButton();
if (obj.id) notification.id = obj.id;
if (obj.className) notification.className = obj.className;
if (obj.cssTransition) notification.setAttribute('cssTransition', obj.cssTransition);
insertToTarget()
}
function getElement() { return notification; }
function getCloseButton() { var c = document.createElement('icon'); c.className = 'close'; events.add(c, 'click', closeCallback); return c; }
function insertToTarget() { notification.innerHTML = render(html, data); notification.appendChild(closeButton); t.appendChild(notification); }
function exit() { if (notification !== null) { removeChild(t, notification); cleanUp(); } }
function cleanUp() { if (events) events.reset(); events = data = notification = closeButton = null; }
};
var Alert = function (t, html, obj) {
var events = new EventManager,
data = obj.data,
alert = null,
closeButton = null;
if (t && html && obj) initAlert();
this.getElement = getElement;
this.exit = closeAlert;
function initAlert() {
alert = document.createElement('alert');
closeButton = getCloseButton();
if (obj.id) alert.id = obj.id;
if (obj.className) alert.className = obj.className;
if (obj.cssTransition) alert.setAttribute('cssTransition', obj.cssTransition);
insertToTarget()
}
function getElement() { return alert; }
function getCloseButton() { var c = document.createElement('icon'); c.className = 'close'; events.add(c, 'click', closeAlert); return c; }
function insertToTarget() { alert.innerHTML = render(html, data); alert.appendChild(closeButton); t.appendChild(alert); }
function closeAlert() { if (alert !== null) removeChild(t, alert); cleanUp(); }
function cleanUp() { if (events) events.reset(); alert = null; closeButton = null; }
};
var LoggedInAsNotification = function (id, isAdmin, returnCB) {
var tgt = document.getElementById('loggedInAs'),
p = null,
a = null,
events = new EventManager,
tmpl = new Template,
__id = id;
this.show = show;
this.hide = hide;
this.update = update;
this.exit = exit;
refreshMessage(__id);
show();
function Template() {
this.p = '
Controlling user id: {{ id }}.
';
this.a = '' + (isAdmin ? 'Return to main account' : 'Return to advertisers list') + '';
}
function show() {
tgt.classList.remove("noDisplay");
}
function hide() {
tgt.classList.add("noDisplay");
}
function update(v) {
__id = v;
refreshMessage(v);
show();
}
function refreshMessage(v) {
var f = document.createDocumentFragment();
p = getElementFromString(render(tmpl.p, __id))
a = getElementFromString(tmpl.a);
f.appendChild(p);
f.appendChild(a);
events.reset();
tgt.innerHTML = "";
tgt.appendChild(f);
events.add(a, 'click', returnCB);
}
function exit() {
if (!!events) {
events.reset();
}
hide();
housekeeping();
}
function housekeeping() { events = tmpl = tgt = null; }
};
var Autocomplete = function (target, data, config) {
var events = new EventManager(),
matchesTemplate = '{{# . }}{{ . }}{{/ . }}',
input = null,
matchesContainer = null,
mc = null,
state = false,
selected = -1;
initialize();
this.reset = resetInput();
this.exit = exit;
function initialize() {
config = config || {};
initInput();
initMatchesContainer();
insertChildren();
}
function initInput() { input = document.createElement('input'); input.type = 'text'; setInputConfig(); }
function initMatchesContainer() { matchesContainer = mc = document.createElement('ac-matches'); }
function setInputConfig() { var c = config; if (c.placeholder) input.placeholder = c.placeholder; if (c.className) input.className = c.className; }
function insertChildren() { var t = target, i = input; t.appendChild(i); t.appendChild(mc); events.add(i, 'keyup', keyUpAction); }
function windowClickAction(e) { if (!isTargetChild(e.target, target)) resetInput(); else if (e.target.tagName == 'AC-MATCH') setInput(e.target.textContent); }
function keyUpAction(e) {
var kc = e.keyCode;
switch (kc) {
case 13: enterCheck(e); break;
case 27: resetInput(); break;
case 38: decrementSelected(); break;
case 40: incrementSelected(); break;
default: searchValidation(e); break;
}
}
function enterCheck(e) { if (selected > -1) { e.preventDefault(); setInput(matchesContainer.childNodes[selected].textContent); } }
function resetInput() { mc.innerHTML = ''; input.value = ''; unbindCancelItems(); }
function setInput(v) { mc.innerHTML = ''; input.value = v; unbindCancelItems(); }
function decrementSelected() { if (selected > -1) { unsetSelected(); selected--; setSelected(); } }
function incrementSelected() { if (selected < matchesContainer.childNodes.length - 1) { unsetSelected(); selected++; setSelected(); } }
function searchValidation(e) { var v = e.target.value; if (v !== '') searchAction(v); else resetInput(); }
function searchAction(v) { processMatches(getMatches(v.toLowerCase())); }
function setSelected() { var c = mc.childNodes; if (isValidSelection(c)) c[selected].classList.add('selected'); }
function unsetSelected() { var c = mc.childNodes; if (isValidSelection(c)) c[selected].classList.remove('selected'); }
function getMatches(s) {
var a = [];
for (var i = 0, d = data, l = d.length; i < l; i++) { processMatch(d[i], s, a); }
if (a.length > 0 && state == false) bindCancelItems();
else if (a.length === 0) a = null;
return a;
}
function getMatchValue(t, s) { return t.toLowerCase().indexOf(s) }
function getHighlightedString(m, iO, l) { return m.substring(0, iO) + '' + m.substring(iO, iO + l) + '' + m.substring(iO + l); }
function pushMatchToArray(a, t, iO, l) { if (iO > -1) a.push(getHighlightedString(t, iO, l)); }
function processMatches(m) { if (m != null) mc.innerHTML = render(matchesTemplate, m); else mc.innerHTML = ''; }
function processMatch(t, s, a) { pushMatchToArray(a, t, getMatchValue(t, s), s.length) }
function bindCancelItems() { state = true; events.add(window, 'click', windowClickAction); }
function unbindCancelItems() { state = false; events.removeAll(window); }
function isTargetChild(c, t) { var p = c.parentNode; if (p == t) return true; else if (p != document.body) return isTargetChild(p, t); else return false; }
function isValidSelection(c) { return selected < c.length && selected > -1; }
function exit() {
if (events) events.reset();
target = data = config = events = matchesTemplate = input = matchesContainer = mc = state = selected = null;
}
};
var SearchContainer = function (target, obj, returnCB) {
var events = new EventManager,
template = '',
data = isDefined(obj.data) ? obj.data : [],
config = obj.config || {},
element = getElementFromString(render(template, config)),
input = element.querySelector('input'),
search = new Search(data),
apiTimer = null;
if (returnCB) {
if (data.length > 0) events.add(element, 'keyup', check);
else if (obj.api) events.add(element, 'keyup', apiCheck);
target.appendChild(element);
}
this.exit = exit;
function check(e) { returnCB(search.getMatches(e.target.value)); }
function apiCheck(e) { clearRequest(); setRequest(e.target.value); }
function clearRequest() { clearTimeout(apiTimer); }
function setRequest(v) { apiTimer = setTimeout(request, 600); }
function request() { new HttpRequest('GET', obj.api + '/' + input.value, null, null, 'json', apiCheckCB); }
function apiCheckCB(e) { var v = isDefined(obj.apiFn) ? obj.apiFn(e) : e; returnCB(v); }
function removeElement() { if (element.parentNode === target) target.removeChild(element); }
function exit() { removeElement(); if (events) events.reset(); template = data = config = element = search = events = null; }
};
var Search = function (d) {
var data = getData(d);
this.getMatches = getMatches;
this.update = update;
function Item(title, value, i) {
this.title = title || "";
this.lc = title.toLowerCase();
this.value = value || null;
this.index = i || 0;
}
function update(d) { if (isArray(d)) data = getData(d); }
function getData(d) {
var a = [];
forEach(d, processItem);
return a;
function processItem(t, d, i) {
if (isString(t)) {
a.push(new Item(t, t, i));
} else if (isObject(t)) {
a.push(new Item(t.title, t.value, i));
} else {
console.error("unsupported type", t)
return;
}
}
}
function getMatches(s) {
var lc = s.toLowerCase();
function checkItem(t) {
return t.lc.indexOf(lc) > -1;
}
return data.filter(checkItem);
}
};
/*
Pagination Variable declarations
--------------------------------
target Element reference - Pagination will be inserted to this reference
pages Number
setLength Number
*/
var Pagination = function (target, pageCount, setLength, returnCB) {
var events = new EventManager,
template = new TemplateObj().index,
currentPage = 1,
currentSet = 1,
pages = Math.ceil(pageCount),
totalSets = null,
obj = null,
paginationElement = null,
beforeCurrentSections = [],
currentSections = [],
afterCurrentSections = [],
previousButton = null,
nextButton = null;
setLength = getSetLength();
totalSets = getTotalSets();
setTimeout(init, 1);
this.updatePageCount = updatePageCount;
this.exit = exit;
function init() { if (target && pages) refresh(); }
function updatePageCount(c, s) { currentPage = 1; currentSet = 1; updatePages(Math.ceil(c / s)); returnCB(1); }
function updatePages(p) { if (pages !== p) { pages = p; totalSets = getTotalSets(); refresh(true); } }
function PaginationObj() {
this.pages = getPagesArray([]);
this.beforeSections = currentSet != 1 ? getBeforeSections([]) : null;
this.beforeActive = this.beforeSections != null && this.beforeSections.length > 0 ? true : false;
this.afterSections = isThereOverflow() ? getAfterSections([]) : null;
this.afterActive = this.afterSections != null && this.afterSections.length > 0 ? true : false;
}
function PageObj(i, v) {
this.value = i + 1;
this.active = (i + 1) != v + currentPage ? false : true;
}
function TemplateObj() {
this.previousButton = '';
this.nextButton = '';
this.expandSection = '
{{ . }}
';
this.pagesSection = '
{{ value }}
';
this.pages = '{{# pages }}' + this.pagesSection + '{{/ pages }}';
this.beforeSections = '{{# beforeSections }}' + this.expandSection + '{{/ beforeSections }}';
this.afterSections = '{{# afterSections }}' + this.expandSection + '{{/ afterSections }}';
this.beforeCheck = '{{# beforeActive }}' + this.beforeSections + '{{/ beforeActive }}';
this.afterCheck = '{{# afterActive }}' + this.afterSections + '{{/ afterActive }}';
this.index = '' + this.previousButton + this.beforeCheck + '' + this.pages + '' + this.afterCheck + this.nextButton + '';
}
function refresh(ignore) {
obj = new PaginationObj;
var n = getElementFromString(render(template, obj));
if (paginationElement) refreshPagination(n);
else target.appendChild(n);
paginationElement = n;
setBindings(n);
if (returnCB && ignore !== true) returnCB(getCurrentPageValue());
}
function incrementPage() {
var r = Math.ceil(pageCount - ((currentSet - 1) * setLength)),
sL = r >= setLength ? setLength : r;
if (currentPage < sL) updateCurrentPage(currentPage);
else if (!isOnLastSet()) incrementSet();
}
function incrementSet() { if (currentSet < totalSets) { currentSet++; currentPage = 1; refresh(); } }
function decrementPage() { if (currentPage > 1) updateCurrentPage(currentPage - 2); else if (currentSet > 1) decrementSet(); }
function decrementSet() { if (currentSet > 1) { currentSet--; currentPage = setLength; refresh(); } }
function refreshPagination(n) { unsetBindings(); replacePagination(n); }
function unsetBindings() { unbindSections(); unbindBeforeSections(); unbindAfterSections(); unbindButtons(); }
function setBindings(n) {
var b = getBeforeElement(n);
a = getAfterElement(n);
bindSections(getPageSectionElements(n));
if (b) bindBeforeSections(b.querySelectorAll('section'));
if (a) bindAfterSections(a.querySelectorAll('section'));
bindNextButton();
bindPreviousButton();
}
function replacePagination(n) { target.insertBefore(n, paginationElement); target.removeChild(paginationElement); }
function updateCurrentPage(i) {
var s = getListSections();
s[currentPage - 1].classList.remove('active');
s[i].classList.add('active');
currentPage = i + 1;
if (!!returnCB) returnCB(getCurrentPageValue());
}
function beforeSectionClick(e, i) { currentPage = 1; currentSet = i + 1; refresh(); }
function afterSectionClick(e, i) { currentPage = 1; currentSet = currentSet + i + 1; refresh(); }
function getPagesArray(a) { var v = getSetStartingValue(); for (var i = v, l = v + getSetLength(); i < l; i++) { a.push(new PageObj(i, v)); } return a; }
function getSetStartingValue() { return (currentSet - 1) * setLength; }
function getCurrentPageValue() { return getSetStartingValue() + currentPage; }
function getSetLength() { if (isThereOverflow()) return setLength; else return pages - (setLength * (currentSet - 1)); }
function getBeforeSections(a) { var v = (setLength * (currentSet - 1)) + 1; for (var i = 1; i < v; i = i + setLength) { if (i < v) a.push(getOverflowSet(i, v)); } return a; }
function getAfterSections(a) { var i = (setLength * (currentSet)) + 1; for (var l = pages; i < l + 1; i = i + setLength) { a.push(getOverflowSet(i, l)); } return a; }
function getOverflowSet(i, l) { var v = i + setLength - 1; if (v > l) v = l; return i + ' - ' + v; }
function getSectionEventClosure(i) { return function (i) { return function () { updateCurrentPage(i); } }(i); }
function getBeforeSectionClosure(i) { return function (i) { return function (e) { beforeSectionClick(e, i); } }(i); }
function getAfterSectionClosure(i) { return function (i) { return function (e) { afterSectionClick(e, i); } }(i); }
function getListSections() { return paginationElement.querySelector('pagination-list').querySelectorAll('section'); }
function getBeforeElement(n) { return n.querySelector('pagination-overflow.before'); }
function getAfterElement(n) { return n.querySelector('pagination-overflow.after'); }
function getPageSectionElements(n) { return n.querySelector('pagination-list').querySelectorAll('section'); }
function getTotalSets() { return Math.ceil(pages / setLength); }
function isThereOverflow() { return isDefined(setLength) && (setLength * currentSet) <= pages; }
function isOnLastSet() { return currentSet == totalSets; }
function bindSections(t) { for (var i = 0, l = t.length; i < l; i++) { bindSection(t[i], i); } }
function bindSection(t, i) { var o = { 't': t, 'c': getSectionEventClosure(i), 'value': getSetStartingValue() + i + 1 }; events.add(t, 'click', o.c); currentSections.push(o); }
function bindBeforeSections(t) { for (var i = 0, l = t.length; i < l; i++) { bindBeforeSection(t[i], i); } }
function bindBeforeSection(t, i) { var o = { 't': t, 'c': getBeforeSectionClosure(i), 'value': obj.beforeSections[i] }; events.add(t, 'click', o.c); beforeCurrentSections.push(o); }
function bindAfterSections(t) { for (var i = 0, l = t.length; i < l; i++) { bindAfterSection(t[i], i); } }
function bindAfterSection(t, i) { var o = { 't': t, 'c': getAfterSectionClosure(i), 'value': obj.afterSections[i] }; events.add(t, 'click', o.c); afterCurrentSections.push(o); }
function bindNextButton() { var t = paginationElement.querySelector('.nextButton'); if (t) events.add(t, 'click', incrementPage); nextButton = t; }
function bindPreviousButton() { var t = paginationElement.querySelector('.prevButton'); if (t) events.add(t, 'click', decrementPage); previousButton = t; }
function unbindSections() { for (var i = 0, t = afterCurrentSections, l = t.length; i < l; i++) { unbindSection(t[i]); } currentSections = []; }
function unbindSection(o) { events.removeAll(o.t); }
function unbindBeforeSections() { for (var i = 0, t = beforeCurrentSections, l = t.length; i < l; i++) { unbindBeforeSection(t[i]); } beforeCurrentSections = []; }
function unbindBeforeSection(o) { events.removeAll(o.t); }
function unbindAfterSections() { for (var i = 0, t = afterCurrentSections, l = t.length; i < l; i++) { unbindAfterSection(t[i]); } afterCurrentSections = []; }
function unbindAfterSection(o) { events.removeAll(o.t); }
function unbindButtons() { if (nextButton) events.removeAll(nextButton); if (previousButton) events.removeAll(previousButton); nextButton = null; previousButton = null; }
function exit() {
if (events) events.reset();
housekeeping();
}
function housekeeping() {
target = pages = setLength = returnCB = events = template = currentPage = currentSet = totalSets = obj = null;
paginationElement = beforeCurrentSections = currentSections = afterCurrentSections = previousButton = nextButton = null;
}
};
var ToggleInput = function (target, returnCB, obj) {
var events = new EventManager,
state = false,
config = new Configuration(obj || {}),
template = getTemplate(),
element = getElementFromString(render(template, config));
startingState();
bindElement();
target.appendChild(element);
this.toggle = toggle;
this.set = on;
this.reset = on;
this.unset = off;
this.getState = getState;
this.exit = exit;
function Configuration(o) {
this.trueLabel = o.trueLabel || 'On';
this.falseLabel = o.falseLabel || 'Off';
this.toggleTheme = o.toggleTheme || 'royal';
this.labelTheme = o.labelTheme || 'fresh';
this.switchTheme = o.switchTheme || 'fresh';
this.transition = o.transition || '';
this.initialValue = o.initialValue || true;
}
function startingState() {
var v = obj ? obj.initialValue : null,
fn = on;
if (v === false || isString(v) && v.toLowerCase() == 'off') {
fn = off;
}
fn();
}
function toggle() { if (!state) on(); else off(); }
function on() { state = true; setElementOn(); if (returnCB) returnCB(true); }
function off() { state = false; setElementOff(); if (returnCB) returnCB(false); }
function setElementOn() { var e = element; if (e) e.classList.remove('off'); }
function setElementOff() { var e = element; if (e) e.classList.add('off'); }
function getState() { return state; }
function getTemplate() {
var trueLabel = '
{{ trueLabel }}
',
s = '',
falseLabel = '
{{ falseLabel }}
',
transition = '{{# transition }}cssTransition="{{ . }}"{{/ transition }}';
return '' + trueLabel + s + falseLabel + '';
}
function bindElement() { events.add(element, 'click', toggle); }
function exit() { if (events) events.reset(); removeElement(); state = null; config = null; template = null; element = null; target = null; returnCB = null; obj = null; events = null; }
function removeElement() { if (element.parentNode === target) target.removeChild(element); }
};
var ToggleNavigation = function (target, obj, returnCB) {
fixObj(obj);
var events = new EventManager,
template = new NavigationTemplate().index,
navigation = getElementFromString(render(template, obj)),
tabs = navigation.querySelectorAll('tab'),
tabList = [],
hidden = {},
activeTab = null;
this.getTabs = getTabs;
this.reset = reset;
this.set = set;
this.setByValue = setByValue;
this.showTab = showTab;
this.hideTab = hideTab;
this.exit = exit;
function initialize() {
bindTabs(tabs);
target.appendChild(navigation);
if (isDefined(obj.initialValue)) setByValue(obj.initialValue);
}
function NavigationTemplate(className) {
this.index = '{{# data }}
{{ title }}
{{/ data }}';
}
function Tab(tab, i, active) {
var data = obj.data[i];
events.add(tab, 'click', updateActive);
if (active) updateActive();
this.set = updateActive;
this.show = show;
this.hide = hide;
function updateActive() { if (activeTab) activeTab.unset(); activeTab = { 'unset': unset, 'index': i }; set(); if (returnCB) returnCB(data, i); }
function show() { tab.classList.remove('noDisplay'); delete hidden[i]; }
function hide() { if (activeTab.index === i) setNext(); tab.classList.add('noDisplay'); hidden[i] = true; }
function set() { tab.classList.add('active'); }
function unset() { tab.classList.remove('active'); }
function setNext() {
for (var v = 0, l = tabList.length; v < l; v++) {
if (v !== i && hidden[v] !== true) {
tabList[v].set();
return
}
}
}
}
function bindTabs(t) { for (var i = 0, l = t.length; i < l; i++) { tabList.push(new Tab(t[i], i, i == 0 ? true : false)); } }
function getTabs() { var a = []; forEach(tabList, p); return a; function p(t, d, i) { a[i] = t; } }
function set(v) { if (v > -1 && v < tabList.length) tabList[v].set(); }
function setByValue(v) {
var len = tabList.length - 1,
c = len;
while (c > -1) {
var i = len - c--;
if (obj.data[i].value === v) { set(i); return true; }
}
return false;
}
function showTab(i) { var t = tabList[i]; if (isDefined(t)) t.show(); }
function hideTab(i) { var t = tabList[i]; if (isDefined(t)) t.hide(); }
function reset() { tabList[0].set(); }
function exit() { if (events) events.reset(); target = obj = returnCB = events = template = navigation = tabs = tabList = activeTab = null; }
function fixObj(o) {
var t = o.data.length,
c = t;
while (c) {
var d = o.data[t - c--];
if (!d.title) d.title = d.value;
}
}
if (target && obj.data) initialize();
};
var TabbedContainer = function (target, obj, returnCB) {
var active = null,
data = obj.data,
config = obj.config || {},
navigationData = getNavigationData(data),
containerData = getContainerData(data),
template = '',
element = getElementFromString(template),
header = element.querySelector('header'),
container = element.querySelector('container'),
navigation = new ToggleNavigation(header, navigationData, refresh);
if (config.prepend !== true) target.appendChild(element);
else prependChild(target, element);
this.reset = navigation.reset;
this.showTab = navigation.showTab;
this.hideTab = navigation.hideTab;
this.update = update;
this.exit = exit;
function update(d) {
data = d;
navigationData = getNavigationData(data);
containerData = getContainerData(data);
}
function refresh(e, i) {
var c = containerData[i],
d = data[i];
if (isDefined(d.initFn)) initPanel(d);
if (active !== null) container.removeChild(active);
active = c;
container.appendChild(active);
if (isDefined(returnCB)) returnCB(i);
}
function getClassName() {
var c = config.className;
if (isDefined(c)) {
return c;
}
return 'tabbed';
}
function getNavigationData(d) {
var a = {
'data': [],
'className': getClassName()
};
d.forEach(function (item) {
a.data.push({ "value": item.title });
});
return a;
}
function getContainerData(d) {
var a = [];
d.forEach(function (item) { a.push(item.element); })
return a;
}
function initPanel(c) { setTimeout(function (fn) { return function () { fn(); } }(c.initFn), 1); c.initFn = null; }
function exit() { if (navigation) navigation.exit(); housekeeping(); }
function housekeeping() { target = obj = active = data = config = navigationData = containerData = template = element = header = container = navigation = null; }
};
var FileDataManager = function () {
var b = void 0, c = void 0, a = void 0, b = new FileReader, c = document.querySelector("body"), a = document.createElement("input");
b.onload = function (a) { window.prompt("Image Data", a.target.result) }; a.type = "file"; c.innerHTML = ""; c.appendChild(a); this.load = function () { b.readAsDataURL(a.files[0]) }
};
var __emc = 0;
var EventManager = function (debug) {
var bindings = getEmptyObj(),
referenceTable = getEmptyObj();
this.add = add;
this.remove = removeRequest;
this.removeAll = removeAll;
this.removeByTag = removeByTag;
this.reset = reset;
function Binding(t, type, fn, tag, keyID, id) { this.t = t; this.type = type; this.fn = fn; this.tag = tag; this.keyID = keyID; this.is = id; }
function add(t, type, fn, tag) { if (isValidTag(tag)) { t.addEventListener(type, fn); return insertReference(t, type, fn, tag); } else addError(); return null; }
function addError() { console.error('Well, we\'ve encountered an issue. It appears that a protected prefix was used in the tag for this add request. Please refer to the API documentation'); }
function removeRequest(t, id) { if (isDefined(t) && isDefined(id)) remove(bindings[t][id]); else removeRequestError(); }
function removeRequestError() { console.error("Well shucks, it looks like I'm missing some information. Please include both target and id attributes to remove a single event."); }
function remove(b) { if (b) { b.t.removeEventListener(b.type, b.fn); removeReference(b); } }
function removeReference(b) { var kID = b.keyID; delete bindings[kID][b.id]; if (bindings[kID].length == 0) delete referenceTable[kID]; }
function removeAll(id) { var o = bindings[id]; for (var k in o) { if (k != 'length') remove(o[k]); } }
function removeByTag(tag) {
var o = bindings;
for (var k in o) { if (k !== 'length') processKey(o[k], tag); }
function processKey(o, tag) { for (var k in o) { if (isValidRemoval(o[k], tag) && (k != 'length')) remove(o[k]); } }
}
function reset() { for (var k in bindings) { removeAll(k); } }
function insertReference(t, type, fn, tag) { var keyID = setKey(t), o = bindings[keyID], l = o.length; o[l] = new Binding(t, type, fn, tag, keyID, l); return o.length++; }
function setTagKey(tag) { if (bindings[tag] === undefined) bindings[tag] = { 'length': 0 }; }
function setKey(t) { var k = getKey(t); if (k === null) k = addKey(t, referenceTable, bindings); return k; }
function addKey(t, r, b) { if (b[r.length] === undefined) b[r.length] = getEmptyObj(); r[r.length] = t; return r.length++; }
function getKey(t) { var o = referenceTable; for (var k in o) { if (k !== 'length' && o[k] == t) return k; } return null; }
function getEmptyObj() { return { 'length': 0 }; }
function isValidRemoval(t, tag) { return tag === undefined || tag == t.tag; }
function isValidTag(tag) { return tag === undefined || tag.indexOf('__') !== 0; }
function invalidTagError() { console.error('Sorry, a restricted prefix was used as a tag. Please refer to the documentation for acceptable tag names.'); }
};
var Calendar = function (target, options, returnCB) {
var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
events = new EventManager(),
cal = new CalendarAssistant,
template = new Template(),
currentDate,
element = getElementFromString(''),
data = null;
this.setToPresent = setToPresent;
this.set = set;
this.get = function () { return currentDate; };
this.exit = exit;
if (!!options && !!options.value) {
set(options.value);
} else {
setToPresent();
}
target.appendChild(element);
function set(v) {
if (isNumber(v)) {
// We are expecting the int to be seconds rather than milliseconds
return refresh(getDataFromDateObj(new Date(v * 1000)));
}
if (isDefined(v) && typeof v.toUTCString === 'function') {
return refresh(getDataFromDateObj(v));
}
if (isDefined(v) && isDefined(v.month) && isDefined(v.monthValue) && isDefined(v.date) && isDefined(v.year)) {
return refresh(v);
}
console.error("Oh noes!", v);
}
function getDataFromDateObj(v) {
return {
month: months[v.getUTCMonth()],
monthValue: v.getUTCMonth() + 1,
date: v.getUTCDate(),
year: v.getUTCFullYear(),
};
}
function setToPresent() { refresh(cal.getCurrentDay()); }
function Data(focusDay) {
var focusMonth = cal.getMonth(focusDay.month, focusDay.year);
this.monthName = focusDay.month
this.yearValue = focusDay.year
this.days = processDays(getDays(focusMonth[0]), focusDay);
this.daysOfWeek = cal.getDaysOfWeek(this.days[0]);
this.focusDay = getFocusDay(this.days);
}
function Day(o, t) { o.element = t; events.add(t, 'click', clickAction, 'tmp'); function clickAction() { updateDay(o); } }
function refresh(day, ignore) {
events.removeByTag('tmp');
data = new Data(day);
repaint(element);
bindAll(element);
currentDate = getReturnData(data.focusDay);
if (ignore !== true && returnCB) returnCB(currentDate);
}
function getReturnData(d) {
var v = !isDefined(d) ? cal.getCurrentDay() : d,
o = {};
o.date = v.date;
o.display = v.date + ' ' + v.month + ', ' + v.year;
o.month = v.month;
o.year = v.year;
o.monthValue = v.monthValue;
o.toDate = function () { return new Date(Date.UTC(o.year, o.monthValue - 1, o.date, 0, 0, 0, 0)); };
o.toUnix = function () {
return Date.UTC(o.year, o.monthValue - 1, o.date, 0, 0, 0, 0) / 1000;
}
return o;
}
function repaint(e) {
var f = getFragment(),
gefs = getElementFromString;
f.appendChild(gefs(render(template.header, data)));
f.appendChild(gefs(render(template.month, data)));
element.innerHTML = '';
element.appendChild(f);
}
function bindAll(e) { bindButtons(e.querySelector('header')); bindDays(e.querySelector('days').querySelectorAll('day')); }
function bindPrev(h) { events.add(h.querySelector('prev-button'), 'click', prev); }
function bindNext(h) { events.add(h.querySelector('next-button'), 'click', next); }
function bindButtons(h) { bindPrev(h); bindNext(h); }
function bindDays(m) { forEach(m, bindDay); }
function bindDay(t, d, i) { new Day(data.days[i], t); }
function getDays(d) { var b = cal.getDaysBefore(d.name), n = cal.getNumberOfDays(d.month, d.year), size = Math.ceil((b + n) / 7) * 7, s = getStartDay(d, b); return cal.getDays(s, size); }
function getStartDay(d, b) { if (b === 0) return d; else return getPreviousMonthDay(d, b); }
function getPreviousMonthDay(d, b) { var m = cal.getPreviousMonth(d.month, d.year), n = cal.getNumberOfDays(m.name, m.year), s = n - b + 1, day = cal.getDay(m.name, s, m.year); return day; }
function getDayClassName(t, f) { if (!isSameMonth(t, f)) return 'grey'; else if (isSameDate(t, f)) return 'focus'; }
function getFocusDay(days) { var m = null; forEach(days, check); return m; function check(t) { if (t.className === 'focus') { m = t; return false; } } }
function Template() {
var calHeaderPrev = '',
calHeaderP = '
{{ monthName }}, {{ yearValue }}
',
calHeaderNext = '',
calHeader = '' + calHeaderPrev + calHeaderP + calHeaderNext + '',
month = '{{# daysOfWeek }}{{ abbreviation }}{{/ daysOfWeek }}{{# days }}{{ date }}{{/ days }}';
this.header = calHeader;
this.month = month;
}
function isSameDate(t, f) { return t.date === f.date; }
function isSameMonth(t, f) { return t.month === f.month; }
function prev() { var f = data.focusDay; goTo(cal.getPreviousMonth(f.month, f.year)); }
function next() { var f = data.focusDay; goTo(cal.getNextMonth(f.month, f.year)); }
function goTo(m) { refresh(cal.getDay(m.name, 1, m.year)); }
function processDays(days, focus) {
forEach(days, processDay);
return days;
function processDay(t) {
t.className = getDayClassName(t, focus);
}
}
function updateDay(day) { var f = data.focusDay; if (isDefined(f) && day.month == f.month) sameMonthUpdate(day, f); else refresh(day); }
function sameMonthUpdate(d, f) { f.element.classList.remove('focus'); d.element.classList.add('focus'); data.focusDay = d; if (returnCB) returnCB(getReturnData(data.focusDay)); }
function exit() { if (events) events.reset(); housekeeping(); }
function housekeeping() { target = options = returnCB = events = cal = template = element = data = null; }
};
var CalendarInput = function (target, options, returnCB) {
var events = new EventManager,
template = '',
element = getElementFromString(template),
input = element.querySelector('input'),
currentValue = null,
cal = new Calendar(element, options, calendarUpdate),
calendar = element.querySelector('calendar'),
state = false;
this.reset = reset;
this.exit = exit;
this.set = cal.set;
this.get = cal.get;
hideCalendar();
events.add(element.querySelector('input'), 'click', toggleCalendar);
target.appendChild(element);
function reset() { cal.setToPresent(); }
function set(v) { cal.set(v); }
function toggleCalendar() { if (!state) showCalendar(); else hideCalendar(); }
function hideCalendar() { events.removeAll(window); calendar.classList.add('noDisplay'); state = false; }
function showCalendar() {
element.classList[target.getBoundingClientRect().top < 400 ? 'add' : 'remove']('bottom');
events.add(window, 'mousedown', windowClick);
calendar.classList.remove('noDisplay');
state = true;
}
function calendarUpdate(v) {
input.value = v.display;
if (currentValue != null && v.month == currentValue.month) {
hideCalendar();
}
currentValue = v;
if (returnCB) returnCB(v);
}
function windowClick(e) { if (!isParentOfTarget(element, e.target)) hideCalendar(); }
function exit() {
if (events) events.reset();
if (cal) cal.exit();
housekeeping();
}
function housekeeping() { target = options = returnCB = events = template = element = input = currentValue = cal = calendar = state = null; }
};
var SlideInput = function (target, obj, returnCB) {
var data = new Data(obj),
template = '{{# separators }}{{/ separators }}{{# nubs }}{{/ nubs }}',
element = getElementFromString(render(template, data)),
fill = element.querySelector('fill'),
dragList = [];
target.appendChild(element);
init();
this.getValues = getValues;
this.setValues = setValues;
this.exit = exit;
function setValues(a) {
if (a.length == data.nubs.length) forEach(data.nubs, p);
function p(t, d, i) { t.setPosition(parseFloat(a[i])); }
}
function init() {
bindNubs();
if (returnCB) returnCB(getValues());
}
function Data(o) {
this.separatorCount = o.separatorCount || 4;
this.separators = getSeparators(this.separatorCount);
this.nubs = getNubs(o);
this.valueRange = o.valueRange;
this.prependValue = o.prependValue || null;
this.appendValue = o.appendValue || null;
this.startValues = o.startValues ? getStartValues(o.valueRange, o.startValues) : null;
this.decimalPlaces = isDefined(o.decimalPlaces) ? o.decimalPlaces : 2;
}
function getStartValues(r, s) {
var a = [];
if (isDefined(s[0])) a[0] = getValueInRange(r, s[0]);
if (isDefined(s[1])) a[1] = getValueInRange(r, s[1]);
return a;
}
function getValueInRange(r, v) {
if (v <= r[1]) { // If the value is less than or equal to the max range
if (v >= r[0]) return v; // If the value is greater than or equal to the min range, return value
else return r[0]; // Else if the value is less than the min range, return min range
}
else return r[1]; //Else if the value is greater than max, return max
}
function Nub(key) {
var nub = null,
nubRects = null,
label = {
'element': null,
'value': null,
'content': null
},
left = 0,
drag = null;
this.key = key;
this.drag = null;
this.dragStart = dragStart;
this.dragEnd = dragEnd;
this.dragMove = dragMove;
this.setElement = setElement;
this.setPosition = setPosition;
this.getLocation = getLocation;
this.getRects = getRects;
this.getData = getData;
this.setDrag = setDrag;
function getRects() { return nubRects; }
function getLocation() { return left; }
function getPrependage() { if (isDefined(data.prependValue)) return data.prependValue; else return '' }
function getAppendage() { if (isDefined(data.appendValue)) return data.appendValue; else return '' }
function getLabelValue() { return left !== 0 ? (left / (element.offsetWidth - nubRects.width)) : 0 }
function getLabelResult(v) { return parseFloat((v * (data.valueRange[1] - data.valueRange[0])).toFixed(data.decimalPlaces)) }
function getLeftValue(v) { return (element.offsetWidth - nubRects.width) * (v / data.valueRange[1] - data.valueRange[0]); }
function getData() { return label; }
function setDrag(d) { drag = d; dragList.push(d); }
function setPosition(v) { setRects(); setLeftPosition(v); setNubPosition(); dragMove(null, left, null, true); drag.setOffsets(); }
function setLeftPosition(v) { if (isDefined(v)) left = getLeftValue(v); }
function setNubPosition() { nub.style.position = 'absolute'; nub.style.left = left + 'px'; }
function setElement(e) { nub = e; label.element = nub.querySelector('label'); }
function setRects() { if (!nubRects) nubRects = nub.getClientRects()[0]; }
function setLabel() { var l = label; l.value = getLabelResult(getLabelValue()); l.element.textContent = l.content = getPrependage() + l.value + getAppendage(); }
function isValid(v) { if (key == 'start' && isStartValid(v)) return true; else if (key == 'end' && isEndValid(v)) return true; else return false; }
function isStartValid(v) { if (isDefined(data.nubs[1])) return (data.nubs[1].getLocation() - nubRects.width > v); else return true; }
function isEndValid(v) { if (isDefined(data.nubs[1])) return (data.nubs[0].getLocation() + nubRects.width < v); else return true; }
function dragStart(e) { nub.classList.add('active'); }
function dragMove(e, l, t, force) { setRects(); if (dragCheck(l, force)) dragMoveAction(l); else return false; }
function dragEnd(e) { nub.classList.remove('active'); if (returnCB) returnCB(getValues()); }
function dragCheck(l, f) { return ((isDefined(l) && isValid(l)) || f); }
function dragMoveAction(l) { left = l; setLabel(); setFill(); }
}
function getValues() {
var a = [];
forEach(data.nubs, process);
return a;
function process(t, d, i) { a.push(t.getData()); }
}
function Separator(v) { this.left = v + '%'; }
function setFill() {
var nubs = data.nubs;
multi = nubs.length > 1,
s = multi ? nubs[0] : 0,
e = multi ? nubs[1] : nubs[0],
sP = multi ? s.getLocation() : 0,
eP = e.getLocation();
fill.style.left = (multi ? s.getRects().width / 2 : 0) + sP + 'px';
fill.style.width = (multi ? eP - sP : eP + (e.getRects().width / 2)) + 'px';
}
function getSeparators(c) { var v = 100 / (c + 1), a = []; for (var i = 0; i < c; i++) { a.push(new Separator(v * (i + 1))); } return a; }
function getNubs(o) { var a = []; if (o.startNub !== false) a.push(new Nub('start')); if (o.endNub !== false) a.push(new Nub('end')); return a; }
function bindNubs() {
var e = element.querySelectorAll('nub');
forEach(e, process);
setFill();
function process(t, d, i) {
t = data.nubs[i];
t.element = t.setElement(e[i]);
t.setDrag(new DragController(e[i], t.dragStart, t.dragEnd, t.dragMove, { 'xOnly': true, 'inBounds': true, 'autoSet': true }));
t.setPosition(data.startValues[i]);
}
}
function exit() { exitDragList(); housekeeping(); }
function exitDragList() { forEach(dragList, p, true); function p(t, d, i) { if (t.exit) t.exit(); d.splice(i, 1); } }
function housekeeping() { target = obj = returnCB = data = template = element = fill = null; }
};
var ConfirmationButton = function (target, obj, returnCB) {
var events = new EventManager(true),
options = new Options(obj, getDefaultOptions()),
template = getTemplate(),
element = getElementFromString(render(template, options)),
state = 0,
timer = null;
this.exit = exit;
this.resetState = resetState;
events.add(element, 'click', clickAction);
target.appendChild(element);
function clickAction(e) {
prevent(e);
if (state == 0) confirmState();
else if (state == 1) confirmationSuccess();
}
function confirmState() {
var e = element, o = options;
state = 1;
if (!!o.color) e.classList.remove(o.color);
if (!!o.confirmColor) e.classList.add(o.confirmColor);
e.textContent = o.confirmText;
setTimer();
}
function confirmationSuccess() {
resetState();
if (returnCB) returnCB(true);
}
function resetState() {
var e = element, o = options;
state = 0;
if (!!o.confirmColor) e.classList.remove(o.confirmColor);
if (!!o.color) e.classList.add(o.color);
e.textContent = o.text;
clearTimer();
}
function prevent(e) { if (e && e.preventDefault) e.preventDefault(); }
function Options(o, dO) {
this.text = getOptionValue('text', o, dO);
this.confirmText = getOptionValue('confirmText', o, dO);
if (o.noClass !== true) {
this.className = getOptionValue('className', o, dO);
this.color = getOptionValue('color', o, dO);
this.confirmColor = getOptionValue('confirmColor', o, dO);
} else {
this.noClass = true;
this.className = "";
this.color = "";
this.confirmColor = "";
}
}
function getOptionValue(k, o, dO) { if (!isDefined(o[k])) return dO[k]; else return o[k]; }
function getDefaultOptions() {
return {
'className': '',
'color': 'cool',
'confirmColor': 'hot',
'text': 'Click',
'confirmText': 'Confirm'
};
}
function getTemplate() { return '{{ text }}'; }
function setTimer() { clearTimer(); timer = setTimeout(resetState, 3000); }
function clearTimer() { if (timer) clearTimeout(timer); timer = null; }
function exit() { events.reset(); target = obj = returnCB = events = options = template = element = state = timer = null; }
};
// Multi Select
// - The only required field is target
// - Return callback will return the selected values
// - Options are used to set classes, that's currently the only functionality
var MultiSelect = function (target, returnCB, options) {
var itemArray = undefined,
select = undefined,
selectData = undefined,
selectReplacement = undefined,
items = undefined,
multiSelect = undefined,
MultiSelectState = true,
initialLoad = true,
self = this;
initialize();
MultiSelectState = true;
this.disable = disable;
this.enable = enable;
this.update = update;
this.value = getValue;
this.getSelected = getSelected;
this.setSelectedByValue = setSelectedByValue;
this.ele = target;
function initialize() {
select = target.querySelector('select');
selectData = getSelectData(select);
selectReplacement = createSelectReplacement(target, select);
multiSelect = createMultiSelect(target, createMenuItems(selectData), select);
insertMultiSelect(target, multiSelect);
if (options && isArray(options.selected)) {
setSelectedByValue(options.selected);
}
initialLoad = false;
}
function bindMenuItem(element, item) { var closure = function (item) { return function (e) { updateMultiSelect(e, item); } }(item); element.addEventListener('click', closure); }
function disable() { closeDropDown(); dropDownState = false; }
function enable() { dropDownState = true; }
function update(i) { updateMultiSelect(null, itemArray[i]); }
function updateMultiSelect(e, item) {
if (e && e.preventDefault) e.preventDefault();
update();
function update() {
if (!item.active) setItemActive(item);
else setItemDisabled(item);
updateSelectReplacement(item);
if (returnCB && !initialLoad) returnCB(item, self);
}
}
function setItemActive(t) { t.active = true; t.element.classList.add('active'); }
function setItemDisabled(t) { t.active = false; t.element.classList.remove('active'); }
function updateSelectReplacement() {
var string = '', count = 0;
for (var i = 0, t = itemArray, l = t.length; i < l; i++) {
var item = t[i];
if (item.active) {
string += (count > 0 ? ', ' : '') + item.text;
count++;
}
}
selectReplacement.value = string;
}
function getValue() { return itemArray[activeItem].value; }
function getSelected() {
var o = [];
for (var i = 0; i < itemArray.length; i++) {
var it = itemArray[i];
if (it.active) o.push({ title: it.text, value: it.value, index: it.index });
}
return o;
}
function setSelectedByValue(values) {
for (var i = 0; i < itemArray.length; i++) {
var it = itemArray[i];
if (values.indexOf(it.value) !== -1) {
setItemActive(it)
}
}
}
function createSelectReplacement(target, select) {
var hidden = document.createElement('input'),
name = select.getAttribute('name');
hidden.name = name;
hidden.type = 'hidden';
return hidden;
}
function createMultiSelect(target, items, select) {
var t = document.createElement('div');
t.className = getTargetClassName('multiSelect', 'multiSelectMenu') + ' ' + select.className;
t.appendChild(items);
return t;
}
function createMenuItems(selectData) {
var fragment = document.createDocumentFragment();
itemArray = [];
for (var i = 0, d = selectData, l = d.length; i < l; i++) {
var item = d[i],
element = document.createElement('div'),
p = document.createElement('p');
item.element = element;
item.index = i;
p.textContent = item.text;
element.appendChild(p);
element.className = getTargetClassName('menuItem', 'menuItem quickTransition');
bindMenuItem(element, item);
itemArray.push(item);
fragment.appendChild(element);
}
return fragment;
}
function getTargetClassName(k, s) { var o = options; if (o && o[k] && o[k].className) s += ' ' + o[k].className; return s; }
function insertMultiSelect(target, dropDown) {
target.innerHTML = '';
target.appendChild(dropDown);
target.appendChild(selectReplacement);
return dropDown;
}
};
var AdGroupAdCountUpdate = function (adGroupID, delta, userID, returnCB) {
var data = null,
adCount = 0;
if (isValid()) new ApiManager({ 'adsList': null }, userID, init);
function init(e, d) { data = d; if (isDefined(d.adsList)) updateGroup(d.adsList); else returnCB(null); }
function isValid() { return (adGroupID && isDefined(delta) && isNumber(delta) && userID && returnCB) }
function updateGroup(d) {
forEach(d, p);
apiRequest('GET', 'adGroups', adGroupID, null, update);
function p(t) { if (t.data.group == adGroupID) adCount++; }
}
function update(e) { e.adCount = adCount; apiRequest('PUT', 'adGroups', adGroupID, e, requestCB); }
function requestCB() { returnCB(data.adGroups); }
};
var ApiUpdate = function (o, userID, returnCB) {
var d = {},
l = getObjectLength(o),
c = 0;
for (var k in o) { new Item(o[k], o, k); }
function Item(t, o, k) {
var c = {};
c[k] = null;
new ApiManager(c, userID, setNew);
function setNew(error, d) { update(getVal(getData(error, d, k), t)); }
function getData(e, d, k) { if (!e) d = d[k]; else if (isEmpty(e)) d = []; return d; }
function getVal(d, t) {
d[getArrayLocation(d, t)] = t;
return d;
}
function getArrayLocation(d, t) {
if (isDefined(t.displayOrder)) {
if (t.displayOrder !== '') {
var v = getUpdateID(d, t.displayOrder);
if (v !== null) return v;
}
t.displayOrder = getNextID(d);
}
return d.length;
}
function getNextID(d) { return d.length > 0 ? d[d.length - 1].displayOrder + 1 : 1; }
function getUpdateID(d, v) {
var m = null;
forEach(d, p);
return m;
function p(t, d, i) { if (t.displayOrder === v) { m = i; return false; } }
}
function isEmpty(e) { return e[0].error == getAPIErrorMessage('noMatch'); }
function update(d) { apiRequest('PUT', k, userID, d, check); }
}
function check() { c++; if (c == l && returnCB) returnCB(true); }
}
var ApiManager = function (o, userID, returnCB) {
var c = getObjectLength(o), l = 0, error = null, state = true;
if (o) process(o);
this.abort = abort;
function process(o) {
for (var k in o) {
new Api(k, o);
}
}
function readyCheck() { l++; if (isReady() && returnCB && state === true) returnCB(error, o); }
function isReady() { return c === l; }
function pushError(m) { if (error == null) error = []; error.push(m); }
function Api(k, o) {
var v = o[k] || {};
if (v.type != 'jsonP') {
if (!!v.source) apiRequest('GET', v.source, v.noID ? null : userID, null, apiCB, v.args);
else apiRequest('GET', k, v.noID ? null : userID, null, apiCB, v.args);
}
else jsonpRequest(v.source, jsonPCB, 'callback', 15000);
function apiCB(d, status) {
if (status === 200) o[k] = d;
else { o[k] = null; pushError({ 'error': isDefined(d) && isDefined(d.error) ? d.error : "Error", 'status': status }); }
readyCheck();
}
function jsonPCB(d) { o[k] = d; readyCheck(); }
}
function abort() { state = false; }
};
var ApiImageDelete = function (core, data, selectedRows, returnCB) {
var count = 0,
total = selectedRows.length;
check();
function check() { if (count < total) new Request(selectedRows[count++]); else returnCB(true); }
function Request(row) {
var c = 0,
t = 0,
d = row.getData();
if (!!d.imageKey) {
c++;
new HttpRequest('DELETE', '/api/v1/images/' + d.imageKey, null, null, 'json', rCheck);
}
if (!!d.logoKey) {
c++;
new HttpRequest('DELETE', '/api/v1/images/' + d.logoKey, null, null, 'json', rCheck);
}
if (!!d.backupBannerKey) {
c++;
new HttpRequest('DELETE', '/api/v1/images/' + d.backupBannerKey, null, null, 'json', rCheck);
}
if (c === 0) check();
function rCheck() { if (++t === c) check(); }
}
};
var ApiMarketingDelete = function (core, data, labelKeys, selectedRows, apiName, returnCB) {
var requestCount = 0,
completeCount = 0,
responseArray = [];
forEach(selectedRows, initRequest);
function initRequest(row, rows, i) {
requestCount++;
new Request(row, rows, i);
}
function Request(row, rows, i) {
var rdata = !!row.getData ? row.getData() : row;
new HttpRequest('DELETE', '/api/v1/' + apiName + '/' + rdata.id, null, null, 'json', cb);
function cb(e, statusCode) { if (statusCode == 200) setSuccess(); else setError(e); }
function setError(e) { responseArray[i] = { "success": false }; if (e.error) responseArray[i] = { error: true, message: e.message }; requestComplete(); }
function setSuccess() { responseArray[i] = { "success": true }; requestComplete(); }
}
function getDBUpdateObj(d, lk) { var o = {}; for (var k in lk) { var v = d[lk[k]]; if (isDefined(v)) o[k] = v; else o[k] = 0; } return o; }
function requestComplete() { if (++completeCount == requestCount) returnCB(responseArray); }
};
var ApiReqGroup = function (items, returnCB) {
var reqCnt = items.length,
finCnt = 0,
errCnt = 0;
loop(items, req);
function req(k, v) { new HttpRequest(v.method, v.url, v.data, 'json', 'json', cb); }
function cb(e, sC) { if (sC !== 200) errCnt++; if (++finCnt == reqCnt) returnCB(errCnt > 0); }
};
function ApiReqItem(method, url, data) {
this.method = method;
this.url = url;
this.data = data;
}
var ApiDelete = function (data, selectedRows, apiName, userID, returnCB) {
var c = getSimpleJSONCopy(data.table.rows),
errors = [],
responses = [],
count = 0,
total = selectedRows.length;
forEach(selectedRows, p);
function p(t, sR, i) { delRow(t, i); }
function delRow(t, i) {
var e = t.getElement(),
name = e.querySelector('.nameColumn'),
span = name.querySelector('span'),
data = t.getData();
t.unset();
span.className = 'deleting';
apiRequest('DELETE', apiName, data.id, data, cb)
}
function cb(e, d) { populateArrays(e, d); completeCheck(); }
function populateArrays(e, d) { errors[count] = e; responses[count] = d; }
function isComplete() { return ++count == total; }
function completeCheck() { if (isComplete()) returnCB(errors, responses); }
};
var ApiAdGroupDelete = function (data, selectedRows, userID, returnCB) {
var adsList = null,
count = 0,
total = selectedRows.length,
results = {};
apiRequest('GET', 'adsList', userID, null, init)
function init(d) { adsList = d; forEach(selectedRows, checkGroup); }
function checkGroup(group) {
var match = false;
forEach(adsList, check)
if (match === false) new Delete(group);
else deletionError(group);
function check(ad, adsList, i) { if (group.getData().id == ad.data.group) { match = true; return true; } }
}
var Delete = function (group) {
var id = group.getData().id
apiRequest('DELETE', 'adGroups', id, null, cb);
function cb(e, d) { results[id] = { 'success': d == 200 }; if (isDefined(e.error)) results[id].error = e.error; requestCheck(); }
}
function deletionError(group) { results[group.getData().id] = { 'success': false, 'error': 'One or more ads still exist which are using this Ad Group' }; requestCheck(); }
function requestCheck() { if (++count == total) returnCB(results); }
};
var ApiDuplicate = function (data, selectedRows, apiName, userID, returnCB) {
var d = selectedRows,
count = 0,
total = d.length;
check();
function check() { if (count < total) duplicateRow(d[count], count++); else returnCB(); }
function duplicateRow(t, i) {
var e = t.getElement(),
name = e.querySelector('.nameColumn'),
span = name.querySelector('span');
t.unset();
span.className = 'duplicating';
apiRequest('POST', apiName, userID, t.getData(), check);
}
};
var ApiChangeAdGroup = function (data, selectedRows, targetAdGroup, apiName, userID, returnCB) {
var d = selectedRows,
count = 0,
total = d.length;
check();
function check() { if (count < total) changeRow(d[count], count++); else returnCB(); }
function changeRow(t, i) {
var e = t.getElement(),
name = e.querySelector('.nameColumn'),
span = name.querySelector('span');
t.unset();
span.className = 'saving';
var rD = t.getData();
rD.group = targetAdGroup;
apiRequest('PUT', apiName, rD.id, rD, check);
}
};
var ApiAdPause = function (data, selectedRows, getIdFn, state, userID, returnCB) {
var d = selectedRows,
count = 0,
total = d.length;
check();
function check() { if (count < total) changeRow(d[count], count++); else returnCB(); }
function changeRow(t, i) {
var e = t.getElement(),
name = e.querySelector('.nameColumn'),
span = name.querySelector('span');
t.unset();
span.className = 'saving';
var rD = t.getData();
rD.active = state;
rD.group = getIdFn(rD.group)
apiRequest('PUT', 'ads', rD.id, rD, check);
}
};
var ApiPause = function (data, selectedRows, apiName, state, userID, returnCB) {
var d = selectedRows,
count = 0,
total = d.length;
check();
function check() { if (count < total) changeRow(d[count], count++); else returnCB(); }
function changeRow(t, i) {
var e = t.getElement(),
name = e.querySelector('.nameColumn'),
span = name.querySelector('span');
t.unset();
span.className = 'saving';
var rD = t.getData();
rD.active = state;
apiRequest('PUT', apiName, rD.id, rD, check);
}
};
var MailSend = function (core, template, data, subject, toEmail, toName, returnCB) {
if (isValid()) request();
function Data(template, data, subject, toEmail, toName) {
this.template = template;
this.data = data;
this.subject = subject;
this.toEmail = toEmail;
this.toName = toName;
}
function request() { new HttpRequest('POST', '/sendMail', new Data(template, data, subject, toEmail, toName), 'json', null, returnCB); }
function isValid() { var iD = isDefined; return iD(core) && iD(data) && iD(toEmail) && iD(toName); }
}
var MailPixelInstructions = function (core, toEmail, returnCB) { new MailSend(core, 'index', { 'id': core.userID }, core.brand.name + ' - Pixel placement instructions', toEmail, 'Webmaster', returnCB); };
var AdSet = function (obj, hiddenInput, resultElement, optional) {
var ads = [],
resultImage = resultElement.querySelector('img'),
current = new Ad;
optional = optional || {};
this.getAds = getAds;
this.resetAds = resetAds;
this.push = push;
this.setValue = setValue;
this.getValue = getValue;
this.setCurrentImage = setCurrentImage;
this.isValid = isValid;
this.getAdCount = getAdCount;
function push(ad) { for (var k in obj) { ad[k] = obj[k]; } ads.push(current); }
function setCurrentImage(d, i) { current.image = getImage(d, i); push(current); current = new Ad; }
function setValue(k, v) { if (obj[k] !== undefined) { obj[k] = v; setAds(k, v); return true; } return false; }
function getValue(k) { return obj[k]; }
function setAds(k, v) { forEach(ads, process); function process(t) { t[k] = v; } }
function getAds() { var a = []; forEach(ads, process); return a; function process(t, d, i) { a[i] = t; } }
function getAdCount() { return ads.length }
function resetAds() { ads = []; }
function isValid() { for (var k in obj) { var t = obj[k]; if (!optional[k] && (t == null || t.length === 0)) return false; } return true; }
function Ad(o) {
var valid = false,
i = null;
this.image = null;
this.isValid = isValid;
this.setIndex = setIndex;
for (var k in o) { if (this[k] == undefined) this[k] = o[k]; }
function setIndex(v) { i = v; }
function validate() { if (this.image !== null && hasObjKeys(o)) valid = true; else valid = false; }
function hasObjKeys(o) { for (var k in o) { if (!isDefined(this[k])) return false; } return true; }
function isValid() { return valid; }
}
function Image(data, rects, name, fileSize) {
this.data = data;
this.width = rects.width;
this.height = rects.height;
this.name = name;
this.fileSize = fileSize;
}
function getImage(d, i) { var f = hiddenInput.files[i]; return new Image(d.result, getImageRects(resultImage), f.name, getKilobytesFromBytes(f.size) + 'K'); }
function getImageRects(t) { var o = t.getClientRects()[0]; return { 'width': o.width, 'height': o.height }; }
};
var AdImage = function (data, name, width, height) {
this.data = data;
this.width = width;
this.height = height;
this.name = name;
this.fileSize = getKilobytesFromBytes(getStringByteValue(data)) + 'K';
};
var AdBatchData = function (imageData, name, width, height, adGroup, landingURL, data) {
this.image = new AdImage(imageData, name, width, height);
this.adGroup = adGroup;
this.data = data;
this.landingURL = landingURL;
};
var AdSave = function (core, ads, adType, userID, returnCB) {
var iK = null,
adBatchData = null;
if (ads && adType) uploadImageBatch(setImageBatch(ads));
else console.error('Well it appears as though I have undefined ads and/or adType, would you mind fixing that? Thanks!');
function setImageBatch(ads) {
var a = []; forEach(ads, p); return a;
function p(t) { a.push(t.image); }
}
function setAdBatch(keys) { var a = []; forEach(ads, p); adBatchData = a; uploadAdBatch(a); function p(t, d, i) { a.push(new AdBatchItem(t, keys[i])); } }
function AdBatchItem(t, imageResponse) {
var w = Math.round(t.image.width),
h = Math.round(t.image.height);
this.imageKey = imageResponse.id;
this.imageLocation = imageResponse.location;
this.active = true;
this.name = t.image.name;
this.size = w + 'x' + h;
this.width = w;
this.height = h;
this.group = t.adGroup;
this.imps = 0;
this.clicks = 0;
this.conv = 0;
this.adType = adType;
this.titleText = t.titleText || null;
this.captionText = t.captionText || null;
this.bodyText = t.bodyText || null;
this.data = t.data || null;
this.landingURL = t.landingURL;
this.clickTrack = t.clickTrack;
this.impTrack = t.impTrack;
}
function uploadImageBatch(iB) {
var count = 0,
max = iB.length,
errors = 0,
a = [];
request();
function check(v) {
if (v) {
if (v.error && !!v.message) {
uploadComplete(v.message);
return;
}
a.push(v);
}
if (count < max) {
request();
} else {
setAdBatch(a);
}
}
function request() { apiRequest('POST', 'images', core.userID, iB[count++], check); }
}
function uploadAdBatch(aB) {
var count = 0,
max = aB.length,
a = [];
request();
function check(v) {
if (v) a.push(v.id);
if (count < max) request();
else new AdGroupProcess();
}
function request() { apiRequest('POST', 'ads', core.userID, aB[count++], check); }
}
function isEmpty(error, d) { return d.ads === null || (error != null && error[0].error == getAPIErrorMessage('noMatch')); }
function AdGroupProcess() {
var adGroupHash = {},
updateCount = 0,
completeCount = 0;
if (adBatchData.length > 0) forEach(adBatchData, setChanges);
processAdGroupHash();
function setChanges(t) {
if (adGroupHash[t.group] === undefined) {
updateCount++;
adGroupHash[t.group] = 1;
}
else adGroupHash[t.group]++;
}
function processAdGroupHash() { for (var k in adGroupHash) { new AdGroupAdCountUpdate(k, adGroupHash[k], core.userID, adGroupUpdateCB); } }
function adGroupUpdateCB() { completeCount++; if (updateCount == completeCount) uploadComplete(); }
}
function uploadComplete(e) { if (returnCB) returnCB(e); }
};
var DynamicSave = function (core, ad, userID, returnCB) {
var iK = null,
adBatchData = null;
if (!!ad) uploadImageBatch([ad.logo, ad.backupBanner]);
else console.error('Well it appears as though I have an undefined ad, would you mind fixing that? Thanks!');
function AdBatchItem(t, imageResponses) {
var w = 300,
h = 250;
this.active = true;
this.name = 'Dynamic Ad - ' + w + 'x' + h;
this.size = w + 'x' + h;
this.width = w;
this.height = h;
this.group = t.adGroup;
this.adType = 'dynamic';
this.logoKey = imageResponses[0].id;
this.logoLocation = imageResponses[0].location;
this.buttonText = t.buttonText;
this.landingURL = t.backupLandingUrl;
this.backupBannerKey = imageResponses[1].id;
this.backupBannerLocation = imageResponses[1].location;
this.adTemplate = t.adTemplate;
this.preImageContent = t.preImageContent;
this.postImageContent = t.postImageContent;
this.footerContent = t.footerContent;
this.clickTrack = t.clickTrack;
this.impTrack = t.impTrack;
}
function uploadImageBatch(iB) {
var count = 0,
max = iB.length,
a = [];
request();
function check(v, sC) {
if (sC !== 200) {
returnCB("Error saving image.")
} else {
if (v) a.push(v);
if (count < max) request();
else apiRequest('POST', 'ads', core.userID, new AdBatchItem(ad, a), adGroupProcess);
}
}
function request() { apiRequest('POST', 'images', core.userID, iB[count++], check); }
}
function adGroupProcess() { new AdGroupAdCountUpdate(ad.adGroup, 1, core.userID, uploadComplete); }
function uploadComplete(e) { if (returnCB) returnCB(e); }
};
var EnterInput = function (input, returnCB) {
var events = new EventManager;
if (input && returnCB) events.add(input, 'keyup', kuAction);
this.exit = exit;
function kuAction(e) { if (e.keyCode === 13) returnCB(); }
function exit() { events.reset(); events = input = returnCB = null; }
};
function AlertModal(obj, returnCB, preInit) {
if (!obj.actionOneClass) obj.actionOneClass = 'grey';
if (!obj.actionTwoClass) obj.actionTwoClass = 'cool';
var events = new EventManager(),
template = new Template,
modal = new Modal({ 'title': obj.title, 'contents': render(template.index, obj) }, falseCB, preInit),
element = modal.element,
footer = element.querySelector('footer'),
anchors = footer.querySelectorAll('a');
if (obj.NoFooter) footer.classList.add('noDisplay');
setTimeout(init, 1);
this.close = close;
function init() {
events.add(anchors[0], 'click', falseCB);
events.add(anchors[1], 'click', trueCB);
}
function trueCB(e) { preventDefault(e); if (returnCB) returnCB(true, element); close(); }
function falseCB(e) { preventDefault(e); if (returnCB) returnCB(false); close(); }
function close() { if (modal) modal.close(); if (events) events.reset(); housekeeping(); }
function housekeeping() { events = template = element = footer = anchors = modal = null; }
function Template() {
var div = '
{{ message }}
',
footer = '';
this.index = div + footer;
}
}
function BillingUpdate(uid, fns, returnCB) {
var events = new EventManager,
template = new Template,
fragment = getFragment(),
modal = new Modal({ 'title': 'Please add your billing info to continue:', 'className': 'editBilling doubleColumnForm' }),
element = modal.element,
billing = new BillingModule(uid, fns, fragment, {}, init, billingCB),
footer = getElementFromString(template.footer),
anchors = footer.querySelectorAll('a');
this.close = close;
function init() {
fragment.appendChild(footer);
modal.element.querySelector('.inner').appendChild(fragment);
events.add(anchors[0], 'click', falseCB);
events.add(anchors[1], 'click', trueCB);
}
function trueCB() { billing.save(); }
function falseCB() { if (returnCB) returnCB(false); close(); }
function billingCB(e) { close(); returnCB(e); }
function close() { if (modal) modal.close(); if (events) events.reset(); housekeeping(); }
function housekeeping() { events = template = element = footer = anchors = modal = null; }
function Template() {
var footer = '';
this.footer = footer;
}
}
var BillingModule = function (uid, fns, target, data, readyCB, returnCB) {
var events = new EventManager,
template = new BillingTemplate,
invalidHash = getInvalidHash(),
data = null,
renderObj = null,
element = null,
elements = null,
inboundData = null;
new ApiManager({ 'billing': null, 'billingHistory': null }, uid, init);
this.exit = exit;
this.save = saveAction;
this.element = element;
function Data(d) {
this.advanced = new Advanced;
this.basic = new Basic(d);
function Advanced() {
this.firstName = null;
this.lastName = null;
this.cardholderName = null;
this.cardNumber = null;
this.month = null;
this.year = null;
this.cvv = null;
}
function Basic(d) {
this.addressOne = d.addressOne;
this.addressTwo = d.addressTwo;
this.city = d.city;
this.state = d.state;
this.zip = d.zip;
this.lastFour = d.lastFour;
this.insertionOrder = d.insertionOrder;
}
}
function init(error, d) {
var billing = isDefined(d.billing) ? d.billing : {};
inboundData = billing;
data = new Data(billing);
element = getElementFromString(render(template.card, { 'billing': data })),
elements = new Elements(element, {
'firstName': { 'selector': '.firstName' },
'lastName': { 'selector': '.lastName' },
'cardNumber': { 'selector': '.cardNumber' },
'month': { 'selector': '.month' },
'year': { 'selector': '.year' },
'cvv': { 'selector': '.cvv' },
'addressOne': { 'selector': '.addressOne' },
'addressTwo': { 'selector': '.addressTwo' },
'city': { 'selector': '.city' },
'state': { 'selector': '.state' },
'zip': { 'selector': '.zip' }
});
var e = elements;
events.add(e.firstName, 'change', updateFirstName);
events.add(e.lastName, 'change', updateLastName);
events.add(e.cardNumber, 'change', updateCardNumber);
events.add(e.month, 'change', updateMonth);
events.add(e.year, 'change', updateYear);
events.add(e.cvv, 'change', updateCVV);
events.add(e.addressOne, 'change', updateAddressOne);
events.add(e.addressTwo, 'change', updateAddressTwo);
events.add(e.city, 'change', updateCity);
events.add(e.state, 'change', updateState);
events.add(e.zip, 'change', updateZip);
insertElement();
if (readyCB) readyCB();
}
function insertElement() { target.appendChild(element); }
function updateFirstName(e) { updateData('firstName', e.target.value, true); }
function updateLastName(e) { updateData('lastName', e.target.value, true); }
function updateCardNumber(e) { updateData('cardNumber', e.target.value, true); }
function updateMonth(e) { updateData('month', e.target.value, true); }
function updateYear(e) { updateData('year', e.target.value, true); }
function updateCVV(e) { updateData('cvv', e.target.value, true); }
function updateAddressOne(e) { updateData('addressOne', e.target.value); }
function updateAddressTwo(e) { updateData('addressTwo', e.target.value); }
function updateCity(e) { updateData('city', e.target.value); }
function updateState(e) { updateData('state', e.target.value); }
function updateZip(e) { updateData('zip', e.target.value); }
function updateData(k, v, adv) { data[adv !== true ? 'basic' : 'advanced'][k] = v; }
function saveAction(e) {
var basicUpdate = true,
advUpdate = false,
completeCount = 0;
if (e && e.preventDefault) e.preventDefault();
var adv = data.advanced,
basic = data.basic;
if (!isDefined(basic.lastFour)) advUpdate = true;
var invalid = getInvalidItems(advUpdate ? adv : null, basicUpdate ? basic : null);
if (invalid === null) {
if (advUpdate) {
basic.lastFour = getLastFour(adv.cardNumber);
basicUpdate = true;
}
save();
}
else setMissing(invalid);
function save() { if (basicUpdate) saveBasic(); if (advUpdate) saveAdvanced(); }
function saveBasic() { apiRequest('PUT', 'billing', uid, data.basic, completeCheck); }
function saveAdvanced() { apiRequest('PUT', 'billingAdvanced', uid, data.advanced, completeCheck); }
function completeCheck(e) {
var c = 0;
completeCount++;
if (basicUpdate == true) c++;
if (advUpdate == true) c++;
if (c == completeCount) saveComplete(true);
}
function saveComplete(e) { if (returnCB) returnCB(e); }
function isSetEmpty(d) { var c = 0; for (var k in d) { if (isDefined(d[k])) c++; } return c === 0; }
}
function setMissing(a) { if (!!fns && !!fns.setMissingFields) fns.setMissingFields(a); }
function getLastFour(s) { return s.slice(s.length - 4); }
function getInvalidHash() {
return {
'firstName': 'First name',
'lastName': 'Last name',
'cardNumber': 'Card number',
'month': 'Month',
'year': 'Year',
'cvv': 'CVV',
'addressOne': 'Address One',
'city': 'City',
'state': 'State',
'zip': 'Zip',
};
}
function getInvalidItems(adv, basic) {
var a = [];
check(basic);
if (isDefined(adv)) checkAdvanced(adv);
return a.length > 0 ? a : null;
function checkAdvanced() { var cI = checkItem; check(adv); if (!cI(adv.cardNumber)) checkCardNumber(adv); if (!cI(adv.month)) checkMonth(adv); if (!cI(adv.year)) checkYear(adv); }
function checkCardNumber(d) {
var s = d.cardNumber.replace(/[ ]/g, '');
d.cardNumber = s;
if (isValidCardLength(s.length)) a.push('Invalid card number length');
if (s.indexOf(/[0-9]/g) > -1) a.push('Invalid card number characters');
}
function checkMonth(d) {
if (d.month.length !== 2 || d.month.indexOf(/[a-zA-Z]/g) > -1) a.push('Please set month the two-digit numeric representation');
else if (!isValidMonth(d.month)) a.push('Please set valid month');
}
function checkYear(d) { if (d.year.length !== 2 || d.year.indexOf(/[a-zA-Z]/g) > -1) a.push('Please set year the two-digit numeric representation'); }
function isValidCardLength(l) { return l < 15 || l > 19; }
function isValidMonth(s) { var v = parseFloat(s); if (!isNaN(v) && v > -1 && v < 13) return true; return false; }
function check(d) { for (var k in d) { var s = invalidHash[k]; if (checkItem(d[k]) && isDefined(s)) { a.push('Missing ' + s); } } }
function checkItem(t) { return (!isDefined(t) || t.length === 0); }
}
function exit() { if (element) removeChild(target, element); if (events) events.reset(); if (elements) elements.exit(); housekeeping(); }
function housekeeping() { target = data = returnCB = events = data = template = element = elements = inboundData = null; }
};
var Modal = function (obj, returnCB, preInit) {
'use strict';
var events = new EventManager(),
template = new Template(),
element = getElementFromString(template.index, obj);
setTimeout(init, 1);
this.close = close;
this.element = element;
function init() {
events.add(element.querySelector('.modalClose'), 'click', eventClose);
events.add(element, 'click', childCheck);
if (typeof preInit === 'function') preInit(element, events);
document.body.appendChild(element);
}
function eventClose() { if (returnCB) returnCB(); close(); }
function close() { if (element) removeChild(document.body, element); if (events) events.reset(); housekeeping(); }
function housekeeping() { events = element = null; }
function childCheck(e) { if (e.target === element) eventClose(); }
function Template() {
var header = '
{{ title }}
',
inner = '
' + header + '{{ contents }}
';
this.index = '' + inner + '';
}
};
function jsonpRequest(src, cb, cbKey, timeoutDuration) {
var tD = isDefined(timeoutDuration) ? timeoutDuration : 3000;
if (src && cb) request(src, cb, cbKey);
else errorResponse();
function request(src, cb, cbKey) { if (!cbKey) cbKey = 'callback'; cycle(src, cb, cbKey); }
function cycle(src, cb, cbKey) { var target = initScript(src, cb, cbKey); addScript(target); }
function errorResponse() { console.error('Well shoot, it looks like I\'m missing some essential arguments. Please try again!'); }
function addScript(target) { var head = getDocumentHead(); head.appendChild(target); }
function setLoadTimer(cb) { setTimeout(function () { if (window[cb]) window[cb](); }, tD); }
function removeScript(target) { var head = getDocumentHead(); head.removeChild(target); target = null; }
function initScript(src, cb, cbKey) { var target = document.createElement('script'), jsoncb = getCallback(cb, cbKey, target); target.type = 'text/javascript'; target.src = src + jsoncb; return target; }
function getDocumentHead() { return document.head || document.getElementsByTagName('head')[0]; }
function getCallback(cb, cbKey, target) {
var cbName = 'jsonPCallback' + (new Date().getTime()) + getRandomInt(10000, 99999), closure = getClosure(cb, cbName, target); window[cbName] = closure; setLoadTimer(cbName); return getQueryChar(src) + cbKey + '=' + cbName;
}
function getQueryChar(s) { return s.indexOf('?') > -1 ? '&' : '?'; }
function getClosure(cb, cbName, target) { var closure = function (cb, cbName, target) { return function (e) { if (isDefined(window[cbName])) { cb(e); window[cbName] = undefined; removeScript(target); } } }(cb, cbName, target); return closure; }
};
function HttpRequest(method, url, data, requestType, responseType, returnCB) {
var request = null;
if (url && returnCB) cycle();
else cycleError();
function cycle() {
if (!isDefined(requestType)) requestType = 'text';
method = method.toUpperCase();
request = new XMLHttpRequest();
openRequest();
setResponseType();
setMethod();
setRequest();
sendRequest();
}
function cycleError() { console.error("Uh oh! I need both URL and Callback to perform an HTTP Request."); }
function openRequest() { request.open(method, url + (url.indexOf('?') > -1 ? '&' : '?') + "ts=" + new Date().getTime(), true); }
function getRequestData() { if (!isDefined(data)) return null; else return rdProcess(); }
function rdProcess() { switch (requestType) { case 'text': return rdProcessText(); case 'json': return rdProcessJSON(); } console.error('unknown request type', requestType); }
function rdProcessText() { setRequestHeaders(request, 'text/plain'); return data; }
function rdProcessJSON() { setRequestHeaders(request, 'application/json'); return JSON.stringify(data); }
function setRequestHeaders(r, contentType) { r.setRequestHeader('Content-type', contentType); }
function setRequest() { request.responseType = responseType; request.onload = response; }
function setResponseType() { if (!isDefined(responseType)) responseType = 'text'; }
function setMethod() { if (!isDefined(method)) method = 'GET'; }
function sendRequest() { var d = getRequestData(); request.send(d); }
function response() { if (returnCB) returnCB(getData(), request.status); request = null; }
function getData() { if (responseType == 'text') return request.responseText; else return request.response; }
}
function prependChild(t, c, limit) {
t.insertBefore(c, t.firstChild);
if (typeof limit === 'number' && t.children.length > limit) t.removeChild(t.lastChild);
}
function popAnchor(e) { if (e && e.preventDefault) e.preventDefault(); pop('Pop!', 'Dashboard', e.target.getAttribute('href')); }
function pop(str, title, url) {
window.history.pushState({ 'foo': 'bar' }, title, url);
if (isFunction(window.ic) && window.intercomSetting) { // intercom.io
ic('reattach_activator');
ic('update', intercomSettings);
}
}
(function (h) { var pushState = h.pushState; h.pushState = function (s) { if (typeof h.onpushstate == "function") h.onpushstate({ 'state': s }); return pushState.apply(h, arguments); } })(window.history);
function FileToImageData(i, cb) {
var fr = new FileReader,
f = i.files,
c = 0,
l = f.length,
a = [],
i = 0;
fr.onload = check;
read();
function check(e) {
var r = e.target.result;
if (r) a.push({ 'e': e, 'result': r });
if (c++ + 1 == l) cb(a);
else read();
}
function read() { if (fr.readAsDataURL.result !== null) fr.readAsDataURL(f[i++]); }
}
/* Calendar Manager - Compiled */
function CalendarAssistant() {
function p(a, d) {
function b(a, b) {
var d = [];
c(a, b, function (a, b) {
var c = b + a.date,
e = h(a.month, c, a.year);
e.number = c;
d.push(e)
});
return d
}
function e() {
var c = q(a.month, a.year);
return b(a, f).concat(p(h(c.name, 1, c.year), d - f))
}
function c(a, b, d) {
for (var c = 0; c < b; c++) d(a, c)
}
var f = getNumberOfDays(a.month, a.year) - a.date + 1;
return f >= d ? b(a, d) : e()
}
function h(a, d, b) {
var e = parseFloat(b.toString().substr(2, 2)),
c = {
January: 3,
February: 6,
March: 6,
April: 2,
May: 4,
June: 0,
July: 2,
August: 5,
September: 1,
October: 3,
November: 6,
December: 1
}[a],
f = e / 4;
0 != f % 1 ? f = Math.floor(f) : "January" != a && "February" != a || (0 != e || 0 != e % 400) && 0 == e || (c -= 1);
e = "Saturday Sunday Monday Tuesday Wednesday Thursday Friday".split(" ")[(4 + e + f + c + parseFloat(d)) % 7];
var vv = new s(a, d, b, e, e.substr(0, 3))
return vv;
}
function s(a, d, b, e, c) {
this.month = a;
this.monthValue = g[a];
this.name = e;
this.element = null;
this.abbreviation = c || null;
this.number = this.className = null;
this.__defineGetter__("date", function () {
return d
});
this.__defineSetter__("date", function () {
return !1
});
this.__defineGetter__("year", function () {
return b
});
this.__defineSetter__("year", function () {
return !1
})
}
function q(a, d) {
var b = null,
b = g[a];
void 0 == d && (d = n().year);
"December" !== a ? b = k[b] : (b = k[0], d++);
return {
name: b,
year: d
}
}
function n() {
var a = new Date;
return h(r(a.getMonth()), a.getDate(), a.getFullYear())
}
function r(a) {
return t[a]
}
var k = "January February March April May June July August September October November December".split(" "),
m = [{
name: "Sunday",
abbreviation: "Sn"
}, {
name: "Monday",
abbreviation: "Mo"
}, {
name: "Tuesday",
abbreviation: "Tu"
}, {
name: "Wednesday",
abbreviation: "We"
}, {
name: "Thursday",
abbreviation: "Th"
}, {
name: "Friday",
abbreviation: "Fr"
}, {
name: "Saturday",
abbreviation: "Sa"
}],
u = {
Sunday: 0,
Monday: 1,
Tuesday: 2,
Wednesday: 3,
Thursday: 4,
Friday: 5,
Saturday: 6
},
g = {
January: 1,
February: 2,
March: 3,
April: 4,
May: 5,
June: 6,
July: 7,
August: 8,
September: 9,
October: 10,
November: 11,
December: 12
},
t = "January February March April May June July August September October November December".split(" "),
l = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
this.numberofdays = l;
this.getDaysOfWeek = function (a) {
a = a.name;
for (var d = [], b = [], e = null, c = 0, f = m.length; c < f; c++) m[c].name == a && (e = c), null === e ? d.push(m[c]) : b.push(m[c]);
return b.concat(d)
};
this.getNextMonth = q;
this.getPreviousMonth = function (a, d) {
var b = null,
b = g[a] - 1;
void 0 == d && (d = n().year);
"January" !== a ? b = k[b - 1] : (b = k[k.length - 1], d--);
return {
name: b,
year: d
}
};
this.getDaysBefore = function (a) {
return u[a]
};
this.getMonth = function (a, d) {
for (var b = l[g[a] - 1], e = [], c = 1; c <= b; c++) {
var f = h(a, c, d);
f.number = c;
e.push(f)
}
return e
};
this.getCurrentDay = n;
this.getDays = p;
this.getDay = h;
this.getMonthValue = function (a) {
return g[a]
};
this.getMonthName = r;
this.getNumberOfDays = getNumberOfDays;
function getNumberOfDays(month, year) {
var v = l[g[month] - 1];
if (month === "February" && isLeapYear(year)) {
v++;
}
return v;
}
function isLeapYear(year) {
if (year % 4 !== 0) {
return false;
}
if (year % 100 === 0 && year % 400 !== 0) {
return false
}
return true;
}
};
/* End Calendar Manager - Compiled */
var AdCreationTool = function (core, target, data, returnCB, title, adFields, adData, adTemplate, adWidth, adHeight, useLogo, addAnother) {
var events = new EventManager,
template = new Template,
adReference = adTemplate[adWidth + 'x' + adHeight],
data = null,
renderData = null,
element = null,
elements = null,
inboundData = null;
this.exit = exit;
new ApiManager({ 'adGroupsList': null }, core.userID, init);
function Data(d) { this.ads = []; this.logo = null; this.adGroup = null; }
function RenderData(d) { this.ads = adData; this.adGroups = d.adGroupsList; this.title = title; this.adFields = adFields; this.useLogo = useLogo; this.addAnother = addAnother; }
function Ad(e, i, d) {
var d = new AdData(d),
cO = getCanvasObj(d, e),
config = cO.config,
rows = e.querySelector('rows'),
c = getCanvas(e, cO),
controls = getControls(e),
close = getClose(e),
index = i,
updateObj = {};
this.element = e;
this.data = d;
this.canvas = c;
this.set = set;
this.setIndex = setIndex;
this.remove = remove;
bindLandingURL();
setUpdateObj();
initRows();
function initRows() { var f = getFragment(); for (var k in updateObj) { new RowKey(k, updateObj[k], f); } rows.insertBefore(f, rows.childNodes[1]); }
function bindLandingURL() { var t = e.querySelector('.landingURL'); if (t) events.add(t, 'change', setLandingURL); }
function RowKey(k, d, f) { forEach(d, p); function p(t) { if (t.type == 'input') f.appendChild(new Row(t, k)); } }
function Row(t, k) {
var row = getElementFromString(getRowString(t.title, d[t.key]));
events.add(row.querySelector('input'), 'change', check);
return row;
function getRowString(t, v) { return '
' + t + '
'; }
function check(e) {
var v = e.target.value;
set(t.key, v);
setObj(t.updateKey, t, v);
}
function setObj(key, t, v) {
var o = getRefreshObj([key]),
m = !isDefined(t.fn) ? v : t.fn(v);
if (isString(t.set)) single(t.set)
else forEach(t.set, p);
c.updateData(o);
function p(setItem) { o[key][setItem] = m[setItem]; }
function single(setItem) { o[key][setItem] = m; }
}
}
function checkUpdates(k, v) {
var t = updateObj[k],
o = {};
if (isDefined(updateObj[k])) forEach(updateObj[k], p);
c.updateData(o);
function p(t) { if (t.type !== 'input') setItem(o, t, t.updateKey, v); }
function setItem(o, t, r, v) {
var m = getValue(t, v);
o[r] = getRefreshObjItem(r);
if (isString(t.set)) single(t.set)
else forEach(t.set, p);
function p(setItem) { o[r][setItem] = m[setItem]; }
function single(setItem) { o[r][setItem] = m; }
}
function getValue(t, v) { return !isDefined(t.fn) ? v : t.fn(v); }
}
function getRefreshObj(a) { var o = {}; forEach(a, p); return o; function p(t) { o[t] = getRefreshObjItem(t); } }
function getRefreshObjItem(i) { return cO.template[i]; }
function getControls() { return new ToggleNavigation(e.querySelector('.controls'), getControlsObj(), setView); }
function getControlsObj() { var a = []; forEach(config.views, p); return { 'data': a, 'className': 'toggle' }; function p(item) { a.push({ 'value': item.title }); } }
function getClose(e) {
return new ConfirmationButton(e.querySelector('.close'), {
'color': 'hot',
'text': 'Close',
'className': 'tidySmall',
'confirmColor': 'mist',
'confirmText': 'Confirm?'
}, remove)
}
function set(k, v) {
if (d) {
if (isString(v)) single(v)
else forEach(v, p);
checkUpdates(k, v);
}
function p(setItem) { d[k] = v[setItem]; }
function single() { d[k] = v; }
}
function setIndex(v) { index = v; }
function setLogo(e) { var o = getRefreshObj([2]); o[2].src = e; c.updateData(o); }
function setLandingURL(e) { set('landingURL', e.target.value); }
function setUpdateObj() {
processItems(config.updateItems);
function processItems(item) { for (var k in item) { processItem(item[k], k); } }
function processItem(t, k) { t.updateKey = parseFloat(k); push(t.key, t); }
function setTargetItem(k, t) { t.reference = parseFloat(k); push(t.target, t); }
function push(k, v) { if (!isDefined(updateObj[k])) updateObj[k] = []; updateObj[k].push(v); }
}
function setView(e) { var v = e.value; if (v == 'Main') c.setView(0); else if (v == 'Re-position background') c.setView(1); }
function remove() { data.ads.splice(index, 1); updateAdIndexes(); exit(); }
function exit() { if (c && c.exit) c.exit(); if (controls) controls.exit(); if (close) close.exit(); if (e) removeChild(elements.adsContainer, e); housekeeping(); }
function housekeeping() { e = name = price = imageURL = landingURL = d = cO = c = main = position = controls = null; }
}
function AdData(d) {
for (var k in d) { this[k] = d[k]; }
this.logo = get300x40LogoImage();
this.adGroup = null;
this.landingURL = '';
}
function Template() {
var header = '