var SlidePointInput = function(target, obj, returnCB){
var data = new Data(obj),
template = '{{# separators }}{{/ separators }}{{# labels }}{{/ labels}}',
element = getElementFromString(render(template, data)),
fill = element.querySelector('fill'),
separators = element.querySelectorAll('dot'),
dragList = [];
this.getValue = data.nub.getValue;
this.setValue = data.nub.setValue;
this.exit = exit;
target.appendChild(element);
setTimeout(init,0);
function init(){ bindNub(); setFill(); setFilledDots(); }
function Data(o){
this.separators = getSeparators(o.values.length);
this.nub = new Nub('end');
this.values = o.values;
this.startValue = o.startValue ? getStartValue(o.values, o.startValue) : null;
this.labels = o.labels;
}
function Nub(key){
var nub = null,
left = 0,
slideWidth = 0,
nubWidth = 0,
currentIndex = 0,
position = 0,
drag = null;
this.key = key;
this.setNub = setNub;
this.setValue = setValue;
this.getLocation = getLocation;
this.getWidth = getWidth;
this.getData = getData;
this.getCurrentIndex = getCurrentIndex;
function getValueIndex(v){
var d = data.values,
t = d.length,
c = t;
while(c){
var i = t-c--;
if(d[i] === v) return i;
}
return 0;
}
function getIndexPosition(i){ return i / (data.values.length - 1); }
function getCurrentIndex(){ return currentIndex; }
function getWidth(){ return nubWidth; }
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 getLeftValue(v){ return (slideWidth - nubWidth) * getIndexPosition(getValueIndex(v)); }
function getData(){
var a = data.values,
t = a.length,
c = t,
d = t-1,
mm = (1/t)/2,
v = null;
while(c){
var i = t - c--,
amt = i/d - position;
if((amt < mm && amt >= 0) || (amt < 0)) v = i;
else if (c === 0 && v === null) v = 0;
}
return data.values[v];
}
function setNub(e){ nub = e; setDrag(new DragController(e, dragStart, dragEnd, dragMove, { 'xOnly' : true, 'inBounds' : true, 'autoSet' : true })); }
function setDrag(d){ drag = d; dragList.push(d); }
function setWidth(){ setSlideWidth(); setNubWidth(); }
function setSlideWidth(){ if(slideWidth != 0) return; c = element.getClientRects(); if(c.length > 0) slideWidth = c[0].width; }
function setNubWidth(){ if(nubWidth != 0) return; c = nub.getClientRects(); if(c.length > 0) nubWidth = c[0].width; }
function setValue(v){ setWidth(); left = getLeftValue(v); setNubPosition(); setPosition(); dragMove(null, left, null, true); drag.setOffsets(); }
function setNubPosition(){ if(!nub) return; nub.style.position = 'absolute'; nub.style.left = left + 'px'; }
function setPosition(){ setWidth(); position = left / (slideWidth - nubWidth); currentIndex = getValueIndex(getData()); }
function dragStart(e){ nub.classList.add('active'); }
function dragMove(e, l, t, force){ if(dragCheck(l, force)) dragMoveAction(l); else return false; }
function dragEnd(e){ var d = getData(); setValue(d); if(!!nub) nub.classList.remove('active'); if(!!returnCB) returnCB(d); }
function dragCheck(l, f){ return true; }
function dragMoveAction(l){ if(isNaN(l)) return; left = l; setPosition(); setFill(); setFilledDots(); }
}
function Separator(v){ this.left = v + '%'; }
function setFill(){ var e = data.nub; fill.style.width = e.getLocation() + (e.getWidth()/2) + 'px'; }
function setFilledDots(){
var d = separators,
t = d.length,
c = t,
ci = data.nub.getCurrentIndex();
while(c){
var i = t-c--;
d[i].classList[i <= ci ? 'add' : 'remove']('filled');
}
}
function getStartValue(values, start){
var t = values.length,
c = t;
while(c){
if(start === values[t-c--]) return start;
}
return values[0];
}
function getSeparators(c){
var v = 94 / (c - 1),
a = [];
for(var i=0; i