0)&&(e={url:e,data:f,dataType:g},"function"==typeof h&&(e.success=h)),e=e||{},e.delegation=e.delegation&&a.isFunction(a.fn.on),!e.delegation&&0===this.length){var i={s:this.selector,c:this.context};return!a.isReady&&i.s?(d("DOM not ready, queuing ajaxForm"),a(function(){a(i.s,i.c).ajaxForm(e)}),this):(d("terminating; zero elements found by selector"+(a.isReady?"":" (DOM not ready)")),this)}return e.delegation?(a(document).off("submit.form-plugin",this.selector,b).off("click.form-plugin",this.selector,c).on("submit.form-plugin",this.selector,e,b).on("click.form-plugin",this.selector,e,c),this):this.ajaxFormUnbind().on("submit.form-plugin",e,b).on("click.form-plugin",e,c)},a.fn.ajaxFormUnbind=function(){return this.off("submit.form-plugin click.form-plugin")},a.fn.formToArray=function(b,c,d){var f=[];if(0===this.length)return f;var g,h=this[0],i=this.attr("id"),j=b||void 0===h.elements?h.getElementsByTagName("*"):h.elements;if(j&&(j=a.makeArray(j)),i&&(b||/(Edge|Trident)\//.test(navigator.userAgent))&&(g=a(':input[form="'+i+'"]').get(),g.length&&(j=(j||[]).concat(g))),!j||!j.length)return f;a.isFunction(d)&&(j=a.map(j,d));var k,l,m,n,o,p,q;for(k=0,p=j.length;karticle,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}";
+c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML=" ";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
+"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);
+if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;da?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML=" ",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML=" ","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML=" ",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;
+if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" a ",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML=" ",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h ]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/\s*$/g,rb={option:[1,""," "],legend:[1,""," "],area:[1,""," "],param:[1,""," "],thead:[1,""],tr:[2,""],col:[2,""],td:[3,""],_default:k.htmlSerialize?[0,"",""]:[1,"X","
"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1>$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?""!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" a ",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight)),b.innerHTML="",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Mb=/alpha\([^)]*\)/i,Nb=/opacity\s*=\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp("^("+S+")(.*)$","i"),Qb=new RegExp("^([+-])=("+S+")","i"),Rb={position:"absolute",visibility:"hidden",display:"block"},Sb={letterSpacing:"0",fontWeight:"400"},Tb=["Webkit","O","Moz","ms"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fb(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Yb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),"normal"===f&&b in Sb&&(f=Sb[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Mb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+" "+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Jb,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e)}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")
+},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc("show"),slideUp:gc("hide"),slideToggle:gc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();ca ",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lc=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lc,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var uc=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(uc," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vc=m.now(),wc=/\?/,xc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\/\//,Gc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hc={},Ic={},Jc="*/".concat("*");try{zc=location.href}catch(Kc){zc=y.createElement("a"),zc.href="",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:"GET",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zc)+"").replace(Ac,"").replace(Fc,yc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yc[3]||("http:"===yc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,"$1_="+vc++):e+(wc.test(e)?"&":"?")+"_="+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\[\]$/,Sc=/\r?\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vc(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join("&").replace(Qc,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,"\r\n")}}):{name:b.name,value:c.replace(Sc,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.ActiveXObject&&m(a).on("unload",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&"withCredentials"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_c.pop()||m.expando+"_"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ad.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,"$1"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});
+//# sourceMappingURL=jquery.min.map
\ No newline at end of file
diff --git a/hosting/static/hosting/js/jquery-2.2.4.min.js b/datacenterlight/static/datacenterlight/js/jquery-2.2.4.min.js
similarity index 100%
rename from hosting/static/hosting/js/jquery-2.2.4.min.js
rename to datacenterlight/static/datacenterlight/js/jquery-2.2.4.min.js
diff --git a/datacenterlight/static/datacenterlight/js/main.js b/datacenterlight/static/datacenterlight/js/main.js
new file mode 100755
index 0000000..c6869cd
--- /dev/null
+++ b/datacenterlight/static/datacenterlight/js/main.js
@@ -0,0 +1,265 @@
+(function($) {
+ "use strict"; // Start of use strict
+
+
+ /* ---------------------------------------------
+ Scripts initialization
+ --------------------------------------------- */
+ var minRam = 1;
+ if(window.minRam){
+ minRam = window.minRam;
+ }
+ var cardPricing = {
+ 'cpu': {
+ 'id': 'coreValue',
+ 'value': 1,
+ 'min': 1,
+ 'max': 48,
+ 'interval': 1
+ },
+ 'ram': {
+ 'id': 'ramValue',
+ 'value': 2,
+ 'min': minRam,
+ 'max': 200,
+ 'interval': 1
+ },
+ 'storage': {
+ 'id': 'storageValue',
+ 'value': 10,
+ 'min': 10,
+ 'max': 2000,
+ 'interval': 10
+ }
+ };
+ $(window).load(function() {
+
+
+ });
+
+ $(document).ready(function() {
+ verifiedUrl();
+ _navScroll();
+ _initScroll();
+ _initNavUrl();
+ _initPricing();
+ ajaxForms();
+ $('#ramValue').data('old-value', $('#ramValue').val());
+ });
+
+ $(window).resize(function() {
+
+
+
+ });
+
+
+
+ /* ---------------------------------------------
+ Nav panel classic
+ --------------------------------------------- */
+ if (window.matchMedia("(min-width: 767px)").matches) {
+ $('ul.nav .dropdown').hover(function() {
+ $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(500);
+ }, function() {
+ $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut(500);
+ });
+ } else {
+ /* the viewport is less than 400 pixels wide */
+ }
+
+
+
+ function _initScroll() {
+ $(window).scroll(function() {
+ _navScroll();
+ });
+ }
+
+ function _navScroll() {
+ if (!window.non_transparent_navbar_always) {
+ if ($(window).scrollTop() > 10) {
+ $(".navbar").removeClass("navbar-transparent");
+ $(".navbar-default .btn-link").css("color", "#777");
+ $(".dropdown-menu").removeClass("navbar-transparent");
+ $(".dropdown-menu > li > a").css("color", "#777");
+ } else {
+ $(".navbar").addClass("navbar-transparent");
+ $(".navbar-default .btn-link").css("color", "#fff");
+ $(".dropdown-menu").addClass("navbar-transparent");
+ $(".dropdown-menu > li > a").css("color", "#fff");
+ }
+ }
+ }
+
+ _navScroll();
+
+ function _initNavUrl() {
+ $('.url-init').each(function(idx, el) {
+ var $this = $(el);
+ var currentPath = window.location.pathname;
+ var thisPaths = $this.attr('href').split('#')
+ if ($this.hasClass('dropdown-toggle') && window.matchMedia("(max-width: 767px)").matches) {
+ $this.removeClass('url-init');
+ $this.attr('href', '');
+ } else if ($('#'+thisPaths[1]).length) {
+ $this.removeClass('url-init').addClass('url');
+ $this.attr('href', '#' + thisPaths[1]);
+ } else {
+ $this.removeClass('url-init');
+ }
+ });
+ $('.url').click(function(event) {
+ event.preventDefault();
+ var $this = $(this);
+ var href = $this.attr('href');
+ $('.navbar-collapse').removeClass('in');
+ $('.navbar-collapse').addClass('collapsing');
+ if (href[0] === "#") {
+ scrollToElement(href);
+ } else if (href) {
+ var path = $(this).prop('href').split('#');
+ var currentPath = window.location.origin + window.location.pathname;
+ if (currentPath == path[0] && path[1]) {
+ scrollToElement('#' + path[1]);
+ } else {
+ window.location = href;
+ }
+ }
+ });
+ }
+
+ function scrollToElement(el) {
+ var $el = $(el);
+ if ($el.length) {
+ $('html, body').animate({
+ scrollTop: $el.offset().top - 50
+ }, 1000);
+ }
+ }
+
+ function verifiedUrl() {
+ if (window.location.href.indexOf('#success') > -1) {
+ form_success();
+ }
+ }
+
+ function _initPricing() {
+ _fetchPricing();
+
+ $('.fa-minus-circle.left').click(function(event) {
+ var data = $(this).data('minus');
+
+ if (cardPricing[data].value > cardPricing[data].min) {
+ if(data === 'ram' && String(cardPricing[data].value) === "1" && minRam === 0.5){
+ cardPricing[data].value = 0.5;
+ $('#ramValue').val('0.5');
+ $("#ramValue").attr('step', 0.5);
+ } else {
+ cardPricing[data].value = Number(cardPricing[data].value) - cardPricing[data].interval;
+ }
+ }
+ _fetchPricing();
+ $('#ramValue').data('old-value', $('#ramValue').val());
+ });
+ $('.fa-plus-circle.right').click(function(event) {
+ var data = $(this).data('plus');
+ if (cardPricing[data].value < cardPricing[data].max) {
+ if(data === 'ram' && String(cardPricing[data].value) === "0.5" && minRam === 0.5){
+ cardPricing[data].value = 1;
+ $('#ramValue').val('1');
+ $("#ramValue").attr('step', 1);
+ } else {
+ cardPricing[data].value = Number(cardPricing[data].value) + cardPricing[data].interval;
+ }
+ }
+ _fetchPricing();
+ $('#ramValue').data('old-value', $('#ramValue').val());
+ });
+
+ $('.input-price').change(function() {
+ var data = $(this).attr("name");
+ var input = $('input[name=' + data + ']');
+ var inputValue = input.val();
+
+ if(data === 'ram') {
+ var ramInput = $('#ramValue');
+ if ($('#ramValue').data('old-value') < $('#ramValue').val()) {
+ if($('#ramValue').val() === '1' && minRam === 0.5) {
+ $("#ramValue").attr('step', 1);
+ $('#ramValue').val('1');
+ }
+ } else {
+ if($('#ramValue').val() === '0' && minRam === 0.5) {
+ $("#ramValue").attr('step', 0.5);
+ $('#ramValue').val('0.5');
+ }
+ }
+ inputValue = $('#ramValue').val();
+ $('#ramValue').data('old-value', $('#ramValue').val());
+ }
+ cardPricing[data].value = inputValue;
+ _fetchPricing();
+ });
+ }
+
+ function _fetchPricing() {
+ Object.keys(cardPricing).map(function(element) {
+ $('input[name=' + element + ']').val(cardPricing[element].value);
+ });
+ _calcPricing();
+ }
+
+ function _calcPricing() {
+ if(typeof window.coresUnitPrice === 'undefined'){
+ window.coresUnitPrice = 5;
+ }
+ if(typeof window.ramUnitPrice === 'undefined'){
+ window.ramUnitPrice = 2;
+ }
+ if(typeof window.ssdUnitPrice === 'undefined'){
+ window.ssdUnitPrice = 0.6;
+ }
+ if(typeof window.discountAmount === 'undefined'){
+ window.discountAmount = 0;
+ }
+ var total = (cardPricing['cpu'].value * window.coresUnitPrice) +
+ (cardPricing['ram'].value * window.ramUnitPrice) +
+ (cardPricing['storage'].value * window.ssdUnitPrice) +
+ window.vmBasePrice - window.discountAmount;
+ total = parseFloat(total.toFixed(2));
+ $("#total").text(total);
+ }
+
+ function form_success() {
+ $('#sucessModal').modal('show');
+ }
+
+ function _calculate(numbers, price) {
+ $('#valueTotal').text(numbers * price * 31);
+ }
+
+ function ajaxForms() {
+ $('body').on('submit', '.ajax-form', function(e){
+ e.preventDefault();
+ var $form = $(this);
+ $form.find('[type=submit]').addClass('sending');
+ $.ajax({
+ url: $form.attr('action'),
+ type: $form.attr('method'),
+ data: $form.serialize(),
+
+ success: function(response) {
+ var responseContain = $($form.attr('data-response'));
+ responseContain.html(response);
+ $form.find('[type=submit]').removeClass('sending');
+ },
+
+ error: function() {
+ $form.find('[type=submit]').removeClass('sending');
+ $form.find('.form-error').removeClass('hide');
+ }
+ });
+ })
+ }
+})(jQuery);
diff --git a/datacenterlight/static/datacenterlight/js/respond-1.4.2.min.js b/datacenterlight/static/datacenterlight/js/respond-1.4.2.min.js
new file mode 100755
index 0000000..80a7b69
--- /dev/null
+++ b/datacenterlight/static/datacenterlight/js/respond-1.4.2.min.js
@@ -0,0 +1,5 @@
+/*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl
+ * Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT
+ * */
+
+!function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b
0:
+ get_or_create_vm_detail(custom_user, manager, vm_id)
diff --git a/datacenterlight/templates/datacenterlight/add_ssh_key.html b/datacenterlight/templates/datacenterlight/add_ssh_key.html
new file mode 100755
index 0000000..0eb2ecf
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/add_ssh_key.html
@@ -0,0 +1,10 @@
+
+{% load static bootstrap3 i18n custom_tags humanize %}
+
+{% block content %}
+ {% block userkey_form %}
+ {% with form_title=_("Your VM is almost ready!") form_sub_title=_("You need to specify your public SSH key to access your VM. You can either add your existing key, or generate a new key pair by clicking the generate button below. After choosing your public SSH key option you’ll be directed to the order confirmation page.") %}
+ {% include 'hosting/user_key.html' with title=form_title sub_title=form_sub_title %}
+ {% endwith %}
+ {% endblock userkey_form %}
+{%endblock%}
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/base.html b/datacenterlight/templates/datacenterlight/base.html
new file mode 100755
index 0000000..4bff9f5
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/base.html
@@ -0,0 +1,67 @@
+{% load static i18n cms_tags sekizai_tags %}
+{% get_current_language as LANGUAGE_CODE %}
+
+
+
+
+
+
+
+
+
+
+ Data Center Light - {% block title %}VM hosting made in Switzerland{% endblock %}
+
+
+
+
+
+
+
+
+
+ {% block css_extra %}
+ {% endblock css_extra %}
+ {% render_block "css" postprocessor "compressor.contrib.sekizai.compress" %}
+ {% render_block "js" postprocessor "compressor.contrib.sekizai.compress" %}
+
+
+
+
+
+
+
+
+
+
+
+ {% include "google_analytics.html" %}
+
+
+
+
+ {% include "gdpr_banner.html" %}
+ {% block navbar %}
+ {% include "datacenterlight/includes/_navbar.html" %}
+ {% endblock navbar %}
+
+ {% block content %}
+ {% endblock %}
+
+ {% include "datacenterlight/includes/_footer.html" %}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/datacenterlight/templates/datacenterlight/base_hosting.html b/datacenterlight/templates/datacenterlight/base_hosting.html
new file mode 100755
index 0000000..000f9c4
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/base_hosting.html
@@ -0,0 +1,95 @@
+{% load static i18n cms_tags sekizai_tags %}
+{% get_current_language as LANGUAGE_CODE %}
+
+
+
+
+
+
+
+
+
+
+
+ Data Center Light - {% block title %}VM hosting made in Switzerland{% endblock %}
+
+
+
+
+
+
+
+
+
+
+
+ {% if request.toolbar.edit_mode %}
+
+ {% endif %}
+ {% block css_extra %}
+ {% endblock css_extra %}
+
+ {% render_block "css" postprocessor "compressor.contrib.sekizai.compress" %}
+ {% render_block "js" postprocessor "compressor.contrib.sekizai.compress" %}
+
+
+
+
+
+
+
+
+
+
+ {% include "google_analytics.html" %}
+
+
+
+
+ {% include "gdpr_banner.html" %}
+ {% cms_toolbar %}
+
+ {% render_placeholder cms_integration.navbar_placeholder %}
+
+
+ {% block content %}
+ {% endblock %}
+
+
+ {% render_placeholder cms_integration.footer_placeholder %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% block js_extra %}
+ {% comment %}
+ this block is above some files, because on stripe error scripts below the stripe
+ script are not properly executed.
+ {% endcomment %}
+ {% endblock js_extra %}
+
+
+
+
+
+
+
+
+
diff --git a/datacenterlight/templates/datacenterlight/cms/banner_item.html b/datacenterlight/templates/datacenterlight/cms/banner_item.html
new file mode 100755
index 0000000..4f0fdae
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/cms/banner_item.html
@@ -0,0 +1,17 @@
+
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/cms/banner_list.html b/datacenterlight/templates/datacenterlight/cms/banner_list.html
new file mode 100755
index 0000000..92c5c05
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/cms/banner_list.html
@@ -0,0 +1,14 @@
+{% load cms_tags %}
+
+
+
+ {% if instance.heading %}
+
+
{{ instance.heading }}
+
+ {% endif %}
+ {% for plugin in instance.child_plugin_instances %}
+ {% render_plugin plugin %}
+ {% endfor %}
+
+
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/cms/base.html b/datacenterlight/templates/datacenterlight/cms/base.html
new file mode 100755
index 0000000..5e55ced
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/cms/base.html
@@ -0,0 +1,81 @@
+{% load static i18n cms_tags sekizai_tags %}
+{% get_current_language as LANGUAGE_CODE %}
+
+
+
+
+
+
+
+
+
+
+ {% page_attribute "page_title" %}
+
+
+
+
+
+
+
+
+
+
+ {% if request.toolbar.edit_mode %}
+
+ {% endif %}
+ {% render_block "css" postprocessor "compressor.contrib.sekizai.compress" %}
+ {% render_block "js" postprocessor "compressor.contrib.sekizai.compress" %}
+
+
+
+
+ {% if request.current_page.cmsfaviconextension %}
+
+ {% else %}
+
+ {% endif %}
+
+
+
+
+
+
+ {% include "google_analytics.html" %}
+
+
+
+
+ {% include "gdpr_banner.html" %}
+ {% cms_toolbar %}
+
+ {% placeholder 'datacenterlight_navbar' %}
+
+ {% placeholder 'Datacenterlight Header' or %}
+
+ {% endplaceholder %}
+
+ {% url 'datacenterlight:index' as calculator_form_url %}
+ {% placeholder 'Datacenterlight Content' %}
+
+ {% placeholder 'datacenterlight_footer'%}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/datacenterlight/templates/datacenterlight/cms/calculator.html b/datacenterlight/templates/datacenterlight/cms/calculator.html
new file mode 100755
index 0000000..20a6664
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/cms/calculator.html
@@ -0,0 +1,5 @@
+
+
+ {% include "datacenterlight/includes/_calculator_form.html" with vm_pricing=instance.pricing vm_base_price=vm_base_price %}
+
+
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/cms/contact.html b/datacenterlight/templates/datacenterlight/cms/contact.html
new file mode 100755
index 0000000..33dc903
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/cms/contact.html
@@ -0,0 +1,43 @@
+
+
+
diff --git a/datacenterlight/templates/datacenterlight/cms/footer.html b/datacenterlight/templates/datacenterlight/cms/footer.html
new file mode 100755
index 0000000..2d92ff7
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/cms/footer.html
@@ -0,0 +1,15 @@
+{% load i18n cms_tags %}
+
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/cms/includes/_section_split_content.html b/datacenterlight/templates/datacenterlight/cms/includes/_section_split_content.html
new file mode 100755
index 0000000..0f41740
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/cms/includes/_section_split_content.html
@@ -0,0 +1,21 @@
+{% load cms_tags %}
+
+{% if instance.heading %}
+
+
{{ instance.heading }}
+
+{% endif %}
+{% if instance.content %}
+
+
+ {{ instance.content }}
+
+
+{% endif %}
+{% if children_to_content|length %}
+
+ {% for plugin in children_to_content %}
+ {% render_plugin plugin %}
+ {% endfor %}
+
+{% endif %}
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/cms/link.html b/datacenterlight/templates/datacenterlight/cms/link.html
new file mode 100755
index 0000000..c05db99
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/cms/link.html
@@ -0,0 +1,3 @@
+
+ {{ instance.text }}
+
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/cms/navbar.html b/datacenterlight/templates/datacenterlight/cms/navbar.html
new file mode 100755
index 0000000..f33c699
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/cms/navbar.html
@@ -0,0 +1,75 @@
+{% load static i18n custom_tags cms_tags %}
+{% get_current_language as LANGUAGE_CODE %}
+{% if instance.show_non_transparent_navbar_always %}
+
+{% endif %}
+
+
+
+
+
+
+ {% for plugin in instance.child_plugin_instances %}
+
+ {% render_plugin plugin %}
+
+ {% endfor %}
+ {% if instance.language_dropdown %}
+
+ {% if LANGUAGE_CODE == 'en-us'%}
+ Deutsch
+ {% else %}
+ English
+ {% endif %}
+
+ {% endif %}
+ {% if instance.show_login_option %}
+ {% if not request.user.is_authenticated %}
+
+ {% trans "Login" %}
+
+ {% else %}
+
+ {% trans "Dashboard" %}
+
+ {% endif %}
+ {% endif %}
+ {% comment %}
+
+
+
+
+ {% if LANGUAGE_CODE == 'en-us'%}
+ English
+ {% else %}
+ Deutsch
+ {% endif %}
+
+
+
+
+
+ {% endcomment %}
+
+
+
diff --git a/datacenterlight/templates/datacenterlight/cms/navbar_dropdown.html b/datacenterlight/templates/datacenterlight/cms/navbar_dropdown.html
new file mode 100755
index 0000000..7092687
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/cms/navbar_dropdown.html
@@ -0,0 +1,10 @@
+{% load cms_tags %}
+
+
diff --git a/datacenterlight/templates/datacenterlight/cms/section.html b/datacenterlight/templates/datacenterlight/cms/section.html
new file mode 100755
index 0000000..4438cf7
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/cms/section.html
@@ -0,0 +1,31 @@
+{% load cms_tags %}
+
+
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/cms/section_icon.html b/datacenterlight/templates/datacenterlight/cms/section_icon.html
new file mode 100755
index 0000000..c0d8feb
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/cms/section_icon.html
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/cms/section_image.html b/datacenterlight/templates/datacenterlight/cms/section_image.html
new file mode 100755
index 0000000..d8bd5e6
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/cms/section_image.html
@@ -0,0 +1,6 @@
+
+
+ {% if instance.caption %}
+
{{ instance.caption }}
+ {% endif %}
+
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/cms/section_promo.html b/datacenterlight/templates/datacenterlight/cms/section_promo.html
new file mode 100755
index 0000000..c330122
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/cms/section_promo.html
@@ -0,0 +1,15 @@
+{% load custom_tags %}
+
+
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/contact_form.html b/datacenterlight/templates/datacenterlight/contact_form.html
new file mode 100755
index 0000000..87848ff
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/contact_form.html
@@ -0,0 +1,57 @@
+{% load i18n %}
+
+{% if success %}
+
+{% else %}
+
+
+
+ {% if form_header %}
+
{{ form_header }}
+ {% else %}
+ {% trans "Get in touch with us!" %}
+ {% endif %}
+
+
+
+
+{% endif %}
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/downtime.html b/datacenterlight/templates/datacenterlight/downtime.html
new file mode 100755
index 0000000..17c40d7
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/downtime.html
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
+ ungleich
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
You caught us while working!
+
+
We're doing scheduled maintenance from
+
17:00 21.08.2017 to 23:00 21.08.2017 CEST.
+
+
If you need immediate assistance, please contact us at
+
+
+
+
+
diff --git a/hosting/templates/hosting/emails/user_activation.html b/datacenterlight/templates/datacenterlight/emails/user_activation.html
similarity index 93%
rename from hosting/templates/hosting/emails/user_activation.html
rename to datacenterlight/templates/datacenterlight/emails/user_activation.html
index 4eaeb7a..403482a 100755
--- a/hosting/templates/hosting/emails/user_activation.html
+++ b/datacenterlight/templates/datacenterlight/emails/user_activation.html
@@ -6,7 +6,7 @@
{% trans "Data Center Light Account Activation" %}
-
+
@@ -14,7 +14,7 @@
-
+
diff --git a/hosting/templates/hosting/emails/user_activation.txt b/datacenterlight/templates/datacenterlight/emails/user_activation.txt
similarity index 100%
rename from hosting/templates/hosting/emails/user_activation.txt
rename to datacenterlight/templates/datacenterlight/emails/user_activation.txt
diff --git a/hosting/templates/hosting/emails/welcome_user.html b/datacenterlight/templates/datacenterlight/emails/welcome_user.html
similarity index 90%
rename from hosting/templates/hosting/emails/welcome_user.html
rename to datacenterlight/templates/datacenterlight/emails/welcome_user.html
index e2e854f..2044b2e 100755
--- a/hosting/templates/hosting/emails/welcome_user.html
+++ b/datacenterlight/templates/datacenterlight/emails/welcome_user.html
@@ -6,7 +6,7 @@
{% trans "Welcome to Data Center Light!" %}
-
+
@@ -14,7 +14,7 @@
-
+
diff --git a/hosting/templates/hosting/emails/welcome_user.txt b/datacenterlight/templates/datacenterlight/emails/welcome_user.txt
similarity index 100%
rename from hosting/templates/hosting/emails/welcome_user.txt
rename to datacenterlight/templates/datacenterlight/emails/welcome_user.txt
diff --git a/datacenterlight/templates/datacenterlight/includes/_calculator_form.html b/datacenterlight/templates/datacenterlight/includes/_calculator_form.html
new file mode 100755
index 0000000..1b1dad5
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/includes/_calculator_form.html
@@ -0,0 +1,106 @@
+{% load static i18n%}
+
+{% if vm_pricing %}
+
+{% endif %}
+
+
+ {% csrf_token %}
+
+
+
{% trans "VM hosting" %}
+
+
+
+
CHF/{% trans "month" %}
+
+
+ {% if vm_pricing.vat_inclusive %}{% trans "VAT included" %} {% endif %}
+ {% if vm_pricing.discount_amount %}
+ {% trans "You save" %} {{ vm_pricing.discount_amount }} CHF
+ {% endif %}
+
+
+
+
+
+
+
+
+
+ OS
+
+ {% for template in templates %}
+
+ {{template.name}}
+ {% endfor %}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/includes/_footer.html b/datacenterlight/templates/datacenterlight/includes/_footer.html
new file mode 100755
index 0000000..c495080
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/includes/_footer.html
@@ -0,0 +1,21 @@
+{% load i18n %}
+
+
diff --git a/datacenterlight/templates/datacenterlight/includes/_navbar.html b/datacenterlight/templates/datacenterlight/includes/_navbar.html
new file mode 100755
index 0000000..ee6be2b
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/includes/_navbar.html
@@ -0,0 +1,58 @@
+{% load static i18n custom_tags %}
+{% get_current_language as LANGUAGE_CODE %}
+
+
+
+
+
diff --git a/datacenterlight/templates/datacenterlight/index.html b/datacenterlight/templates/datacenterlight/index.html
new file mode 100755
index 0000000..a499fea
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/index.html
@@ -0,0 +1,165 @@
+{% extends "datacenterlight/base.html" %}
+{% load static i18n %}
+
+{% block content %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{% trans "Highlights" %}
+
+
+
+
+
+ {% trans "Reuses existing factory halls instead of building a new expensive building." %}
+
+
+
+
+ {% trans "Only wants you to pay for what you actually need." %}
+
+
+
+ {% trans "Is creative, using a modern and alternative design for a data center in order to make it more sustainable and affordable at the same time." %}
+
+
+
+ {% trans "Cuts down the costs for you by using FOSS (Free Open Source Software) exclusively, wherefore we can save money from paying licenses." %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{% trans "Scale out" %}
+
+
+
{% trans "We don't use special hardware. We use commodity hardware: we buy computers that you buy. Just many more and put them in a cozy home for computers called data center." %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{% trans "Reliable and light" %}
+
+
+
{% trans "Our VMs are located in Switzerland, with reliable power supply and fast internet connection. Our VM costs less thanks to our featherlight infrastructure." %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{% trans "Simple and affordable: Try our virtual machine with featherlight price." %}
+
+
+
+
{% blocktrans %}Ready in 30 seconds. Experience the unbeatable speed from Data Center Light.{% endblocktrans %}
+
+
+
+
+
+
+
+ {% include "datacenterlight/includes/_calculator_form.html" %}
+
+
+
+
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/datacenterlight/templates/datacenterlight/landing_payment.html b/datacenterlight/templates/datacenterlight/landing_payment.html
new file mode 100755
index 0000000..f5bed79
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/landing_payment.html
@@ -0,0 +1,195 @@
+{% extends "datacenterlight/base_hosting.html" %}
+{% load static bootstrap3 i18n cms_tags humanize %}
+
+{% block css_extra %}
+
+{% endblock css_extra %}
+
+{% block navbar %}
+ {% include "datacenterlight/includes/_navbar.html" %}
+{% endblock navbar %}
+
+{% block content %}
+
+
+
+
+ {% for message in messages %}
+ {% if 'vat_error' in message.tags %}
+
+ {% endif %}
+ {% endfor %}
+
+
+
+
+ {% if request.user.is_authenticated %}
+
+
{% trans "Welcome back" %} {{request.user.name}}!
+
{% trans "Review your billing address and card details and proceed to make payment." %}
+
+ {% else %}
+
{%trans "Log in" %}
+
+
{% blocktrans %}Already signed up? By logging in you can retrieve saved billing information.{% endblocktrans %}
+
+ {% for field in login_form %}
+ {% csrf_token %}
+ {% bootstrap_field field show_label=False type='fields'%}
+ {% endfor %}
+ {{login_form.non_field_errors|striptags}}
+
+
+ {% trans "LOGIN" %}
+
+
+
+ {% trans "Don't have an account yet?" %}
+ {% trans "You can sign up by filling in the information below." %}
+ {% trans "Forgot password?" %} or {% trans "Resend activation link" %}?
+
+ {% endif %}
+
+
+
+
+ {% if not request.user.is_authenticated %}
+
{%trans "Sign up"%}
+ {% else %}
+
{%trans "Billing Address"%}
+ {% endif %}
+
+ {% for message in messages %}
+ {% if 'duplicate_email' in message.tags %}
+
{{message}}
+ {% endif %}
+ {% endfor %}
+
+ {% csrf_token %}
+ {% for field in billing_address_form %}
+ {% bootstrap_field field show_label=False type='fields'%}
+ {% endfor %}
+
+
+
+
+
+ {% if generic_payment_form %}
+
{%trans "Make a payment" %}
+
+
+ {% csrf_token %}
+
+ {% for field in generic_payment_form %}
+ {% bootstrap_field field type='fields'%}
+ {% endfor %}
+ {{generic_payment_form.non_field_errors|striptags}}
+
+ {% else %}
+
{%trans "Your Order" %}
+
+
+
{% trans "Cores"%} {{request.session.specs.cpu|floatformat}}
+
+
{% trans "Memory"%} {{request.session.specs.memory|floatformat}} GB
+
+
{% trans "Disk space"%} {{request.session.specs.disk_size|floatformat}} GB
+
+
{% trans "Configuration"%} {{request.session.template.name}}
+
+
+ {%trans "Total" %}
+
+ ({% if vm_pricing.vat_inclusive %}{%trans "including VAT" %}{% else %}{%trans "excluding VAT" %}{% endif %})
+
+ {{request.session.specs.price|intcomma}} CHF/{% trans "Month" %}
+
+
+ {% if vm_pricing.discount_amount %}
+
+ {%trans "Discount" as discount_name %}
+ {{ vm_pricing.discount_name|default:discount_name }}
+ - {{ vm_pricing.discount_amount }} CHF/{% trans "Month" %}
+
+
+ ({% trans "Will be applied at checkout" %})
+
+ {% endif %}
+
+ {% endif %}
+
+
+
+
+ {% with card_list_len=cards_list|length %}
+
{%trans "Credit Card"%}
+
+
+ {% if card_list_len > 0 %}
+ {% blocktrans %}Please select one of the cards that you used before or fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %}
+ {% else %}
+ {% blocktrans %}Please fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %}
+ {% endif %}
+
+
+ {% for card in cards_list %}
+
+
+
{% trans "Credit Card" %}
+ {% trans "Last" %} 4: ***** {{card.last4}}
+ {% trans "Type" %}: {{card.brand}}
+ {% trans "Expiry" %}: {{card.exp_month}}/{{card.exp_year}}
+
+
+
+ {% endfor %}
+ {% if card_list_len > 0 %}
+
+
+
+
{% trans "Add a new credit card" %}
+
+
+
+ {% trans "NEW CARD" %}
+
+
+
+
+
+
+
+
{%trans "New Credit Card" %}
+
+ {% include "hosting/includes/_card_input.html" %}
+
+
+ {% else%}
+ {% include "hosting/includes/_card_input.html" %}
+ {% endif %}
+
+ {% endwith %}
+
+
+
+
+
+
+
+{% if stripe_key %}
+{% get_current_language as LANGUAGE_CODE %}
+
+{%endif%}
+{%endblock%}
diff --git a/datacenterlight/templates/datacenterlight/order_detail.html b/datacenterlight/templates/datacenterlight/order_detail.html
new file mode 100755
index 0000000..e0d4d41
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/order_detail.html
@@ -0,0 +1,343 @@
+{% extends "datacenterlight/base_hosting.html" %}
+{% load static bootstrap3 i18n custom_tags humanize %}
+
+{% block content %}
+
+
+ {% if messages %}
+
+ {% for message in messages %}
+ {{ message }}
+ {% endfor %}
+
+ {% endif %}
+ {% if not error %}
+
+
+ {% blocktrans with page_header_text=page_header_text|default:"Invoice" %}{{page_header_text}}{% endblocktrans %}
+
+
+
+
+ {% trans "Date" %}:
+
+ {% now "Y-m-d h:i a" %}
+
+
+
+
+
+ {% trans "Billed to" %}:
+
+ {% with request.session.billing_address_data as billing_address %}
+ {{billing_address.cardholder_name}}
+ {{billing_address.street_address}}, {{billing_address.postal_code}}
+ {{billing_address.city}}, {{billing_address.country}}
+ {% if billing_address.vat_number %}
+ {% trans "VAT Number" %} {{billing_address.vat_number}}
+ {% if vm.vat_validation_status != "ch_vat" and vm.vat_validation_status != "not_needed" %}
+ {% if vm.vat_validation_status == "verified" %}
+
+ {% else %}
+
+ {% endif %}
+ {% endif %}
+ {% endif %}
+ {% endwith %}
+
+
+
+
+
+
{% trans "Payment method" %}:
+
+ {{cc_brand|default:_('Credit Card')}} {% trans "ending in" %} ****{{cc_last4}}
+ {% trans "Expiry" %} {{cc_exp_year}}/{{cc_exp_month}}
+ {{request.user.email}}
+
+
+
+
+
{% trans "Order summary" %}
+
+ {% if generic_payment_details %}
+
+
+
+ {% trans "Product" %}:
+ {{ generic_payment_details.product_name }}
+
+ {% if generic_payment_details.description %}
+
+ {% trans "Description" %}:
+ {{generic_payment_details.description}}
+
+ {% endif %}
+ {% if generic_payment_details.recurring %}
+
+ {% trans "Recurring" %}:
+ Yes
+
+ {% endif %}
+
+ {% if generic_payment_details.exclude_vat_calculations %}
+ {% else %}
+
+
+
+
+
+ {% trans "Price Before VAT" %}
+ {{generic_payment_details.amount_before_vat|floatformat:2|intcomma}} CHF
+
+
+
+
+
+
+
+
+
+
{% trans "Pre VAT" %}
+
+
+
+
+
+
+
{{generic_payment_details.amount_before_vat|floatformat:2|intcomma}} CHF
+
+
+
{{generic_payment_details.amount|floatformat:2|intcomma}} CHF
+
+
+
+
+
+
+
+
+
+
+
{{generic_payment_details.amount_before_vat|floatformat:2|intcomma}} CHF
+
+
+
{{generic_payment_details.amount|floatformat:2|intcomma}} CHF
+
+
+
+ {% endif %}
+
+
+
+
+ {% trans "Your Price in Total" %}
+ {{generic_payment_details.amount|floatformat:2|intcomma}} CHF
+
+
+ {% else %}
+
+ {% trans "Product" %}:
+ {{ request.session.template.name }}
+
+
+
+
+ {% trans "Cores" %}:
+ {{vm.cpu|floatformat}}
+
+
+ {% trans "Memory" %}:
+ {{vm.memory|intcomma}} GB
+
+
+ {% trans "Disk space" %}:
+ {{vm.disk_size|intcomma}} GB
+
+
+
+
+
+
+
+ {% trans "Price Before VAT" %}
+ {{vm.price|floatformat:2|intcomma}} CHF
+
+
+
+
+
+
+
+
+
+
{% trans "Pre VAT" %}
+
+
+
+
+
+
+
{{vm.price|floatformat:2|intcomma}} CHF
+
+
+
{{vm.price_with_vat|floatformat:2|intcomma}} CHF
+
+
+ {% if vm.discount.amount > 0 %}
+
+
+
+
-{{vm.discount.amount|floatformat:2|intcomma}} CHF
+
+
+
-{{vm.discount.amount_with_vat|floatformat:2|intcomma}} CHF
+
+
+ {% endif %}
+
+
+
+
+
+
+
+
+
{{vm.price_after_discount|floatformat:2|intcomma}} CHF
+
+
+
{{vm.price_after_discount_with_vat|floatformat:2|intcomma}} CHF
+
+
+
+
+
+
+
+ {% trans "Your Price in Total" %}
+ {{vm.total_price|floatformat:2|intcomma}} CHF
+
+
+ {% endif %}
+
+
+
+
+ {% csrf_token %}
+
+
+ {% if generic_payment_details %}
+ {% if generic_payment_details.recurring %}
+ {% if generic_payment_details.recurring_interval == 'year' %}
+
{% blocktrans with total_price=generic_payment_details.amount|floatformat:2|intcomma %} By clicking "Place order" you agree to our
Terms of Service and this plan will charge your credit card account with {{ total_price }} CHF/year{% endblocktrans %}.
+ {% else %}
+
{% blocktrans with total_price=generic_payment_details.amount|floatformat:2|intcomma %}
+ By clicking "Place order" you agree to our
Terms of Service and this plan will charge your credit card account with {{ total_price }} CHF/month{% endblocktrans %}.
+ {% endif %}
+ {% else %}
+
{% blocktrans with total_price=generic_payment_details.amount|floatformat:2|intcomma %}By clicking "Place order" you agree to our
Terms of Service and this plan will charge your credit card account with {{ total_price }} CHF{% endblocktrans %}.
+ {% endif %}
+ {% else %}
+
{% blocktrans with vm_total_price=vm.total_price|floatformat:2|intcomma %}By clicking "Place order" you agree to our
Terms of Service and this plan will charge your credit card account with {{ vm_total_price }} CHF/month{% endblocktrans %}.
+ {% endif %}
+
+
+
+ {% trans "Place order" %}
+
+
+
+
+ {% endif %}
+
+
+
+
+
+
+
+
+
+
+
+ {% trans "Processing..." %}
+
+
+
+ {% trans "Hold tight, we are processing your request" %}
+
+
+
+
+
+
+
+
+
+{%endblock%}
diff --git a/datacenterlight/templates/datacenterlight/whydatacenterlight.html b/datacenterlight/templates/datacenterlight/whydatacenterlight.html
new file mode 100755
index 0000000..60d56a9
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/whydatacenterlight.html
@@ -0,0 +1,140 @@
+{% extends "datacenterlight/base.html" %}
+{% load static i18n%}
+
+{% block content %}
+
+
+
+
+
+
+
+
+
{% trans "Tech Stack" %}
+
+
+
{% trans "We are seriously open source." %}
+
{% blocktrans %} Our full software stack is open source – We don't use anything that isn't open source. Yes, we are that cool. {% endblocktrans %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{% trans "We believe in giving back to the FOSS community." %}
+
+
+
{% blocktrans %}Data Center Light is the child of free and open source software (FOSS) movement. We grew up with it, live by it, and believe in it. The more we work on our data center, the more we contribute back to the FOSS community.{% endblocktrans %}
+
+
+
+
+
+
+
+
+
+
{% trans "We bring the future to you." %}
+
+
+
+ 100% IPv6
+
+
+
{% blocktrans %}Data Center Light uses the most modern technologies out there. Your VM needs only IPv6. Data Center Light provides transparent two-way IPv6/IPv4 translation.{% endblocktrans %}
+
+
+
+
+
100% SSD
+
+
+
{% blocktrans %} No more spinning metal plates! Data Center Light uses only SSDs. We keep things faster and lighter. {% endblocktrans %}
+
+
+
+
+
+
+
+
+
+
+
{% trans "Starting from only 15CHF per month. Try now." %}
+
+
+
+
{% trans "Actions speak louder than words. Let's do it, try our VM now." %}
+
+
+
+
+
+
+ {% include "datacenterlight/includes/_calculator_form.html" %}
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/datacenterlight/templatetags/__init__.py b/datacenterlight/templatetags/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/datacenterlight/templatetags/custom_tags.py b/datacenterlight/templatetags/custom_tags.py
new file mode 100755
index 0000000..2465bd2
--- /dev/null
+++ b/datacenterlight/templatetags/custom_tags.py
@@ -0,0 +1,176 @@
+import datetime
+import logging
+
+from django import template
+from django.urls import resolve, reverse
+from django.utils.safestring import mark_safe
+from django.utils.translation import activate, get_language, gettext_lazy as _
+
+from hosting.models import GenericProduct, HostingOrder
+from utils.hosting_utils import get_ip_addresses
+
+logger = logging.getLogger(__name__)
+
+register = template.Library()
+
+
+@register.simple_tag(takes_context=True)
+def change_lang(context, lang=None, *args, **kwargs):
+
+ path = context['request'].path
+ url_parts = resolve(path)
+
+ url = path
+ cur_language = get_language()
+ try:
+ activate(lang)
+ url = reverse(url_parts.view_name, kwargs=url_parts.kwargs)
+ finally:
+ activate(cur_language)
+
+ return "%s" % url
+
+
+@register.filter('get_value_from_dict')
+def get_value_from_dict(dict_data, key):
+ """
+ usage example {{ your_dict|get_value_from_dict:your_key }}
+ """
+ if key:
+ return dict_data.get(key)
+ else:
+ return ""
+
+
+@register.filter('multiply')
+def multiply(value, arg):
+ """
+ usage: {{ quantity|multiply:price }}
+ :param value:
+ :param arg:
+ :return:
+ """
+ return value * arg
+
+
+@register.filter('escaped_line_break')
+def escaped_line_break(value):
+ """
+ usage: {{ text|escaped_line_break }}
+ :param value:
+ :return:
+ """
+ return value.replace("\\n", "\n")
+
+
+@register.filter('get_line_item_from_hosting_order_charge')
+def get_line_item_from_hosting_order_charge(hosting_order_id):
+ """
+ Returns ready-to-use "html" line item to be shown for a charge in the
+ invoice list page
+
+ :param hosting_order_id: the HostingOrder id
+ :return:
+ """
+ try:
+ hosting_order = HostingOrder.objects.get(id = hosting_order_id)
+ if hosting_order.stripe_charge_id:
+ return mark_safe("""
+ {product_name}
+ {created_at}
+ {total}
+
+ {see_invoice_text}
+
+ """.format(
+ product_name=hosting_order.generic_product.product_name.capitalize(),
+ created_at=hosting_order.created_at.strftime('%Y-%m-%d'),
+ total='%.2f' % (hosting_order.price),
+ receipt_url=reverse('hosting:orders',
+ kwargs={'pk': hosting_order.id}),
+
+ see_invoice_text=_("See Invoice")
+ ))
+ else:
+ return ""
+ except Exception as ex:
+ logger.error("Error %s" % str(ex))
+ return ""
+
+
+@register.filter('get_line_item_from_stripe_invoice')
+def get_line_item_from_stripe_invoice(invoice):
+ """
+ Returns ready-to-use "html" line item to be shown for an invoice in the
+ invoice list page
+
+ :param invoice: the stripe Invoice object
+ :return:
+ """
+ start_date = 0
+ end_date = 0
+ is_first = True
+ vm_id = -1
+ plan_name = ""
+ for line_data in invoice["lines"]["data"]:
+ if is_first:
+ plan_name = line_data.plan.name if line_data.plan is not None else ""
+ start_date = line_data.period.start
+ end_date = line_data.period.end
+ is_first = False
+ if hasattr(line_data.metadata, "VM_ID"):
+ vm_id = line_data.metadata.VM_ID
+ else:
+ if line_data.period.start < start_date:
+ start_date = line_data.period.start
+ if line_data.period.end > end_date:
+ end_date = line_data.period.end
+ if hasattr(line_data.metadata, "VM_ID"):
+ vm_id = line_data.metadata.VM_ID
+
+ try:
+ vm_id = int(vm_id)
+ except ValueError as ve:
+ print(str(ve))
+ if invoice["lines"]["data"]:
+ return mark_safe("""
+ {vm_id}
+ {ip_addresses}
+ {period}
+ {total}
+
+ {see_invoice_text}
+
+ """.format(
+ vm_id=vm_id if vm_id > 0 else "",
+ ip_addresses=mark_safe(get_ip_addresses(vm_id)) if vm_id > 0 else
+ mark_safe(get_product_name(plan_name)),
+ period=mark_safe("%s — %s" % (
+ datetime.datetime.fromtimestamp(start_date).strftime('%Y-%m-%d'),
+ datetime.datetime.fromtimestamp(end_date).strftime('%Y-%m-%d'))),
+ total='%.2f' % (invoice.total/100),
+ stripe_invoice_url=invoice.hosted_invoice_url,
+ see_invoice_text=_("See Invoice")
+ ))
+ else:
+ return ""
+
+
+def get_product_name(plan_name):
+ product_name = ""
+ if plan_name and plan_name.startswith("generic-"):
+ first_index_hyphen = plan_name.index("-") + 1
+ product_id = plan_name[first_index_hyphen:
+ (plan_name[first_index_hyphen:].index("-")) + first_index_hyphen]
+ try:
+ product = GenericProduct.objects.get(id=product_id)
+ product_name = product.product_name
+ except GenericProduct.DoesNotExist as dne:
+ logger.error("Generic product id=%s does not exist" % product_id)
+ product_name = plan_name
+ except GenericProduct.MultipleObjectsReturned as mor:
+ logger.error("Multiple products with id=%s exist" % product_id)
+ product_name = "Unknown"
+ else:
+ logger.debug("Product name for plan %s does not exist" % plan_name)
+ return product_name
diff --git a/datacenterlight/tests.py b/datacenterlight/tests.py
new file mode 100755
index 0000000..ca1bb93
--- /dev/null
+++ b/datacenterlight/tests.py
@@ -0,0 +1,161 @@
+# from django.test import TestCase
+
+from time import sleep
+
+import stripe
+from celery.result import AsyncResult
+from django.conf import settings
+from django.core.management import call_command
+from django.test import TestCase, override_settings
+from model_mommy import mommy
+from unittest import skipIf
+
+from datacenterlight.models import VMTemplate
+from datacenterlight.tasks import create_vm_task
+from hosting.models import HostingOrder
+from membership.models import StripeCustomer
+from opennebula_api.serializers import VMTemplateSerializer
+from utils.hosting_utils import get_vm_price
+from utils.models import BillingAddress
+from utils.stripe_utils import StripeUtils
+
+
+@skipIf(
+ settings.STRIPE_API_PRIVATE_KEY_TEST is None or
+ settings.STRIPE_API_PRIVATE_KEY_TEST is "",
+ """Stripe details unavailable, so skipping CeleryTaskTestCase"""
+ )
+class CeleryTaskTestCase(TestCase):
+ @override_settings(
+ task_eager_propagates=True,
+ task_always_eager=True,
+ )
+ def setUp(self):
+ self.customer_password = 'test_password'
+ self.customer_email = 'celery-createvm-task-test@ungleich.ch'
+ self.customer_name = "Monty Python"
+ self.user = {
+ 'email': self.customer_email,
+ 'name': self.customer_name
+ }
+ self.customer = mommy.make('membership.CustomUser')
+ self.customer.set_password(self.customer_password)
+ self.customer.email = self.customer_email
+ self.customer.save()
+ self.stripe_utils = StripeUtils()
+ stripe.api_key = settings.STRIPE_API_PRIVATE_KEY_TEST
+ self.token = stripe.Token.create(
+ card={
+ "number": '4111111111111111',
+ "exp_month": 12,
+ "exp_year": 2022,
+ "cvc": '123'
+ },
+ )
+ # Run fetchvmtemplates so that we have the VM templates from
+ # OpenNebula
+ call_command('fetchvmtemplates')
+
+ @skipIf(
+ settings.OPENNEBULA_DOMAIN is None or settings.OPENNEBULA_DOMAIN is
+ "test_domain",
+ """OpenNebula details unavailable, so skipping test_create_vm_task"""
+ )
+ def test_create_vm_task(self):
+ """Tests the create vm task for monthly subscription
+
+ This test is supposed to validate the proper execution
+ of celery create_vm_task on production, as we have no
+ other way to do this.
+ """
+
+ # We create a VM from the first template available to DCL
+ vm_template = VMTemplate.objects.all().first()
+ template_data = VMTemplateSerializer(vm_template).data
+
+ # The specs of VM that we want to create
+ specs = {
+ 'cpu': 1,
+ 'memory': 2,
+ 'disk_size': 10,
+ 'price': 15
+ }
+
+ stripe_customer = StripeCustomer.get_or_create(
+ email=self.customer_email,
+ token=self.token
+ )
+ card_details = self.stripe_utils.get_card_details(
+ stripe_customer.stripe_id
+ )
+ card_details_dict = card_details.get('error')
+ self.assertEquals(card_details_dict, None)
+ billing_address_data = {'cardholder_name': self.customer_name,
+ 'postal_code': '1231',
+ 'country': 'CH',
+ 'token': self.token,
+ 'street_address': 'Monty\'s Street',
+ 'city': 'Hollywood'}
+ vm_template_id = template_data.get('id', 1)
+
+ cpu = specs.get('cpu')
+ memory = specs.get('memory')
+ disk_size = specs.get('disk_size')
+ amount_to_be_charged = get_vm_price(cpu=cpu, memory=memory,
+ disk_size=disk_size)
+ plan_name = StripeUtils.get_stripe_plan_name(cpu=cpu,
+ memory=memory,
+ disk_size=disk_size,
+ price=amount_to_be_charged)
+ stripe_plan_id = StripeUtils.get_stripe_plan_id(cpu=cpu,
+ ram=memory,
+ ssd=disk_size,
+ version=1,
+ app='dcl')
+ stripe_plan = self.stripe_utils.get_or_create_stripe_plan(
+ amount=amount_to_be_charged,
+ name=plan_name,
+ stripe_plan_id=stripe_plan_id)
+ subscription_result = self.stripe_utils.subscribe_customer_to_plan(
+ stripe_customer.stripe_id,
+ [{"plan": stripe_plan.get(
+ 'response_object').stripe_plan_id}])
+ stripe_subscription_obj = subscription_result.get('response_object')
+ # Check if the subscription was approved and is active
+ if stripe_subscription_obj is None \
+ or stripe_subscription_obj.status != 'active':
+ msg = subscription_result.get('error')
+ raise Exception("Creating subscription failed: {}".format(msg))
+
+ billing_address = BillingAddress(
+ cardholder_name=billing_address_data['cardholder_name'],
+ street_address=billing_address_data['street_address'],
+ city=billing_address_data['city'],
+ postal_code=billing_address_data['postal_code'],
+ country=billing_address_data['country']
+ )
+ billing_address.save()
+
+ order = HostingOrder.create(
+ price=specs['price'],
+ vm_id=0,
+ customer=stripe_customer,
+ billing_address=billing_address
+ )
+
+ async_task = create_vm_task.delay(
+ vm_template_id, self.user, specs, template_data, order.id
+ )
+ new_vm_id = 0
+ res = None
+ for i in range(0, 10):
+ sleep(5)
+ res = AsyncResult(async_task.task_id)
+ if res.result is not None and res.result > 0:
+ new_vm_id = res.result
+ break
+
+ # We expect a VM to be created within 50 seconds
+ self.assertGreater(new_vm_id, 0,
+ "VM could not be created. res._get_task_meta() = {}"
+ .format(res._get_task_meta()))
diff --git a/datacenterlight/urls.py b/datacenterlight/urls.py
new file mode 100755
index 0000000..7772790
--- /dev/null
+++ b/datacenterlight/urls.py
@@ -0,0 +1,30 @@
+from django.urls import re_path, path
+from django.views.generic import TemplateView, RedirectView
+
+from utils.views import AskSSHKeyView
+from .views import (
+ IndexView, PaymentOrderView, OrderConfirmationView,
+ WhyDataCenterLightView, ContactUsView
+)
+
+app_name = 'datacenterlight'
+urlpatterns = [
+ path('', IndexView.as_view(), name='index'),
+ re_path(r'^t/$', IndexView.as_view(), name='index_t'),
+ re_path(r'^g/$', IndexView.as_view(), name='index_g'),
+ re_path(r'^f/$', IndexView.as_view(), name='index_f'),
+ re_path(r'^l/$', IndexView.as_view(), name='index_l'),
+ re_path(r'^new/$', RedirectView.as_view(url='/cms/'),
+ name='cms_index'),
+ re_path(r'^whydatacenterlight/?$', WhyDataCenterLightView.as_view(),
+ name='whydatacenterlight'),
+ re_path(r'^payment/?$', PaymentOrderView.as_view(), name='payment'),
+ re_path(r'^order-confirmation/?$', OrderConfirmationView.as_view(),
+ name='order_confirmation'),
+ re_path(r'^add-ssh-key/?$', AskSSHKeyView.as_view(),
+ name='add_ssh_key'),
+ re_path(r'^contact/?$', ContactUsView.as_view(), name='contact_us'),
+ re_path(r'glasfaser/?$',
+ TemplateView.as_view(template_name='ungleich_page/glasfaser.html'),
+ name='glasfaser'),
+]
diff --git a/hosting/utils.py b/datacenterlight/utils.py
old mode 100644
new mode 100755
similarity index 50%
rename from hosting/utils.py
rename to datacenterlight/utils.py
index 2f22996..6e7fdb4
--- a/hosting/utils.py
+++ b/datacenterlight/utils.py
@@ -1,51 +1,163 @@
import datetime
-import decimal
-import json
-
-import stripe
-from django.http import JsonResponse
-
-from dynamicweb2.stripe_utils import StripeUtils
-from hosting.models import VATRates, UserBillingAddress, BillingAddress, StripeCustomer, UserHostingKey, VMPricing
-from django.conf import settings
-from django.contrib import messages
-from django.utils.translation import get_language, gettext_lazy as _
-from django.urls import reverse
import logging
+# import pyotp
+import requests
+import stripe
+from django.conf import settings
+from django.contrib.sites.models import Site
+
+from datacenterlight.tasks import create_vm_task
+from hosting.models import HostingOrder, HostingBill, OrderDetail
+from membership.models import StripeCustomer
+from utils.forms import UserBillingAddressForm
+from utils.models import BillingAddress, UserBillingAddress
+from utils.stripe_utils import StripeUtils
+from .cms_models import CMSIntegration
+from .models import VMPricing, VMTemplate
+
logger = logging.getLogger(__name__)
-
eu_countries = ['at', 'be', 'bg', 'ch', 'cy', 'cz', 'hr', 'dk',
'ee', 'fi', 'fr', 'mc', 'de', 'gr', 'hu', 'ie', 'it',
- 'lv', 'lu', 'mt', 'nl', 'pl', 'pt', 'ro', 'sk', 'si', 'es',
+ 'lv', 'lu', 'mt', 'nl', 'pl', 'pt', 'ro','sk', 'si', 'es',
'se', 'gb']
-def get_vat_rate_for_country(country):
+def get_cms_integration(name):
+ current_site = Site.objects.get_current()
try:
- vat_rate = VATRates.objects.get(
- territory_codes=country, start_date__isnull=False, stop_date=None
+ cms_integration = CMSIntegration.objects.get(
+ name=name, domain=current_site
)
- logger.debug("VAT rate for %s is %s" % (country, vat_rate.rate))
- return vat_rate.rate
- except VATRates.DoesNotExist as dne:
- logger.debug(str(dne))
- logger.debug("Did not find VAT rate for %s, returning 0" % country)
- return 0
+ except CMSIntegration.DoesNotExist:
+ cms_integration = CMSIntegration.objects.get(name=name, domain=None)
+ return cms_integration
+
+
+def create_vm(billing_address_data, stripe_customer_id, specs,
+ stripe_subscription_obj, card_details_dict, request,
+ vm_template_id, template, user):
+ logger.debug("In create_vm")
+ billing_address = BillingAddress(
+ cardholder_name=billing_address_data['cardholder_name'],
+ street_address=billing_address_data['street_address'],
+ city=billing_address_data['city'],
+ postal_code=billing_address_data['postal_code'],
+ country=billing_address_data['country'],
+ vat_number=billing_address_data['vat_number'],
+ )
+ billing_address.save()
+ customer = StripeCustomer.objects.filter(id=stripe_customer_id).first()
+ vm_pricing = (
+ VMPricing.get_vm_pricing_by_name(name=specs['pricing_name'])
+ if 'pricing_name' in specs else
+ VMPricing.get_default_pricing()
+ )
+
+ final_price = (
+ specs.get('total_price')
+ if 'total_price' in specs
+ else specs.get('price')
+ )
+
+ # Create a Hosting Order with vm_id = 0, we shall set it later in
+ # celery task once the VM instance is up and running
+ order = HostingOrder.create(
+ price=final_price,
+ customer=customer,
+ billing_address=billing_address,
+ vm_pricing=vm_pricing
+ )
+
+ order_detail_obj, obj_created = OrderDetail.objects.get_or_create(
+ vm_template=VMTemplate.objects.get(
+ opennebula_vm_template_id=vm_template_id
+ ),
+ cores=specs['cpu'], memory=specs['memory'], ssd_size=specs['disk_size']
+ )
+ order.order_detail = order_detail_obj
+ order.save()
+
+ # Create a Hosting Bill
+ HostingBill.create(customer=customer, billing_address=billing_address)
+
+ # Create Billing Address for User if he does not have one
+ if not customer.user.billing_addresses.count():
+ billing_address_data.update({
+ 'user': customer.user.id
+ })
+ billing_address_user_form = UserBillingAddressForm(
+ billing_address_data
+ )
+ billing_address_user_form.is_valid()
+ billing_address_user_form.save()
+
+ # Associate the given stripe subscription with the order
+ order.set_subscription_id(
+ stripe_subscription_obj.id, card_details_dict
+ )
+
+ # Set order status approved
+ order.set_approved()
+
+ create_vm_task.delay(vm_template_id, user, specs, template, order.id)
+
+
+def clear_all_session_vars(request):
+ if request.session is not None:
+ for session_var in ['specs', 'template', 'billing_address',
+ 'billing_address_data', 'card_id',
+ 'token', 'customer', 'generic_payment_type',
+ 'generic_payment_details', 'product_id',
+ 'order_confirm_url', 'new_user_hosting_key_id',
+ 'vat_validation_status', 'billing_address_id',
+ 'id_payment_method']:
+ if session_var in request.session:
+ del request.session[session_var]
+
+
+# def check_otp(name, realm, token):
+# data = {
+# "auth_name": settings.AUTH_NAME,
+# "auth_token": pyotp.TOTP(settings.AUTH_SEED).now(),
+# "auth_realm": settings.AUTH_REALM,
+# "name": name,
+# "realm": realm,
+# "token": token
+# }
+# response = requests.post(
+# "https://{OTP_SERVER}{OTP_VERIFY_ENDPOINT}".format(
+# OTP_SERVER=settings.OTP_SERVER,
+# OTP_VERIFY_ENDPOINT=settings.OTP_VERIFY_ENDPOINT
+# ),
+# data=data
+# )
+# return response.status_code
def validate_vat_number(stripe_customer_id, billing_address_id,
is_user_ba=False):
if is_user_ba:
- billing_address = get_billing_address(billing_address_id)
+ try:
+ billing_address = UserBillingAddress.objects.get(
+ id=billing_address_id)
+ except UserBillingAddress.DoesNotExist as dne:
+ billing_address = None
+ logger.debug(
+ "UserBillingAddress does not exist for %s" % billing_address_id)
+ except UserBillingAddress.MultipleObjectsReturned as mor:
+ logger.debug(
+ "Multiple UserBillingAddress exist for %s" % billing_address_id)
+ billing_address = UserBillingAddress.objects.filter(
+ id=billing_address_id).order_by('-id').first()
else:
try:
billing_address = BillingAddress.objects.get(id=billing_address_id)
- except BillingAddress.DoesNotExist:
+ except BillingAddress.DoesNotExist as dne:
billing_address = None
logger.debug("BillingAddress does not exist for %s" % billing_address_id)
- except BillingAddress.MultipleObjectsReturned:
+ except BillingAddress.MultipleObjectsReturned as mor:
logger.debug("Multiple BillingAddress exist for %s" % billing_address_id)
billing_address = BillingAddress.objects.filter(id=billing_address_id).order_by('-id').first()
if billing_address is not None:
@@ -119,43 +231,38 @@ def validate_vat_number(stripe_customer_id, billing_address_id,
}
-def get_billing_address(billing_address_id):
- try:
- billing_address = UserBillingAddress.objects.get(
- id=billing_address_id)
- except UserBillingAddress.DoesNotExist:
- billing_address = None
- logger.debug(
- "UserBillingAddress does not exist for %s" % billing_address_id)
- except UserBillingAddress.MultipleObjectsReturned:
- logger.debug(
- "Multiple UserBillingAddress exist for %s" % billing_address_id)
- billing_address = UserBillingAddress.objects.filter(
- id=billing_address_id).order_by('-id').first()
- return billing_address
-
-
-def create_tax_id(stripe_customer_id, billing_address_id, vat_type, is_user_ba=False):
+def create_tax_id(stripe_customer_id, billing_address_id, type,
+ is_user_ba=False):
if is_user_ba:
- billing_address = get_billing_address(billing_address_id)
+ try:
+ billing_address = UserBillingAddress.objects.get(
+ id=billing_address_id)
+ except UserBillingAddress.DoesNotExist as dne:
+ billing_address = None
+ logger.debug(
+ "UserBillingAddress does not exist for %s" % billing_address_id)
+ except UserBillingAddress.MultipleObjectsReturned as mor:
+ logger.debug(
+ "Multiple UserBillingAddress exist for %s" % billing_address_id)
+ billing_address = UserBillingAddress.objects.filter(
+ id=billing_address_id).order_by('-id').first()
else:
try:
billing_address = BillingAddress.objects.get(id=billing_address_id)
- except BillingAddress.DoesNotExist:
+ except BillingAddress.DoesNotExist as dne:
billing_address = None
logger.debug("BillingAddress does not exist for %s" % billing_address_id)
- except BillingAddress.MultipleObjectsReturned:
+ except BillingAddress.MultipleObjectsReturned as mor:
logger.debug("Multiple BillingAddress exist for %s" % billing_address_id)
billing_address = BillingAddress.objects.filter(billing_address_id).order_by('-id').first()
tax_id_obj = None
- tax_id_response = None
if billing_address:
stripe_utils = StripeUtils()
tax_id_response = stripe_utils.get_or_create_tax_id_for_user(
stripe_customer_id,
vat_number=billing_address.vat_number,
- vat_type=vat_type,
+ type=type,
country=billing_address.country
)
@@ -166,8 +273,8 @@ def create_tax_id(stripe_customer_id, billing_address_id, vat_type, is_user_ba=F
return {
'paid': False,
'response_object': None,
- 'error': tax_id_response["error"] if tax_id_response and 'error' in tax_id_response else
- "No such address found"
+ 'error': "No such address found" if 'error' not in tax_id_response else
+ tax_id_response["error"]
}
try:
@@ -190,114 +297,9 @@ def create_tax_id(stripe_customer_id, billing_address_id, vat_type, is_user_ba=F
ub_address.vat_validation_status = tax_id_obj.verification.status
ub_address.save()
logger.debug("Updated user_billing_address %s" % str(ub_address))
- except StripeCustomer.DoesNotExist:
+ except StripeCustomer.DoesNotExist as dne:
logger.debug("StripeCustomer %s does not exist" % stripe_customer_id)
billing_address.stripe_tax_id = tax_id_obj.id
billing_address.vat_validation_status = tax_id_obj.verification.status
billing_address.save()
return tax_id_obj
-
-
-def get_vm_price_for_given_vat(cpu, memory, ssd_size, hdd_size=0,
- pricing_name='default', vat_rate=0):
- try:
- pricing = VMPricing.objects.get(name=pricing_name)
- except Exception as ex:
- logger.error(
- "Error getting VMPricing object for {pricing_name}."
- "Details: {details}".format(
- pricing_name=pricing_name, details=str(ex)
- )
- )
- return None
-
- price = (
- (decimal.Decimal(cpu) * pricing.cores_unit_price) +
- (decimal.Decimal(memory) * pricing.ram_unit_price) +
- (decimal.Decimal(ssd_size) * pricing.ssd_unit_price) +
- (decimal.Decimal(hdd_size) * pricing.hdd_unit_price) +
- decimal.Decimal(settings.VM_BASE_PRICE)
- )
-
- discount_name = pricing.discount_name
- discount_amount = round(float(pricing.discount_amount), 2)
- vat = price * decimal.Decimal(vat_rate) * decimal.Decimal(0.01)
- vat_percent = vat_rate
-
- cents = decimal.Decimal('.01')
- price = price.quantize(cents, decimal.ROUND_HALF_UP)
- vat = vat.quantize(cents, decimal.ROUND_HALF_UP)
- discount_amount_with_vat = (decimal.Decimal(discount_amount) *
- (1 + decimal.Decimal(vat_rate) * decimal.Decimal(0.01)))
- discount_amount_with_vat = discount_amount_with_vat.quantize(cents, decimal.ROUND_HALF_UP)
- discount = {
- 'name': discount_name,
- 'amount': discount_amount,
- 'amount_with_vat': round(float(discount_amount_with_vat), 2),
- 'stripe_coupon_id': pricing.stripe_coupon_id
- }
- return (round(float(price), 2), round(float(vat), 2),
- round(float(vat_percent), 2), discount)
-
-
-def get_all_public_keys(customer):
- """
- Returns all the public keys of the user
- :param customer: The customer whose public keys are needed
- :return: A list of public keys
- """
- return UserHostingKey.objects.filter(user_id=customer.id).values_list(
- "public_key", flat=True).distinct()
-
-
-def create_incomplete_intent_request(request):
- """
- Creates a dictionary of all session variables so that they could be
- picked up in the webhook for processing.
-
- :param request:
- :return:
- """
- req = {
- 'scheme': request.scheme,
- 'host': request.get_host(),
- 'language': get_language(),
- 'new_user_hosting_key_id': request.session.get(
- 'new_user_hosting_key_id', None),
- 'card_id': request.session.get('card_id', None),
- 'generic_payment_type': request.session.get(
- 'generic_payment_type', None),
- 'generic_payment_details': request.session.get(
- 'generic_payment_details', None),
- 'user': request.session.get('user', None),
- 'id_payment_method': request.session.get('id_payment_method', None),
- }
- return json.dumps(req)
-
-
-def get_error_response_dict(msg, request):
- logger.error(msg)
- response = {
- 'status': False,
- 'redirect': "{url}#{section}".format(
- url=(reverse(
- 'show_product',
- kwargs={'product_slug': request.session['generic_payment_details']['product_slug']}
- ) if 'generic_payment_details' in request.session else
- reverse('hosting:payment')
- ),
- section='payment_error'
- ),
- 'msg_title': str(_('Error.')),
- 'msg_body': str(
- _('There was a payment related error.'
- ' On close of this popup, you will be redirected back to'
- ' the payment page.'))
- }
- return response
-
-
-def show_error(msg, request):
- logger.error(msg)
- messages.add_message(request, messages.ERROR, msg, extra_tags='failed_payment')
- return JsonResponse(get_error_response_dict(msg,request))
diff --git a/datacenterlight/views.py b/datacenterlight/views.py
new file mode 100755
index 0000000..9c9ffd8
--- /dev/null
+++ b/datacenterlight/views.py
@@ -0,0 +1,1610 @@
+import json
+import logging
+
+import stripe
+from django import forms
+from django.conf import settings
+from django.contrib import messages
+from django.contrib.auth import login, authenticate
+from django.core.exceptions import ValidationError
+from django.urls import reverse
+from django.http import (
+ HttpResponseRedirect, JsonResponse, Http404, HttpResponse
+)
+from django.shortcuts import render
+from django.utils.decorators import method_decorator
+from django.utils.translation import get_language, gettext_lazy as _
+from django.views.decorators.cache import cache_control, never_cache
+from django.views.generic import FormView, CreateView, DetailView
+
+from hosting.forms import (
+ HostingUserLoginForm, GenericPaymentForm, ProductPaymentForm,
+ UserHostingKeyForm
+)
+from hosting.models import (
+ HostingBill, HostingOrder, UserCardDetail, GenericProduct, UserHostingKey,
+ StripeTaxRate, IncompleteSubscriptions, IncompletePaymentIntents)
+from membership.models import CustomUser, StripeCustomer
+from opennebula_api.serializers import VMTemplateSerializer
+from utils.forms import (
+ BillingAddressForm, BillingAddressFormSignup, UserBillingAddressForm,
+ BillingAddress
+)
+from utils.hosting_utils import (
+ get_vm_price_with_vat, get_all_public_keys, get_vat_rate_for_country,
+ get_vm_price_for_given_vat
+)
+from utils.stripe_utils import StripeUtils
+from utils.tasks import send_plain_email_task
+from .cms_models import DCLCalculatorPluginModel
+from .forms import ContactForm
+from .models import VMTemplate, VMPricing
+from .utils import (
+ get_cms_integration, create_vm, clear_all_session_vars, validate_vat_number
+)
+
+logger = logging.getLogger(__name__)
+
+
+class ContactUsView(FormView):
+ template_name = "datacenterlight/contact_form.html"
+ form_class = ContactForm
+
+ def get(self, request, *args, **kwargs):
+ return HttpResponseRedirect(reverse('datacenterlight:index'))
+
+ def form_invalid(self, form):
+ if self.request.is_ajax():
+ return self.render_to_response(
+ self.get_context_data(contact_form=form))
+ else:
+ return render(
+ self.request, 'datacenterlight/index.html',
+ self.get_context_data(contact_form=form)
+ )
+
+ def form_valid(self, form):
+ form.save()
+ from_emails = {
+ 'glasfaser': 'glasfaser@ungleich.ch'
+ }
+ from_page = self.request.POST.get('from_page')
+ email_data = {
+ 'subject': "{dcl_text} Message from {sender}".format(
+ dcl_text=settings.DCL_TEXT,
+ sender=form.cleaned_data.get('email')
+ ),
+ 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
+ 'to': [from_emails.get(from_page, 'support@ungleich.ch')],
+ 'body': "\n".join(
+ ["%s=%s" % (k, v) for (k, v) in form.cleaned_data.items()]),
+ 'reply_to': [form.cleaned_data.get('email')],
+ }
+ send_plain_email_task.delay(email_data)
+ if self.request.is_ajax():
+ return self.render_to_response(
+ self.get_context_data(success=True, contact_form=form))
+ else:
+ return render(
+ self.request, 'datacenterlight/index.html',
+ self.get_context_data(success=True, contact_form=form)
+ )
+
+
+class IndexView(CreateView):
+ template_name = "datacenterlight/index.html"
+ success_url = "/datacenterlight#requestform"
+ success_message = "Thank you, we will contact you as soon as possible"
+
+ def validate_cores(self, value):
+ if (value > 48) or (value < 1):
+ raise ValidationError(_('Invalid number of cores'))
+
+ def validate_memory(self, value):
+ if 'pid' in self.request.POST:
+ try:
+ plugin = DCLCalculatorPluginModel.objects.get(
+ id=self.request.POST['pid']
+ )
+ except DCLCalculatorPluginModel.DoesNotExist as dne:
+ logger.error(
+ str(dne) + " plugin_id: " + self.request.POST['pid']
+ )
+ raise ValidationError(_('Invalid calculator properties'))
+ if plugin.enable_512mb_ram:
+ if value % 1 == 0 or value == 0.5:
+ logger.debug(
+ "Given ram {value} is either 0.5 or a"
+ " whole number".format(value=value)
+ )
+ if (value > 200) or (value < 0.5):
+ raise ValidationError(_('Invalid RAM size'))
+ else:
+ raise ValidationError(_('Invalid RAM size'))
+ elif (value > 200) or (value < 1) or (value % 1 != 0):
+ raise ValidationError(_('Invalid RAM size'))
+ else:
+ raise ValidationError(_('Invalid RAM size'))
+
+ def validate_storage(self, value):
+ if (value > 2000) or (value < 10):
+ raise ValidationError(_('Invalid storage size'))
+
+ #@cache_control(no_cache=True, must_revalidate=True, no_store=True)
+ @method_decorator(decorator=never_cache)
+ def get(self, request, *args, **kwargs):
+ clear_all_session_vars(request)
+ return HttpResponseRedirect(reverse('datacenterlight:cms_index'))
+
+ def post(self, request):
+ cores = request.POST.get('cpu')
+ cores_field = forms.IntegerField(validators=[self.validate_cores])
+ memory = request.POST.get('ram')
+ memory_field = forms.FloatField(validators=[self.validate_memory])
+ storage = request.POST.get('storage')
+ storage_field = forms.IntegerField(validators=[self.validate_storage])
+ template_id = int(request.POST.get('config'))
+ pricing_name = request.POST.get('pricing_name')
+ vm_pricing = VMPricing.get_vm_pricing_by_name(pricing_name)
+
+ template = VMTemplate.objects.filter(
+ opennebula_vm_template_id=template_id
+ ).first()
+ template_data = VMTemplateSerializer(template).data
+ referer_url = request.META['HTTP_REFERER']
+
+ if vm_pricing is None:
+ vm_pricing_name_msg = _(
+ "Incorrect pricing name. Please contact support"
+ "{support_email}".format(
+ support_email=settings.DCL_SUPPORT_FROM_ADDRESS
+ )
+ )
+ messages.add_message(
+ self.request, messages.ERROR, vm_pricing_name_msg,
+ extra_tags='pricing'
+ )
+ return HttpResponseRedirect(referer_url + "#order_form")
+ else:
+ vm_pricing_name = vm_pricing.name
+
+ try:
+ cores = cores_field.clean(cores)
+ except ValidationError as err:
+ msg = '{} : {}.'.format(cores, str(err))
+ messages.add_message(
+ self.request, messages.ERROR, msg, extra_tags='cores'
+ )
+ return HttpResponseRedirect(referer_url + "#order_form")
+
+ try:
+ memory = memory_field.clean(memory)
+ except ValidationError as err:
+ msg = '{} : {}.'.format(memory, str(err))
+ messages.add_message(
+ self.request, messages.ERROR, msg, extra_tags='memory'
+ )
+ return HttpResponseRedirect(referer_url + "#order_form")
+
+ try:
+ storage = storage_field.clean(storage)
+ except ValidationError as err:
+ msg = '{} : {}.'.format(storage, str(err))
+ messages.add_message(
+ self.request, messages.ERROR, msg, extra_tags='storage'
+ )
+ return HttpResponseRedirect(referer_url + "#order_form")
+
+ price, vat, vat_percent, discount = get_vm_price_with_vat(
+ cpu=cores,
+ memory=memory,
+ ssd_size=storage,
+ pricing_name=vm_pricing_name
+ )
+ specs = {
+ 'cpu': cores,
+ 'memory': memory,
+ 'disk_size': storage,
+ 'price': price,
+ 'vat': vat,
+ 'vat_percent': vat_percent,
+ 'discount': discount,
+ 'total_price': round(price + vat - discount['amount'], 2),
+ 'pricing_name': vm_pricing_name
+ }
+ request.session['specs'] = specs
+ request.session['template'] = template_data
+ return HttpResponseRedirect(reverse('datacenterlight:payment'))
+
+ def get_success_url(self):
+ success_url = reverse('datacenterlight:index')
+ success_url += "#requestform"
+ return success_url
+
+ def get_context_data(self, **kwargs):
+ context = super(IndexView, self).get_context_data(**kwargs)
+ context.update({
+ 'base_url': "{0}://{1}".format(
+ self.request.scheme, self.request.get_host()
+ ),
+ 'contact_form': ContactForm
+ })
+ return context
+
+
+class WhyDataCenterLightView(IndexView):
+ template_name = "datacenterlight/whydatacenterlight.html"
+
+
+@method_decorator(decorator=never_cache, name='get')
+class PaymentOrderView(FormView):
+ template_name = 'datacenterlight/landing_payment.html'
+
+ def get_form_class(self):
+ if self.request.user.is_authenticated:
+ return BillingAddressForm
+ else:
+ return BillingAddressFormSignup
+
+ def get_context_data(self, **kwargs):
+ context = super(PaymentOrderView, self).get_context_data(**kwargs)
+ if 'billing_address_data' in self.request.session:
+ billing_address_data = self.request.session['billing_address_data']
+ else:
+ billing_address_data = {}
+
+ if self.request.user.is_authenticated:
+ if billing_address_data:
+ billing_address_form = BillingAddressForm(
+ initial=billing_address_data
+ )
+ else:
+ billing_address_form = BillingAddressForm(
+ instance=self.request.user.billing_addresses.order_by('-id').first()
+ )
+ user = self.request.user
+ if hasattr(user, 'stripecustomer'):
+ stripe_customer = user.stripecustomer
+ else:
+ stripe_customer = None
+ stripe_utils = StripeUtils()
+ cards_list_request = stripe_utils.get_available_payment_methods(
+ stripe_customer
+ )
+ cards_list = cards_list_request.get('response_object')
+ context.update({'cards_list': cards_list})
+ else:
+ billing_address_form = BillingAddressFormSignup(
+ initial=billing_address_data
+ )
+
+ context.update({
+ 'stripe_key': settings.STRIPE_API_PUBLIC_KEY,
+ 'site_url': reverse('datacenterlight:index'),
+ 'login_form': HostingUserLoginForm(prefix='login_form'),
+ 'billing_address_form': billing_address_form,
+ 'cms_integration': get_cms_integration('default'),
+ })
+
+ if ('generic_payment_type' in self.request.session and
+ self.request.session['generic_payment_type'] == 'generic'):
+ if 'product_id' in self.request.session:
+ product = GenericProduct.objects.get(
+ id=self.request.session['product_id']
+ )
+ context.update({'generic_payment_form': ProductPaymentForm(
+ prefix='generic_payment_form',
+ initial={'product_name': product.product_name,
+ 'amount': float(product.get_actual_price()),
+ 'recurring': product.product_is_subscription,
+ 'description': product.product_description,
+ },
+ product_id=product.id
+ ), })
+ else:
+ context.update({'generic_payment_form': GenericPaymentForm(
+ prefix='generic_payment_form',
+ ), })
+ else:
+ context.update({
+ 'vm_pricing': VMPricing.get_vm_pricing_by_name(
+ self.request.session['specs']['pricing_name']
+ )
+ })
+
+ return context
+
+ def get(self, request, *args, **kwargs):
+ for k in ['vat_validation_status', 'card_id', 'token', 'id_payment_method']:
+ if k in request.session:
+ request.session.pop(k)
+ logger.debug("Session: %s" % str(request.session))
+ for key, value in request.session.items():
+ logger.debug("Session: %s %s" % (key, value))
+ if (('type' in request.GET and request.GET['type'] == 'generic')
+ or 'product_slug' in kwargs):
+ request.session['generic_payment_type'] = 'generic'
+ if 'generic_payment_details' in request.session:
+ request.session.pop('generic_payment_details')
+ request.session.pop('product_id')
+ if 'product_slug' in kwargs:
+ logger.debug("Product slug is " + kwargs['product_slug'])
+ try:
+ product = GenericProduct.objects.get(
+ product_slug=kwargs['product_slug']
+ )
+ except GenericProduct.DoesNotExist as dne:
+ logger.error(
+ "Product '{}' does "
+ "not exist".format(kwargs['product_slug'])
+ )
+ raise Http404()
+ request.session['product_id'] = product.id
+ elif 'specs' not in request.session:
+ return HttpResponseRedirect(reverse('datacenterlight:index'))
+ return self.render_to_response(self.get_context_data())
+
+ def post(self, request, *args, **kwargs):
+ if 'product' in request.POST:
+ # query for the supplied product
+ product = None
+ try:
+ product = GenericProduct.objects.get(
+ id=request.POST['generic_payment_form-product_name']
+ )
+ except GenericProduct.DoesNotExist as dne:
+ logger.error(
+ "The requested product '{}' does not exist".format(
+ request.POST['generic_payment_form-product_name']
+ )
+ )
+ except GenericProduct.MultipleObjectsReturned as mpe:
+ logger.error(
+ "There seem to be more than one product with "
+ "the name {}".format(
+ request.POST['generic_payment_form-product_name']
+ )
+ )
+ product = GenericProduct.objects.all(
+ product_name=request.
+ POST['generic_payment_form-product_name']
+ ).first()
+ if product is None:
+ return JsonResponse({})
+ else:
+ return JsonResponse({
+ 'amount': product.get_actual_price(),
+ 'isSubscription': product.product_is_subscription
+ })
+ if 'login_form' in request.POST:
+ login_form = HostingUserLoginForm(
+ data=request.POST, prefix='login_form'
+ )
+ if login_form.is_valid():
+ email = login_form.cleaned_data.get('email')
+ password = login_form.cleaned_data.get('password')
+ auth_user = authenticate(email=email, password=password)
+ if auth_user:
+ login(self.request, auth_user)
+ if 'product_slug' in kwargs:
+ return HttpResponseRedirect(
+ reverse('show_product',
+ kwargs={
+ 'product_slug': kwargs['product_slug']}
+ )
+ )
+ return HttpResponseRedirect(
+ reverse('datacenterlight:payment')
+ )
+ else:
+ context = self.get_context_data()
+ context['login_form'] = login_form
+ return self.render_to_response(context)
+ if request.user.is_authenticated():
+ address_form = BillingAddressForm(
+ data=request.POST,
+ )
+ else:
+ address_form = BillingAddressFormSignup(
+ data=request.POST,
+ )
+ if address_form.is_valid():
+ # Check if we are in a generic payment case and handle the generic
+ # payment details form before we go on to verify payment
+ if ('generic_payment_type' in request.session and
+ self.request.session['generic_payment_type'] == 'generic'):
+ if 'product_id' in request.session:
+ generic_payment_form = ProductPaymentForm(
+ data=request.POST, prefix='generic_payment_form',
+ product_id=request.session['product_id']
+ )
+ else:
+ generic_payment_form = GenericPaymentForm(
+ data=request.POST, prefix='generic_payment_form'
+ )
+ if generic_payment_form.is_valid():
+ logger.debug("Generic payment form is valid.")
+ if 'product_id' in request.session:
+ product = generic_payment_form.product
+ else:
+ product = generic_payment_form.cleaned_data.get(
+ 'product_name'
+ )
+ user_country_vat_rate = get_vat_rate_for_country(
+ address_form.cleaned_data["country"]
+ )
+ gp_details = {
+ "product_name": product.product_name,
+ "vat_rate": 0 if product.exclude_vat_calculations else
+ user_country_vat_rate * 100,
+ "vat_amount": 0 if product.exclude_vat_calculations
+ else round(
+ float(product.product_price) *
+ user_country_vat_rate, 2),
+ "vat_country": address_form.cleaned_data["country"],
+ "amount_before_vat": round(
+ float(product.product_price), 2),
+ "amount": product.get_actual_price(
+ vat_rate=get_vat_rate_for_country(
+ address_form.cleaned_data["country"])
+ ),
+ "recurring": generic_payment_form.cleaned_data.get(
+ 'recurring'
+ ),
+ "description": generic_payment_form.cleaned_data.get(
+ 'description'
+ ),
+ "product_id": product.id,
+ "product_slug": product.product_slug,
+ "recurring_interval":
+ product.product_subscription_interval,
+ "exclude_vat_calculations": product.exclude_vat_calculations
+ }
+ request.session["generic_payment_details"] = (
+ gp_details
+ )
+ else:
+ logger.debug("Generic payment form invalid")
+ context = self.get_context_data()
+ context['generic_payment_form'] = generic_payment_form
+ context['billing_address_form'] = address_form
+ return self.render_to_response(context)
+ id_payment_method = self.request.POST.get('id_payment_method',
+ None)
+ if id_payment_method == 'undefined':
+ id_payment_method = address_form.cleaned_data.get('card')
+ request.session["id_payment_method"] = id_payment_method
+ logger.debug("id_payment_method is %s" % id_payment_method)
+ if request.user.is_authenticated():
+ this_user = {
+ 'email': request.user.email,
+ 'name': request.user.name
+ }
+ customer = StripeCustomer.get_or_create(
+ email=this_user.get('email'),
+ id_payment_method=id_payment_method
+ )
+ else:
+ user_email = address_form.cleaned_data.get('email')
+ user_name = address_form.cleaned_data.get('name')
+ this_user = {
+ 'email': user_email,
+ 'name': user_name
+ }
+ try:
+ custom_user = CustomUser.objects.get(email=user_email)
+ customer = StripeCustomer.objects.filter(
+ user_id=custom_user.id).first()
+ if customer is None:
+ logger.debug(
+ ("User {email} is already registered with us."
+ "But, StripeCustomer does not exist for {email}."
+ "Hence, creating a new StripeCustomer.").format(
+ email=user_email
+ )
+ )
+ customer = StripeCustomer.create_stripe_api_customer(
+ email=user_email,
+ id_payment_method=id_payment_method,
+ customer_name=user_name)
+ except CustomUser.DoesNotExist:
+ logger.debug(
+ ("StripeCustomer does not exist for {email}."
+ "Hence, creating a new StripeCustomer.").format(
+ email=user_email
+ )
+ )
+ customer = StripeCustomer.create_stripe_api_customer(
+ email=user_email,
+ id_payment_method=id_payment_method,
+ customer_name=user_name)
+
+ billing_address = address_form.save()
+ request.session["billing_address_id"] = billing_address.id
+ request.session['billing_address_data'] = address_form.cleaned_data
+ request.session['user'] = this_user
+ # Get or create stripe customer
+ if not customer:
+ address_form.add_error(
+ "__all__", "Invalid credit card"
+ )
+ return self.render_to_response(
+ self.get_context_data(
+ billing_address_form=address_form
+ )
+ )
+ if type(customer) is StripeCustomer:
+ request.session['customer'] = customer.stripe_id
+ else:
+ request.session['customer'] = customer
+
+ vat_number = address_form.cleaned_data.get('vat_number').strip()
+ if vat_number:
+ validate_result = validate_vat_number(
+ stripe_customer_id=request.session['customer'],
+ billing_address_id=billing_address.id
+ )
+
+ if 'error' in validate_result and validate_result['error']:
+ messages.add_message(
+ request, messages.ERROR, validate_result["error"],
+ extra_tags='vat_error'
+ )
+ return HttpResponseRedirect(
+ reverse('datacenterlight:payment') + '#vat_error'
+ )
+ request.session["vat_validation_status"] = validate_result["status"]
+
+ # For generic payment we take the user directly to confirmation
+ if ('generic_payment_type' in request.session and
+ self.request.session['generic_payment_type'] == 'generic'):
+ return HttpResponseRedirect(
+ reverse('datacenterlight:order_confirmation'))
+ else:
+ self.request.session['order_confirm_url'] = reverse('datacenterlight:order_confirmation')
+ return HttpResponseRedirect(
+ reverse('datacenterlight:add_ssh_key'))
+ else:
+ context = self.get_context_data()
+ context['billing_address_form'] = address_form
+ return self.render_to_response(context)
+
+
+class OrderConfirmationView(DetailView, FormView):
+ form_class = UserHostingKeyForm
+ template_name = "datacenterlight/order_detail.html"
+ payment_template_name = 'datacenterlight/landing_payment.html'
+ context_object_name = "order"
+ model = HostingOrder
+
+ def get_form_kwargs(self):
+ kwargs = super(OrderConfirmationView, self).get_form_kwargs()
+ kwargs.update({'request': self.request})
+ return kwargs
+
+ @cache_control(no_cache=True, must_revalidate=True, no_store=True)
+ def get(self, request, *args, **kwargs):
+ context = {}
+ # this is amount to be charge/subscribed before VAT and discount
+ # and expressed in chf. To convert to cents, multiply by 100
+ amount_to_charge = 0
+ vm_specs = None
+ if (('specs' not in request.session or 'user' not in request.session)
+ and 'generic_payment_type' not in request.session):
+ return HttpResponseRedirect(reverse('datacenterlight:index'))
+ if 'id_payment_method' in self.request.session:
+ payment_method = self.request.session['id_payment_method']
+ logger.debug("id_payment_method: %s" % payment_method)
+ stripe_utils = StripeUtils()
+ card_details = stripe_utils.get_cards_details_from_payment_method(
+ payment_method
+ )
+ if not card_details.get('response_object'):
+ return HttpResponseRedirect(reverse('datacenterlight:payment'))
+ card_details_response = card_details['response_object']
+ context['cc_last4'] = card_details_response['last4']
+ context['cc_brand'] = card_details_response['brand']
+ context['cc_exp_year'] = card_details_response['exp_year']
+ context['cc_exp_month'] = '{:02d}'.format(
+ card_details_response['exp_month'])
+ context['id_payment_method'] = payment_method
+ else:
+ # TODO check when we go through this case (to me, it seems useless)
+ card_id = self.request.session.get('card_id')
+ logger.debug("NO id_payment_method, using card: %s" % card_id)
+ card_detail = UserCardDetail.objects.get(id=card_id)
+ context['cc_last4'] = card_detail.last4
+ context['cc_brand'] = card_detail.brand
+ context['cc_exp_year'] = card_detail.exp_year
+ context['cc_exp_month'] ='{:02d}'.format(card_detail.exp_month)
+
+ if ('generic_payment_type' in request.session and
+ self.request.session['generic_payment_type'] == 'generic'):
+ if "vat_validation_status" in request.session and (
+ request.session["vat_validation_status"] == "verified" or
+ request.session["vat_validation_status"] == "not_needed"):
+ request.session['generic_payment_details']['vat_rate'] = 0
+ request.session['generic_payment_details']['vat_amount'] = 0
+ request.session['generic_payment_details']['amount'] = (
+ request.session['generic_payment_details']['amount_before_vat']
+ )
+ context.update({
+ 'generic_payment_details':
+ request.session['generic_payment_details'],
+ })
+ amount_to_charge = request.session['generic_payment_details']['amount']
+ else:
+ vm_specs = request.session.get('specs')
+ user_vat_country = (
+ request.session.get('billing_address_data').get("country")
+ )
+ user_country_vat_rate = get_vat_rate_for_country(user_vat_country)
+ price, vat, vat_percent, discount = get_vm_price_for_given_vat(
+ cpu=vm_specs['cpu'],
+ memory=vm_specs['memory'],
+ ssd_size=vm_specs['disk_size'],
+ pricing_name=vm_specs['pricing_name'],
+ vat_rate=user_country_vat_rate * 100
+ )
+ vm_specs["price"] = price
+ vm_specs["price_after_discount"] = price - discount["amount"]
+ amount_to_charge = price
+ vat_number = request.session.get('billing_address_data').get("vat_number")
+ billing_address = BillingAddress.objects.get(
+ id=request.session["billing_address_id"])
+ if vat_number:
+ validate_result = validate_vat_number(
+ stripe_customer_id=request.session['customer'],
+ billing_address_id=billing_address.id
+ )
+ if 'error' in validate_result and validate_result['error']:
+ messages.add_message(
+ request, messages.ERROR, validate_result["error"],
+ extra_tags='vat_error'
+ )
+ return HttpResponseRedirect(
+ reverse('datacenterlight:payment') + '#vat_error'
+ )
+ request.session["vat_validation_status"] = validate_result["status"]
+
+ if user_vat_country.lower() == "ch":
+ vm_specs["vat"] = vat
+ vm_specs["vat_percent"] = vat_percent
+ vm_specs["vat_validation_status"] = "ch_vat"
+ elif ("vat_validation_status" in request.session and
+ (request.session["vat_validation_status"] == "verified" or
+ request.session["vat_validation_status"] == "not_needed")):
+ vm_specs["vat_percent"] = 0
+ vm_specs["vat"] = 0
+ vm_specs["vat_validation_status"] = request.session["vat_validation_status"]
+ else:
+ vm_specs["vat"] = vat
+ vm_specs["vat_percent"] = vat_percent
+ vm_specs["vat_validation_status"] = request.session["vat_validation_status"] if "vat_validation_status" in request.session else ""
+ vm_specs["vat_country"] = user_vat_country
+ vm_specs["price_with_vat"] = round(price * (1 + vm_specs["vat_percent"] * 0.01), 2)
+ vm_specs["price_after_discount"] = round(price - discount['amount'], 2)
+ vm_specs["price_after_discount_with_vat"] = round((price - discount['amount']) * (1 + vm_specs["vat_percent"] * 0.01), 2)
+ discount["amount_with_vat"] = round(vm_specs["price_with_vat"] - vm_specs["price_after_discount_with_vat"], 2)
+ vm_specs["total_price"] = vm_specs["price_after_discount_with_vat"]
+ vm_specs["discount"] = discount
+ logger.debug(vm_specs)
+ request.session['specs'] = vm_specs
+
+ context.update({
+ 'vm': vm_specs,
+ 'form': UserHostingKeyForm(request=self.request),
+ 'keys': get_all_public_keys(self.request.user)
+ })
+
+ is_subscription = False
+ if ('generic_payment_type' not in request.session or
+ (request.session['generic_payment_details']['recurring'])):
+ # Obtain PaymentIntent so that we can initiate and charge
+ # the customer
+ is_subscription = True
+ logger.debug("CASE: Subscription")
+ else:
+ logger.debug("CASE: One time payment")
+ stripe_utils = StripeUtils()
+ payment_intent_response = stripe_utils.get_payment_intent(
+ int(amount_to_charge * 100),
+ customer=request.session['customer']
+ )
+ payment_intent = payment_intent_response.get(
+ 'response_object')
+ if not payment_intent:
+ logger.error("Could not create payment_intent %s" %
+ str(payment_intent_response))
+ else:
+ logger.debug("payment_intent.client_secret = %s" %
+ str(payment_intent.client_secret))
+ context.update({
+ 'payment_intent_secret': payment_intent.client_secret
+ })
+ logger.debug("Request %s" % create_incomplete_intent_request(
+ self.request))
+ logger.debug("%s" % str(payment_intent))
+ logger.debug("customer %s" % request.session['customer'])
+ logger.debug("card_details_response %s" % card_details_response)
+ logger.debug("request.session[generic_payment_details] %s" % request.session["generic_payment_details"])
+ logger.debug("request.session[billing_address_data] %s" % request.session["billing_address_data"])
+ IncompletePaymentIntents.objects.create(
+ request=create_incomplete_intent_request(self.request),
+ payment_intent_id=payment_intent.id,
+ stripe_api_cus_id=request.session['customer'],
+ card_details_response=json.dumps(card_details_response),
+ stripe_subscription_id=None,
+ stripe_charge_id=None,
+ gp_details=json.dumps(request.session["generic_payment_details"]),
+ billing_address_data=json.dumps(request.session["billing_address_data"])
+ )
+ logger.debug("IncompletePaymentIntent done")
+
+ context.update({
+ 'site_url': reverse('datacenterlight:index'),
+ 'page_header_text': _('Confirm Order'),
+ 'billing_address_data': (
+ request.session.get('billing_address_data')
+ ),
+ 'cms_integration': get_cms_integration('default'),
+ 'error_msg': get_error_response_dict("Error", request),
+ 'success_msg': {
+ 'msg_title': _("Thank you !"),
+ 'msg_body': _("Your product will be provisioned as soon as "
+ "we receive the payment."),
+ 'redirect': reverse('hosting:invoices') if
+ request.user.is_authenticated() else
+ reverse('datacenterlight:index')
+ },
+ 'stripe_key': settings.STRIPE_API_PUBLIC_KEY,
+ 'is_subscription': str(is_subscription).lower()
+ })
+ return render(request, self.template_name, context)
+
+ def post(self, request, *args, **kwargs):
+ stripe_onetime_charge = None
+ stripe_customer_obj = None
+ gp_details = None
+ specs = None
+ vm_template_id = 0
+ template = None
+ user = request.session.get('user')
+ stripe_api_cus_id = request.session.get('customer')
+ stripe_utils = StripeUtils()
+ logger.debug("user=%s stripe_api_cus_id=%s" % (user, stripe_api_cus_id))
+ card_details_response = None
+ new_user_hosting_key_id = None
+ card_id = None
+ generic_payment_type = None
+ generic_payment_details = None
+ stripe_subscription_obj = None
+ if 'generic_payment_details' in request.session:
+ generic_payment_details = request.session[
+ 'generic_payment_details']
+ if 'generic_payment_type' in request.session:
+ generic_payment_type = request.session['generic_payment_type']
+ if 'new_user_hosting_key_id' in self.request.session:
+ new_user_hosting_key_id = request.session[
+ 'new_user_hosting_key_id']
+ if 'card_id' in request.session:
+ card_id = request.session.get('card_id')
+ req = {
+ 'scheme': self.request.scheme,
+ 'host': self.request.get_host(),
+ 'language': get_language(),
+ 'new_user_hosting_key_id': new_user_hosting_key_id,
+ 'card_id': card_id,
+ 'generic_payment_type': generic_payment_type,
+ 'generic_payment_details': generic_payment_details,
+ 'user': user
+ }
+
+ if 'id_payment_method' in request.session:
+ card_details = stripe_utils.get_cards_details_from_payment_method(
+ request.session.get('id_payment_method')
+ )
+ logger.debug(
+ "card_details=%s" % (card_details))
+ if not card_details.get('response_object'):
+ msg = card_details.get('error')
+ return show_error(msg, self.request)
+ card_details_response = card_details['response_object']
+ card_details_dict = {
+ 'last4': card_details_response['last4'],
+ 'brand': card_details_response['brand'],
+ 'card_id': card_details_response['card_id']
+ }
+ stripe_customer_obj = StripeCustomer.objects.filter(
+ stripe_id=stripe_api_cus_id).first()
+ if stripe_customer_obj:
+ ucd = UserCardDetail.get_user_card_details(
+ stripe_customer_obj, card_details_response
+ )
+ if not ucd:
+ acc_result = stripe_utils.associate_customer_card(
+ stripe_api_cus_id, request.session['id_payment_method'],
+ set_as_default=True
+ )
+ if acc_result['response_object'] is None:
+ msg = _(
+ 'An error occurred while associating the card.'
+ ' Details: {details}'.format(
+ details=acc_result['error']
+ )
+ )
+ return show_error(msg, self.request)
+ else:
+ # Associate PaymentMethod with the stripe customer
+ # and set it as the default source
+ acc_result = stripe_utils.associate_customer_card(
+ stripe_api_cus_id, request.session['id_payment_method'],
+ set_as_default=True
+ )
+ if acc_result['response_object'] is None:
+ msg = _(
+ 'An error occurred while associating the card.'
+ ' Details: {details}'.format(
+ details=acc_result['error']
+ )
+ )
+ return show_error(msg, self.request)
+ elif 'card_id' in request.session:
+ card_id = request.session.get('card_id')
+ user_card_detail = UserCardDetail.objects.get(id=card_id)
+ card_details_dict = {
+ 'last4': user_card_detail.last4,
+ 'brand': user_card_detail.brand,
+ 'card_id': user_card_detail.card_id
+ }
+ UserCardDetail.set_default_card(
+ stripe_api_cus_id=stripe_api_cus_id,
+ stripe_source_id=user_card_detail.card_id
+ )
+ logger.debug("card_details_dict=%s" % card_details_dict)
+ else:
+ response = {
+ 'status': False,
+ 'redirect': "{url}#{section}".format(
+ url=reverse('datacenterlight:payment'),
+ section='payment_error'),
+ 'msg_title': str(_('Error.')),
+ 'msg_body': str(
+ _('There was a payment related error.'
+ ' On close of this popup, you will be redirected back to'
+ ' the payment page.'))
+ }
+ return JsonResponse(response)
+
+ if ('generic_payment_type' in request.session and
+ self.request.session['generic_payment_type'] == 'generic'):
+ gp_details = self.request.session['generic_payment_details']
+ logger.debug("gp_details=%s" % gp_details)
+ if gp_details['recurring']:
+ # generic recurring payment
+ logger.debug("Commencing a generic recurring payment")
+ if ('generic_payment_type' not in request.session or
+ (request.session['generic_payment_details']['recurring'])):
+ recurring_interval = 'month'
+ logger.debug("'generic_payment_type' not in request.session or"
+ "(request.session['generic_payment_details']['recurring']")
+ if 'generic_payment_details' in request.session:
+ vat_percent = request.session['generic_payment_details']['vat_rate']
+ vat_country = request.session['generic_payment_details']['vat_country']
+ if 'discount' in request.session['generic_payment_details']:
+ discount = request.session['generic_payment_details']['discount']
+ else:
+ discount = {'name': '', 'amount': 0, 'coupon_id': ''}
+ amount_to_be_charged = (
+ round(
+ request.session['generic_payment_details']['amount_before_vat'],
+ 2
+ )
+ )
+ plan_name = "generic-{0}-{1:.2f}".format(
+ request.session['generic_payment_details']['product_id'],
+ amount_to_be_charged
+ )
+ stripe_plan_id = plan_name
+ recurring_interval = request.session['generic_payment_details']['recurring_interval']
+ if recurring_interval == "year":
+ plan_name = "{}-yearly".format(plan_name)
+ stripe_plan_id = plan_name
+ else:
+ template = request.session.get('template')
+ specs = request.session.get('specs')
+ vm_template_id = template.get('id', 1)
+
+ cpu = specs.get('cpu')
+ memory = specs.get('memory')
+ disk_size = specs.get('disk_size')
+ amount_to_be_charged = specs.get('price')
+ vat_percent = specs.get('vat_percent')
+ vat_country = specs.get('vat_country')
+ discount = specs.get('discount')
+ plan_name = StripeUtils.get_stripe_plan_name(
+ cpu=cpu,
+ memory=memory,
+ disk_size=disk_size,
+ price=amount_to_be_charged
+ )
+ stripe_plan_id = StripeUtils.get_stripe_plan_id(
+ cpu=cpu,
+ ram=memory,
+ ssd=disk_size,
+ version=1,
+ app='dcl',
+ price=amount_to_be_charged
+ )
+ logger.debug(specs)
+ stripe_plan = stripe_utils.get_or_create_stripe_plan(
+ amount=amount_to_be_charged,
+ name=plan_name,
+ stripe_plan_id=stripe_plan_id,
+ interval=recurring_interval
+ )
+ # Create StripeTaxRate if applicable to the user
+ logger.debug("vat_percent = %s, vat_country = %s" %
+ (vat_percent, vat_country)
+ )
+ stripe_tax_rate = None
+ if vat_percent > 0:
+ try:
+ stripe_tax_rate = StripeTaxRate.objects.get(
+ description="VAT for %s" % vat_country
+ )
+ print("Stripe Tax Rate exists")
+ except StripeTaxRate.DoesNotExist as dne:
+ print("StripeTaxRate does not exist")
+ tax_rate_obj = stripe.TaxRate.create(
+ display_name="VAT",
+ description="VAT for %s" % vat_country,
+ jurisdiction=vat_country,
+ percentage=vat_percent,
+ inclusive=False,
+ )
+ stripe_tax_rate = StripeTaxRate.objects.create(
+ display_name=tax_rate_obj.display_name,
+ description=tax_rate_obj.description,
+ jurisdiction=tax_rate_obj.jurisdiction,
+ percentage=tax_rate_obj.percentage,
+ inclusive=False,
+ tax_rate_id=tax_rate_obj.id
+ )
+ logger.debug("Created StripeTaxRate %s" %
+ stripe_tax_rate.tax_rate_id)
+ subscription_result = stripe_utils.subscribe_customer_to_plan(
+ stripe_api_cus_id,
+ [{"plan": stripe_plan.get('response_object').stripe_plan_id}],
+ coupon=(discount['stripe_coupon_id']
+ if 'name' in discount and
+ discount['name'] is not None and
+ 'ipv6' in discount['name'].lower() and
+ discount['stripe_coupon_id']
+ else ""),
+ tax_rates=[stripe_tax_rate.tax_rate_id] if stripe_tax_rate else [],
+ default_payment_method=request.session['id_payment_method']
+ )
+ stripe_subscription_obj = subscription_result.get('response_object')
+ logger.debug(stripe_subscription_obj)
+ latest_invoice = stripe.Invoice.retrieve(
+ stripe_subscription_obj.latest_invoice)
+ subscription_status = ''
+ if stripe_subscription_obj:
+ subscription_status = stripe_subscription_obj.status
+
+ # Check if the subscription was approved and is active
+ if (stripe_subscription_obj is None
+ or (stripe_subscription_obj.status != 'active'
+ and stripe_subscription_obj.status != 'incomplete')):
+ # At this point, we have created a Stripe API card and
+ # associated it with the customer; but the transaction failed
+ # due to some reason. So, we would want to dissociate this card
+ # here.
+ # ...
+ msg = subscription_result.get('error')
+ return show_error(msg, self.request)
+ elif stripe_subscription_obj.status == 'incomplete':
+ # Store params so that they can be retrieved later
+ IncompleteSubscriptions.objects.create(
+ subscription_id=stripe_subscription_obj.id,
+ subscription_status=subscription_status,
+ name=user.get('name'),
+ email=user.get('email'),
+ request=json.dumps(req),
+ stripe_api_cus_id=stripe_api_cus_id,
+ card_details_response=json.dumps(card_details_response),
+ stripe_subscription_obj=json.dumps(
+ stripe_subscription_obj) if stripe_customer_obj else '',
+ stripe_onetime_charge=json.dumps(
+ stripe_onetime_charge) if stripe_onetime_charge else '',
+ gp_details=json.dumps(gp_details) if gp_details else '',
+ specs=json.dumps(specs) if specs else '',
+ vm_template_id=vm_template_id if vm_template_id else 0,
+ template=json.dumps(template) if template else '',
+ billing_address_data=json.dumps(
+ request.session.get('billing_address_data')
+ )
+ )
+ pi = stripe.PaymentIntent.retrieve(
+ latest_invoice.payment_intent
+ )
+ # TODO: requires_attention is probably wrong value to compare
+ if request.user.is_authenticated():
+ if 'generic_payment_details' in request.session:
+ redirect_url = reverse('hosting:invoices')
+ else:
+ redirect_url = reverse('hosting:virtual_machines')
+ else:
+ redirect_url = reverse('datacenterlight:index')
+
+ if (pi.status == 'requires_attention' or
+ pi.status == 'requires_source_action'):
+ logger.debug("Display SCA authentication %s " % pi.status)
+ context = {
+ 'sid': stripe_subscription_obj.id,
+ 'payment_intent_secret': pi.client_secret,
+ 'STRIPE_PUBLISHABLE_KEY': settings.STRIPE_API_PUBLIC_KEY,
+ 'showSCA': True,
+ 'success': {
+ 'status': True,
+ 'redirect': redirect_url,
+ 'msg_title': str(_('Thank you for the order.')),
+ 'msg_body': str(
+ _('Your product will be provisioned as soon as'
+ ' we receive a payment confirmation from '
+ 'Stripe. We will send you a confirmation '
+ 'email. You can always contact us at '
+ 'support@datacenterlight.ch')
+ )
+ },
+ 'error': {
+ 'status': False,
+ 'redirect': "{url}#{section}".format(
+ url=(reverse(
+ 'show_product',
+ kwargs={'product_slug':
+ request.session[
+ 'generic_payment_details']
+ ['product_slug']}
+ ) if 'generic_payment_details' in request.session else
+ reverse('datacenterlight:payment')
+ ),
+ section='payment_error'
+ ),
+ 'msg_title': str(_('Error.')),
+ 'msg_body': str(
+ _('There was a payment related error.'
+ ' On close of this popup, you will be redirected back to'
+ ' the payment page.')
+ )
+ }
+ }
+ return JsonResponse(context)
+ else:
+ logger.debug(
+ "Handle this case when "
+ "stripe.subscription_status is incomplete but "
+ "pi.status is neither requires_attention nor "
+ "requires_source_action")
+ msg = subscription_result.get('error')
+ return show_error(msg, self.request)
+ # the code below is executed for
+ # a) subscription case
+ # b) the subscription object is active itself, without requiring
+ # SCA
+ provisioning_response = do_provisioning(
+ req, stripe_api_cus_id,
+ card_details_response, stripe_subscription_obj,
+ stripe_onetime_charge, gp_details, specs, vm_template_id,
+ template, request.session.get('billing_address_data'),
+ self.request
+ )
+
+ if (provisioning_response and
+ type(provisioning_response['response']) == JsonResponse):
+ new_user = provisioning_response.get('user', None)
+ if new_user:
+ login(self.request, new_user)
+ return provisioning_response['response']
+
+ response = {
+ 'status': True,
+ 'redirect': (
+ reverse('hosting:virtual_machines')
+ if request.user.is_authenticated()
+ else reverse('datacenterlight:index')
+ ),
+ 'msg_title': str(_('Thank you for the order.')),
+ 'msg_body': str(
+ _('Your VM will be up and running in a few moments.'
+ ' We will send you a confirmation email as soon as'
+ ' it is ready.'))
+ }
+
+ return JsonResponse(response)
+
+
+def create_incomplete_intent_request(request):
+ """
+ Creates a dictionary of all session variables so that they could be
+ picked up in the webhook for processing.
+
+ :param request:
+ :return:
+ """
+ req = {
+ 'scheme': request.scheme,
+ 'host': request.get_host(),
+ 'language': get_language(),
+ 'new_user_hosting_key_id': request.session.get(
+ 'new_user_hosting_key_id', None),
+ 'card_id': request.session.get('card_id', None),
+ 'generic_payment_type': request.session.get(
+ 'generic_payment_type', None),
+ 'generic_payment_details': request.session.get(
+ 'generic_payment_details', None),
+ 'user': request.session.get('user', None),
+ 'id_payment_method': request.session.get('id_payment_method', None),
+ }
+ return json.dumps(req)
+
+
+def get_or_create_custom_user(request, stripe_api_cus_id):
+ new_user = None
+ name = request.get('user').get('name')
+ email = request.get('user').get('email')
+
+ try:
+ custom_user = CustomUser.objects.get(email=email)
+ stripe_customer = StripeCustomer.objects.filter(
+ user_id=custom_user.id).first()
+ if stripe_customer is None:
+ stripe_customer = StripeCustomer.objects.create(
+ user=custom_user, stripe_id=stripe_api_cus_id
+ )
+ stripe_customer_id = stripe_customer.id
+ except CustomUser.DoesNotExist:
+ logger.debug(
+ "Customer {} does not exist.".format(email))
+ password = CustomUser.get_random_password()
+ base_url = "{0}://{1}".format(request['scheme'],
+ request['host'])
+ custom_user = CustomUser.register(
+ name, password,
+ email,
+ app='dcl', base_url=base_url, send_email=True,
+ account_details=password
+ )
+ logger.debug("Created user {}.".format(email))
+ stripe_customer = StripeCustomer.objects. \
+ create(user=custom_user, stripe_id=stripe_api_cus_id)
+ stripe_customer_id = stripe_customer.id
+ new_user = authenticate(username=custom_user.email,
+ password=password)
+ logger.debug("User %s is authenticated" % custom_user.email)
+ new_user_hosting_key_id = request.get('new_user_hosting_key_id', None)
+ if new_user_hosting_key_id:
+ user_hosting_key = UserHostingKey.objects.get(
+ id=new_user_hosting_key_id)
+ user_hosting_key.user = new_user
+ user_hosting_key.save()
+ logger.debug("User %s key is saved" % custom_user.email)
+ return custom_user, new_user
+
+
+def set_user_card(card_id, stripe_api_cus_id, custom_user,
+ card_details_response):
+ if card_id:
+ logger.debug("card_id %s was in request" % card_id)
+ user_card_detail = UserCardDetail.objects.get(id=card_id)
+ card_details_dict = {
+ 'last4': user_card_detail.last4,
+ 'brand': user_card_detail.brand,
+ 'card_id': user_card_detail.card_id
+ }
+ #if not user_card_detail.preferred:
+ UserCardDetail.set_default_card(
+ stripe_api_cus_id=stripe_api_cus_id,
+ stripe_source_id=user_card_detail.card_id
+ )
+ else:
+ logger.debug("card_id was NOT in request, using "
+ "card_details_response")
+ ucd = UserCardDetail.get_or_create_user_card_detail(
+ stripe_customer=custom_user.stripecustomer,
+ card_details=card_details_response
+ )
+ UserCardDetail.save_default_card_local(
+ custom_user.stripecustomer.stripe_id,
+ ucd.card_id
+ )
+ card_details_dict = {
+ 'last4': ucd.last4,
+ 'brand': ucd.brand,
+ 'card_id': ucd.card_id
+ }
+ return card_details_dict
+
+
+def do_provisioning_generic(
+ request, stripe_api_cus_id, card_details_response,
+ stripe_subscription_id, stripe_charge_id, gp_details,
+ billing_address_data):
+ stripe_utils = StripeUtils()
+ acc_result = stripe_utils.associate_customer_card(
+ stripe_api_cus_id, request['id_payment_method'],
+ set_as_default=True
+ )
+ """
+ Identical to do_provisioning(), except for the fact that this
+ is specific to handling provisioning of the generic products
+ """
+ logger.debug("Card %s associate result %s" % (
+ request['id_payment_method'],
+ acc_result.get('response_object')
+ ))
+ user = request.get('user', None)
+ logger.debug("generic_payment_type case")
+ custom_user, new_user = get_or_create_custom_user(
+ request, stripe_api_cus_id)
+ logger.debug("%s %s" % (custom_user.email, custom_user.id))
+
+ card_id = request.get('card_id', None)
+
+ card_details_dict = set_user_card(card_id, stripe_api_cus_id, custom_user,
+ card_details_response)
+
+ logger.debug("After card details dict %s" % str(card_details_dict))
+
+ # Save billing address
+ billing_address_data.update({
+ 'user': custom_user.id
+ })
+ logger.debug('billing_address_data is {}'.format(billing_address_data))
+
+ stripe_cus = StripeCustomer.objects.filter(
+ stripe_id=stripe_api_cus_id
+ ).first()
+ billing_address = BillingAddress(
+ cardholder_name=billing_address_data['cardholder_name'],
+ street_address=billing_address_data['street_address'],
+ city=billing_address_data['city'],
+ postal_code=billing_address_data['postal_code'],
+ country=billing_address_data['country'],
+ vat_number=billing_address_data['vat_number']
+ )
+ billing_address.save()
+
+ order = HostingOrder.create(
+ price=request['generic_payment_details']['amount'],
+ customer=stripe_cus,
+ billing_address=billing_address,
+ vm_pricing=VMPricing.get_default_pricing()
+ )
+
+ # Create a Hosting Bill
+ HostingBill.create(customer=stripe_cus,
+ billing_address=billing_address)
+
+ # Create Billing Address for User if he does not have one
+ if not stripe_cus.user.billing_addresses.count():
+ billing_address_data.update({
+ 'user': stripe_cus.user.id
+ })
+ billing_address_user_form = UserBillingAddressForm(
+ billing_address_data
+ )
+ billing_address_user_form.is_valid()
+ billing_address_user_form.save()
+
+ recurring = request['generic_payment_details'].get('recurring')
+ if recurring:
+ logger.debug("recurring case")
+ # Associate the given stripe subscription with the order
+ order.set_subscription_id(
+ stripe_subscription_id, card_details_dict
+ )
+ logger.debug("recurring case, set order subscription id done")
+ else:
+ logger.debug("one time charge case")
+ # Associate the given stripe charge id with the order
+ stripe_onetime_charge = stripe.Charge.retrieve(stripe_charge_id)
+ order.set_stripe_charge(stripe_onetime_charge)
+
+ # Set order status approved
+ order.set_approved()
+ order.generic_payment_description = gp_details["description"]
+ order.generic_product_id = gp_details["product_id"]
+ order.save()
+ logger.debug("Order saved")
+ # send emails
+ context = {
+ 'name': user.get('name'),
+ 'email': user.get('email'),
+ 'amount': gp_details['amount'],
+ 'description': gp_details['description'],
+ 'recurring': gp_details['recurring'],
+ 'product_name': gp_details['product_name'],
+ 'product_id': gp_details['product_id'],
+ 'order_id': order.id
+ }
+
+ email_data = {
+ 'subject': (settings.DCL_TEXT +
+ " Payment received from %s" % context['email']),
+ 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
+ 'to': ['dcl-orders@ungleich.ch'],
+ 'body': "\n".join(
+ ["%s=%s" % (k, v) for (k, v) in context.items()]),
+ 'reply_to': [context['email']],
+ }
+ send_plain_email_task.delay(email_data)
+ recurring_text = _(" This is a monthly recurring plan.")
+ if gp_details['recurring_interval'] == "year":
+ recurring_text = _(" This is an yearly recurring plan.")
+
+ email_data = {
+ 'subject': _("Confirmation of your payment"),
+ 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
+ 'to': [user.get('email')],
+ 'body': _("Hi {name},\n\n"
+ "thank you for your order!\n"
+ "We have just received a payment of CHF {amount:.2f}"
+ " from you.{recurring}\n\n"
+ "Cheers,\nYour Data Center Light team".format(
+ name=user.get('name'),
+ amount=gp_details['amount'],
+ recurring=(
+ recurring_text
+ if gp_details['recurring'] else ''
+ )
+ )
+ ),
+ 'reply_to': ['info@ungleich.ch'],
+ }
+ send_plain_email_task.delay(email_data)
+ redirect_url = reverse('datacenterlight:index')
+ logger.debug("Sent user/admin emails")
+ logger.debug("redirect_url = %s " % redirect_url)
+ response = {
+ 'status': True,
+ 'redirect': redirect_url,
+ 'msg_title': str(_('Thank you for the payment.')),
+ 'msg_body': str(
+ _('You will soon receive a confirmation email of the '
+ 'payment. You can always contact us at '
+ 'info@ungleich.ch for any question that you may have.')
+ )
+ }
+ logger.debug("after response")
+ logger.debug(str(response))
+ return HttpResponse(status=200)
+
+
+def do_provisioning(request, stripe_api_cus_id, card_details_response,
+ stripe_subscription_obj, stripe_onetime_charge, gp_details,
+ specs, vm_template_id, template, billing_address_data,
+ real_request):
+ """
+ :param request: a dict
+ {
+ 'scheme': 'https',
+ 'host': 'domain',
+ 'language': 'en-us',
+ 'new_user_hosting_key_id': 1,
+ 'card_id': 1, # if usercarddetail exists already,
+ 'generic_payment_type': 'generic' # represents a generic payment
+ 'generic_payment_details': {
+ 'amount': 100,
+ 'recurring':
+ },
+ 'user': {
+ 'name': 'John Doe',
+ 'email': 'john@doe.com'
+ }
+ }
+ :param stripe_api_cus_id: 'cus_xxxxxxx' the actual stripe customer id str
+ :param card_details_response:
+ :param stripe_subscription_obj: The actual Stripe's Subscription Object
+ :param stripe_onetime_charge: Stripe's Charge object
+ :param gp_details:
+ :param specs:
+ :param vm_template_id:
+ :param template:
+ :param real_request:
+ :return:
+ """
+
+ logger.debug("do_provisioning")
+ user = request.get('user', None)
+
+ # Create user if the user is not logged in and if he is not already
+ # registered
+ custom_user, new_user = get_or_create_custom_user(
+ request, stripe_api_cus_id)
+
+ card_id = request.get('card_id', None)
+
+ card_details_dict = set_user_card(card_id, stripe_api_cus_id, custom_user,
+ card_details_response)
+
+ # Save billing address
+ billing_address_data.update({
+ 'user': custom_user.id
+ })
+ logger.debug('billing_address_data is {}'.format(billing_address_data))
+
+ generic_payment_type = request.get('generic_payment_type', None)
+ if generic_payment_type:
+ logger.debug("generic_payment_type case")
+ stripe_cus = StripeCustomer.objects.filter(
+ stripe_id=stripe_api_cus_id
+ ).first()
+ billing_address = BillingAddress(
+ cardholder_name=billing_address_data['cardholder_name'],
+ street_address=billing_address_data['street_address'],
+ city=billing_address_data['city'],
+ postal_code=billing_address_data['postal_code'],
+ country=billing_address_data['country'],
+ vat_number=billing_address_data['vat_number']
+ )
+ billing_address.save()
+
+ order = HostingOrder.create(
+ price=request['generic_payment_details']['amount'],
+ customer=stripe_cus,
+ billing_address=billing_address,
+ vm_pricing=VMPricing.get_default_pricing()
+ )
+
+ # Create a Hosting Bill
+ HostingBill.create(customer=stripe_cus,
+ billing_address=billing_address)
+
+ # Create Billing Address for User if he does not have one
+ if not stripe_cus.user.billing_addresses.count():
+ billing_address_data.update({
+ 'user': stripe_cus.user.id
+ })
+ billing_address_user_form = UserBillingAddressForm(
+ billing_address_data
+ )
+ billing_address_user_form.is_valid()
+ billing_address_user_form.save()
+
+ recurring = request['generic_payment_details'].get('recurring')
+ if recurring:
+ logger.debug("recurring case")
+ # Associate the given stripe subscription with the order
+ order.set_subscription_id(
+ stripe_subscription_obj.id, card_details_dict
+ )
+ logger.debug("recurring case, set order subscription id done")
+ else:
+ logger.debug("one time charge case")
+ # Associate the given stripe charge id with the order
+ order.set_stripe_charge(stripe_onetime_charge)
+
+ # Set order status approved
+ order.set_approved()
+ order.generic_payment_description = gp_details["description"]
+ order.generic_product_id = gp_details["product_id"]
+ order.save()
+ logger.debug("Order saved")
+ # send emails
+ context = {
+ 'name': user.get('name'),
+ 'email': user.get('email'),
+ 'amount': gp_details['amount'],
+ 'description': gp_details['description'],
+ 'recurring': gp_details['recurring'],
+ 'product_name': gp_details['product_name'],
+ 'product_id': gp_details['product_id'],
+ 'order_id': order.id
+ }
+
+ email_data = {
+ 'subject': (settings.DCL_TEXT +
+ " Payment received from %s" % context['email']),
+ 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
+ 'to': ['dcl-orders@ungleich.ch'],
+ 'body': "\n".join(
+ ["%s=%s" % (k, v) for (k, v) in context.items()]),
+ 'reply_to': [context['email']],
+ }
+ send_plain_email_task.delay(email_data)
+ recurring_text = _(" This is a monthly recurring plan.")
+ if gp_details['recurring_interval'] == "year":
+ recurring_text = _(" This is an yearly recurring plan.")
+
+ email_data = {
+ 'subject': _("Confirmation of your payment"),
+ 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
+ 'to': [user.get('email')],
+ 'body': _("Hi {name},\n\n"
+ "thank you for your order!\n"
+ "We have just received a payment of CHF {amount:.2f}"
+ " from you.{recurring}\n\n"
+ "Cheers,\nYour Data Center Light team".format(
+ name=user.get('name'),
+ amount=gp_details['amount'],
+ recurring=(
+ recurring_text
+ if gp_details['recurring'] else ''
+ )
+ )
+ ),
+ 'reply_to': ['info@ungleich.ch'],
+ }
+ send_plain_email_task.delay(email_data)
+ redirect_url = reverse('datacenterlight:index')
+ logger.debug("Sent user/admin emails")
+ if real_request:
+ clear_all_session_vars(real_request)
+ if real_request.user.is_authenticated():
+ redirect_url = reverse('hosting:invoices')
+ logger.debug("redirect_url = %s " % redirect_url)
+ response = {
+ 'status': True,
+ 'redirect': redirect_url,
+ 'msg_title': str(_('Thank you for the payment.')),
+ 'msg_body': str(
+ _('You will soon receive a confirmation email of the '
+ 'payment. You can always contact us at '
+ 'info@ungleich.ch for any question that you may have.')
+ )
+ }
+ logger.debug("after response")
+ logger.debug(str(response))
+ return {'response': JsonResponse(response), 'user': new_user}
+
+ user = {
+ 'name': custom_user.name,
+ 'email': custom_user.email,
+ 'username': custom_user.username,
+ 'pass': custom_user.password,
+ 'request_scheme': request['scheme'],
+ 'request_host': request['host'],
+ 'language': request['language'],
+ }
+
+ create_vm(
+ billing_address_data, custom_user.stripecustomer.id, specs,
+ stripe_subscription_obj, card_details_dict, request,
+ vm_template_id, template, user
+ )
+
+ if real_request:
+ clear_all_session_vars(real_request)
+
+
+def get_error_response_dict(msg, request):
+ logger.error(msg)
+ response = {
+ 'status': False,
+ 'redirect': "{url}#{section}".format(
+ url=(reverse(
+ 'show_product',
+ kwargs={'product_slug':
+ request.session['generic_payment_details']
+ ['product_slug']}
+ ) if 'generic_payment_details' in request.session else
+ reverse('datacenterlight:payment')
+ ),
+ section='payment_error'
+ ),
+ 'msg_title': str(_('Error.')),
+ 'msg_body': str(
+ _('There was a payment related error.'
+ ' On close of this popup, you will be redirected back to'
+ ' the payment page.'))
+ }
+ return response
+
+
+def show_error(msg, request):
+ logger.error(msg)
+ messages.add_message(request, messages.ERROR, msg,
+ extra_tags='failed_payment')
+ return JsonResponse(get_error_response_dict(msg,request))
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..194c9bc
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,38 @@
+version: '3'
+
+services:
+ dynamicweb2:
+ build:
+ context: .
+ ports:
+ - "8000:8000"
+ volumes:
+ - dynamicweb2_vol:/app
+ depends_on:
+ - db
+ env_file:
+ - .env
+
+ nginx:
+ build:
+ context: ./nginx
+ ports:
+ - "80:80"
+ depends_on:
+ - dynamicweb2
+
+ db:
+ image: postgres:latest
+ environment:
+ POSTGRES_DB: app
+ POSTGRES_USER: app
+ POSTGRES_PASSWORD: uuiowmm3AS
+ volumes:
+ - postgres_data:/var/lib/postgresql/data
+ - postgres_socket:/var/run/postgresql
+
+volumes:
+ dynamicweb2_vol:
+ postgres_data:
+ postgres_socket:
+
diff --git a/dynamicweb2/pr_celery.py b/dynamicweb2/pr_celery.py
new file mode 100644
index 0000000..c935d9a
--- /dev/null
+++ b/dynamicweb2/pr_celery.py
@@ -0,0 +1,21 @@
+import os
+from celery import Celery
+
+# set the default Django settings module for the 'celery' program.
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dynamicweb2.settings')
+
+app = Celery('dynamicweb2')
+
+# Using a string here means the worker don't have to serialize
+# the configuration object to child processes.
+# - namespace='CELERY' means all celery-related configuration keys
+# should have a `CELERY_` prefix.
+app.config_from_object('django.conf:settings', namespace='CELERY')
+
+# Load task modules from all registered Django app configs.
+app.autodiscover_tasks()
+
+
+@app.task(bind=True)
+def debug_task(self):
+ print('Request: {0!r}'.format(self.request))
diff --git a/dynamicweb2/settings.py b/dynamicweb2/settings.py
index f1f4614..d909def 100644
--- a/dynamicweb2/settings.py
+++ b/dynamicweb2/settings.py
@@ -13,6 +13,7 @@ import dotenv
import os
from pathlib import Path
+from django.utils.translation import gettext_lazy as _
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
@@ -41,8 +42,20 @@ INSTALLED_APPS = [
'django.contrib.staticfiles',
'django.contrib.sites',
'bootstrap3',
+ 'compressor',
'guardian',
'hosting',
+ 'membership',
+ 'utils',
+ 'cms',
+ 'menus',
+ 'easy_thumbnails',
+ 'treebeard',
+ 'filer',
+ 'datacenterlight',
+ 'opennebula_api',
+ 'sekizai',
+ 'webhook'
]
MIDDLEWARE = [
@@ -53,6 +66,7 @@ MIDDLEWARE = [
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
+ 'django.middleware.locale.LocaleMiddleware',
]
ROOT_URLCONF = 'dynamicweb2.urls'
@@ -76,7 +90,7 @@ TEMPLATES = [
"django.template.context_processors.static", # Updated import
"django.template.context_processors.tz", # Updated import
"django.contrib.messages.context_processors.messages",
- 'hosting.context_processor.google_analytics',
+ 'sekizai.context_processors.sekizai',
],
},
},
@@ -86,14 +100,31 @@ TEMPLATES = [
WSGI_APPLICATION = 'dynamicweb2.wsgi.application'
+def env(env_name):
+ env_name = os.environ.get(env_name)
+ return env_name if env_name else '0'
+
# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
+DB_USER=env('POSTGRES_USER')
+DB_PASS=env('POSTGRES_PASSWORD')
+DB_HOST=env('POSTGRES_HOST')
+DB_NAME=env('POSTGRES_DB')
+
DATABASES = {
'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': BASE_DIR / 'db.sqlite3',
+ 'ENGINE': 'django.db.backends.postgresql_psycopg2',
+ 'NAME': DB_NAME,
+ 'HOST': DB_HOST,
+ 'PASSWORD': DB_PASS,
+ 'USER': DB_USER,
+ 'PORT': ''
}
+ # 'default': {
+ # 'ENGINE': 'django.db.backends.sqlite3',
+ # 'NAME': BASE_DIR / 'db.sqlite3',
+ # }
}
@@ -137,6 +168,7 @@ STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
+ 'compressor.finders.CompressorFinder'
)
# Default primary key field type
@@ -145,9 +177,6 @@ STATICFILES_FINDERS = (
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
-def env(env_name):
- return os.environ.get(env_name)
-
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env('SECRET_KEY')
@@ -182,9 +211,9 @@ STRIPE_API_PRIVATE_KEY = env('STRIPE_API_PRIVATE_KEY')
STRIPE_API_PUBLIC_KEY = env('STRIPE_API_PUBLIC_KEY')
STRIPE_API_PRIVATE_KEY_TEST = env('STRIPE_API_PRIVATE_KEY_TEST')
-GUARDIAN_GET_INIT_ANONYMOUS_USER = 'hosting.models.get_anonymous_user_instance'
+GUARDIAN_GET_INIT_ANONYMOUS_USER = 'membership.models.get_anonymous_user_instance'
-AUTH_USER_MODEL = 'hosting.CustomUser'
+AUTH_USER_MODEL = 'membership.CustomUser'
AUTHENTICATION_BACKENDS = (
'dynamicweb2.backend.UngleichLDAPBackend',
@@ -271,3 +300,52 @@ VM_BASE_PRICE = float(env('VM_BASE_PRICE'))
# # Handle the case where the site doesn't exist
# pass
+# The oneadmin user name of the OpenNebula infrastructure
+OPENNEBULA_USERNAME = env('OPENNEBULA_USERNAME')
+
+# The oneadmin password of the OpenNebula infrastructure
+# The default credentials of the Sandbox OpenNebula VM is
+# oneadmin:opennebula
+OPENNEBULA_PASSWORD = env('OPENNEBULA_PASSWORD')
+
+# The protocol is generally http or https
+OPENNEBULA_PROTOCOL = env('OPENNEBULA_PROTOCOL')
+
+# The ip address or the domain name of the opennebula infrastructure
+OPENNEBULA_DOMAIN = env('OPENNEBULA_DOMAIN')
+
+# The port to connect in order to send an xmlrpc request. The default
+# port is 2633
+OPENNEBULA_PORT = env('OPENNEBULA_PORT')
+
+# The endpoint to which the XML RPC request needs to be sent to. The
+# default value is /RPC2
+OPENNEBULA_ENDPOINT = env('OPENNEBULA_ENDPOINT')
+
+# The public ssh key of the oneadmin user
+ONEADMIN_USER_SSH_PUBLIC_KEY = env('ONEADMIN_USER_SSH_PUBLIC_KEY')
+
+CELERY_MAX_RETRIES = 1
+
+BYPASS_OPENNEBULA = True
+
+SITE_ID = 1
+
+ANONYMOUS_USER_NAME = 'anonymous@ungleich.ch'
+
+GUARDIAN_GET_INIT_ANONYMOUS_USER = 'membership.models.get_anonymous_user_instance'
+
+LANGUAGES = (
+ ('en-us', _('English')),
+ ('de', _('Deutsch')),
+)
+
+LANGUAGE_CODE = 'en-us'
+
+USE_I18N = True
+
+USE_L10N = True
+
+LOCALE_PATHS = [
+ os.path.join(PROJECT_DIR, 'locale'),
+]
\ No newline at end of file
diff --git a/dynamicweb2/urls.py b/dynamicweb2/urls.py
index a681735..14c3e96 100644
--- a/dynamicweb2/urls.py
+++ b/dynamicweb2/urls.py
@@ -14,14 +14,95 @@ Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
+# from django.contrib import admin
+# from django.urls import re_path, path, include
+# from datacenterlight.views import PaymentOrderView
+#
+# urlpatterns = [
+# path('admin/', admin.site.urls),
+# re_path('hosting/', include('hosting.urls')),
+# re_path(r'^product/(?P[\w-]+)/$',
+# PaymentOrderView.as_view(),
+# name='show_product'),
+# ]
+
+
+from cms.models.pagemodel import Page
+from django.urls import include, re_path, path
from django.contrib import admin
-from django.urls import re_path, path, include
-from hosting.views import PaymentOrderView
+from django.contrib.sites.models import Site
+from django.conf.urls.i18n import i18n_patterns
+from django.conf.urls.static import static
+from django.views import i18n, static as static_view
+
+from django.conf import settings
+
+import hosting
+from hosting.views import (
+ RailsHostingView, DjangoHostingView, NodeJSHostingView
+)
+from datacenterlight.views import PaymentOrderView
+from webhook import views as webhook_views
+from membership import urls as membership_urls
+from ungleich_page.views import LandingView
+from django.views.generic import RedirectView
+from django.urls import reverse_lazy
+from django.views.static import serve as static_serve
+
urlpatterns = [
- path('admin/', admin.site.urls),
- re_path('hosting/', include('hosting.urls')),
- re_path(r'^product/(?P[\w-]+)/$',
- PaymentOrderView.as_view(),
- name='show_product'),
-]
\ No newline at end of file
+ re_path('^admin/', admin.site.urls),
+ re_path(r'^index.html$', LandingView.as_view()),
+ # re_path(r'^open_api/', include('opennebula_api.urls', namespace='opennebula_api',), name="opennebula_api"),
+ re_path(r'^railshosting/', RailsHostingView.as_view(), name="rails.hosting"),
+ re_path(r'^nodehosting/', NodeJSHostingView.as_view(), name="node.hosting"),
+ re_path(r'^djangohosting/', DjangoHostingView.as_view(), name="django.hosting"),
+ re_path(r'^product/(?P[\w-]+)/$', PaymentOrderView.as_view(), name='show_product'),
+ path('hosting/', include('hosting.urls')),
+ path('datacenterlight/', include('datacenterlight.urls'), name='datacenterlight'),
+ path('i18n/', include('django.conf.urls.i18n')), # Language switcher URL
+ re_path(r'^cms/', include('cms.urls')),
+]
+urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
+
+# urlpatterns += i18n_patterns(
+#
+# # Add other internationalized patterns here if needed
+# )
+
+
+
+# note the django CMS URLs included via i18n_patterns
+REDIRECT_TO_CMS = False
+# if Page.objects.filter(site_id=Site.objects.get_current().id).count():
+# REDIRECT_TO_CMS = True
+
+# urlpatterns += i18n_patterns(
+# path('admin/', admin.site.urls),
+# re_path(r'^datacenterlight/',
+# include(('datacenterlight.urls', 'datacenterlight'), namespace="datacenterlight")),
+# re_path(r'^hosting/', RedirectView.as_view(url=reverse_lazy('hosting:login')),
+# name='redirect_hosting_login'),
+# re_path(r'^membership/', include(membership_urls)),
+# #re_path(r'^cms/blog/', include('ungleich.urls', namespace='ungleich')),
+# #re_path(r'^blog/(?P\d{4})/(?P\d{1,2})/(?P\d{1,2})/(?P\w[-\w]*)/$',
+# # RedirectView.as_view(pattern_name='ungleich:post-detail')),
+# #re_path(r'^blog/$',
+# # RedirectView.as_view(url=reverse_lazy('ungleich:post-list')),
+# # name='blog_list_view'),
+# re_path(r'^cms/', include('cms.urls')),
+# #re_path(r'^blog/', include('djangocms_blog.urls', namespace='djangocms_blog')),
+# re_path(r'^webhooks/', webhook_views.handle_webhook),
+# re_path(r'^$', RedirectView.as_view(url='/cms') if REDIRECT_TO_CMS else LandingView.as_view()),
+# re_path(r'^', include(('ungleich_page.urls', 'ungleich_page'), namespace='ungleich_page')),
+# )
+
+# urlpatterns += [
+# # re_path(r'^media/(?P.*)$',
+# # static_view.serve, {
+# # 'document_root': settings.MEDIA_ROOT,
+# # }),
+# re_path(r'^media/(?P.*)$', static_serve, {
+# 'document_root': settings.MEDIA_ROOT,
+# }),
+# ]
\ No newline at end of file
diff --git a/hosting/README-opennebula-integration.md b/hosting/README-opennebula-integration.md
new file mode 100755
index 0000000..7f6251a
--- /dev/null
+++ b/hosting/README-opennebula-integration.md
@@ -0,0 +1,41 @@
+Here are the steps to follow for running opennebula-integration correctly.
+
+1. Install [python-oca](https://github.com/python-oca/python-oca)
+This is the library that allows sending XMLRPC commands to OpenNebula. Unfortunately, the latest version of oca available in Python package index is not compatible with python 3.5. Hence, one would need to download the latest version from the above github link and install it from there.
+Assuming virtualenv is located at ~/python/env
+
+```
+~/python/env/bin/python setup.py build
+sudo ~/python/env/bin/python setup.py install
+```
+
+2. Setup opennebula parameters in the `.env` file.
+
+```
+#############################################
+# configurations for opennebula-integration #
+#############################################
+
+# The oneadmin user name of the OpenNebula infrastructure
+OPENNEBULA_USERNAME='oneadmin'
+
+# The oneadmin password of the OpenNebula infrastructure
+# The default credentials of the Sandbox OpenNebula VM is
+# oneadmin:opennebula
+OPENNEBULA_PASSWORD='opennebula'
+
+# The protocol is generally http or https
+OPENNEBULA_PROTOCOL='http'
+
+# The ip address or the domain name of the opennebula infrastructure
+OPENNEBULA_DOMAIN='192.168.182.124'
+
+# The port to connect in order to send an xmlrpc request. The default
+# port is 2633
+OPENNEBULA_PORT='2633'
+
+# The endpoint to which the XML RPC request needs to be sent to. The
+# default value is /RPC2
+OPENNEBULA_ENDPOINT='/RPC2'
+```
+
diff --git a/hosting/admin.py b/hosting/admin.py
old mode 100644
new mode 100755
index 8c38f3f..dc476b4
--- a/hosting/admin.py
+++ b/hosting/admin.py
@@ -1,3 +1,8 @@
from django.contrib import admin
-# Register your models here.
+from .models import HostingOrder, HostingBill, HostingPlan, GenericProduct
+
+admin.site.register(HostingOrder)
+admin.site.register(HostingBill)
+admin.site.register(HostingPlan)
+admin.site.register(GenericProduct)
diff --git a/hosting/apps.py b/hosting/apps.py
deleted file mode 100644
index 2d16ff8..0000000
--- a/hosting/apps.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from django.apps import AppConfig
-
-
-class HostingConfig(AppConfig):
- default_auto_field = 'django.db.models.BigAutoField'
- name = 'hosting'
diff --git a/hosting/context_processor.py b/hosting/context_processor.py
deleted file mode 100644
index adcba29..0000000
--- a/hosting/context_processor.py
+++ /dev/null
@@ -1,32 +0,0 @@
-from django.conf import settings
-
-
-def google_analytics(request):
- """
- Use the variables returned in this function to
- render your Google Analytics tracking code template.
-
- Also check whether the site is a tenant site and create a corresponding
- variable to indicate this
- """
- return_dict = {}
- host = request.get_host()
- if getattr(settings, 'GOOGLE_ANALYTICS_PROPERTY_IDS', False):
- ga_prop_id = getattr(settings, 'GOOGLE_ANALYTICS_PROPERTY_IDS').get(
- host)
- which_urlspy = settings.MULTISITE_CMS_URLS.get(host)
- if ga_prop_id is None:
- # Try checking if we have a www in host, if yes we remove
- # that and check in the dict again
- if host.startswith('www.'):
- ga_prop_id = getattr(settings, 'GOOGLE_ANALYTICS_PROPERTY_IDS',
- False).get(host[4:])
- which_urlspy = settings.MULTISITE_CMS_URLS.get(host[4:])
-
- if not settings.DEBUG and ga_prop_id:
- return_dict['GOOGLE_ANALYTICS_PROPERTY_ID'] = ga_prop_id
- if which_urlspy:
- if which_urlspy.endswith("multi"):
- return_dict['IS_TENANT_SITE'] = True
-
- return return_dict
diff --git a/hosting/forms.py b/hosting/forms.py
old mode 100644
new mode 100755
index efe8428..55599cd
--- a/hosting/forms.py
+++ b/hosting/forms.py
@@ -1,155 +1,20 @@
-from django import forms
-
-from .models import CustomUser, BillingAddress, UserBillingAddress
-from django.utils.translation import gettext_lazy as _
import datetime
+import html
import logging
import subprocess
import tempfile
-import xml
from django import forms
from django.conf import settings
from django.contrib.auth import authenticate
from django.utils.translation import gettext_lazy as _
-from .models import CustomUser
+from membership.models import CustomUser
from .models import UserHostingKey, GenericProduct
logger = logging.getLogger(__name__)
-class ResendActivationEmailForm(forms.Form):
- email = forms.CharField(widget=forms.EmailInput())
-
- class Meta:
- fields = ['email']
-
- def clean_email(self):
- email = self.cleaned_data.get('email')
- try:
- c = CustomUser.objects.get(email=email)
- if c.validated == 1:
- raise forms.ValidationError(
- _("The account is already active."))
- return email
- except CustomUser.DoesNotExist:
- raise forms.ValidationError(_("User does not exist"))
-
-
-class PasswordResetRequestForm(forms.Form):
- email = forms.CharField(widget=forms.EmailInput())
-
- class Meta:
- fields = ['email']
-
- def clean_email(self):
- email = self.cleaned_data.get('email')
- try:
- CustomUser.objects.get(email=email)
- return email
- except CustomUser.DoesNotExist:
- raise forms.ValidationError(_("User does not exist"))
-
-
-class SetPasswordForm(forms.Form):
- """
- A form that lets a user change set their password without entering the old
- password
- """
- error_messages = {
- 'password_mismatch': _("The two password fields didn't match."),
- }
- new_password1 = forms.CharField(label=_("New password"),
- widget=forms.PasswordInput)
- new_password2 = forms.CharField(label=_("New password confirmation"),
- widget=forms.PasswordInput)
-
- def clean_new_password2(self):
- password1 = self.cleaned_data.get('new_password1')
- password2 = self.cleaned_data.get('new_password2')
- if password1 and password2:
- if password1 != password2:
- raise forms.ValidationError(
- self.error_messages['password_mismatch'],
- code='password_mismatch', )
- return password2
-
-
-class EditCreditCardForm(forms.Form):
- token = forms.CharField(widget=forms.HiddenInput())
-
-
-class BillingAddressForm(forms.ModelForm):
- token = forms.CharField(widget=forms.HiddenInput(), required=False)
- card = forms.CharField(widget=forms.HiddenInput(), required=False)
-
- class Meta:
- model = BillingAddress
- fields = ['cardholder_name', 'street_address',
- 'city', 'postal_code', 'country', 'vat_number']
- labels = {
- 'cardholder_name': _('Cardholder Name'),
- 'street_address': _('Street Address'),
- 'city': _('City'),
- 'postal_code': _('Postal Code'),
- 'Country': _('Country'),
- 'VAT Number': _('VAT Number')
- }
-
-
-class BillingAddressFormSignup(BillingAddressForm):
- name = forms.CharField(label=_('Name'))
- email = forms.EmailField(label=_('Email Address'))
- field_order = ['name', 'email']
-
- class Meta:
- model = BillingAddress
- fields = ['name', 'email', 'cardholder_name', 'street_address',
- 'city', 'postal_code', 'country', 'vat_number']
- labels = {
- 'name': 'Name',
- 'email': _('Email'),
- 'cardholder_name': _('Cardholder Name'),
- 'street_address': _('Street Address'),
- 'city': _('City'),
- 'postal_code': _('Postal Code'),
- 'Country': _('Country'),
- 'vat_number': _('VAT Number')
- }
-
- def clean_email(self):
- email = self.cleaned_data.get('email')
- try:
- CustomUser.objects.get(email=email)
- raise forms.ValidationError(
- _("The email %(email)s is already registered with us. "
- "Please reset your password and access your account.") %
- {'email': email}
- )
- except CustomUser.DoesNotExist:
- return email
-
-
-class UserBillingAddressForm(forms.ModelForm):
- user = forms.ModelChoiceField(queryset=CustomUser.objects.all(),
- widget=forms.HiddenInput())
-
- class Meta:
- model = UserBillingAddress
- fields = ['cardholder_name', 'street_address',
- 'city', 'postal_code', 'country', 'user', 'vat_number']
- labels = {
- 'cardholder_name': _('Cardholder Name'),
- 'street_address': _('Street Building'),
- 'city': _('City'),
- 'postal_code': _('Postal Code'),
- 'Country': _('Country'),
- 'vat_number': _('VAT Number'),
- }
-
-
-
def generate_ssh_key_name():
return '{prefix}{date_time_str}'.format(
prefix=settings.DCL_SSH_KEY_NAME_PREFIX,
@@ -343,7 +208,7 @@ class UserHostingKeyForm(forms.ModelForm):
logger.debug(
"Not a correct ssh format {error}".format(error=str(cpe)))
raise forms.ValidationError(KEY_ERROR_MESSAGE)
- return xml.sax.saxutils.escape(openssh_pubkey_str)
+ return html.escape(openssh_pubkey_str)
def clean_name(self):
INVALID_NAME_MESSAGE = _("Comma not accepted in the name of the key")
@@ -370,4 +235,3 @@ class UserHostingKeyForm(forms.ModelForm):
class Meta:
model = UserHostingKey
fields = ['user', 'name', 'public_key']
-
diff --git a/hosting/locale/de/LC_MESSAGES/django.mo b/hosting/locale/de/LC_MESSAGES/django.mo
new file mode 100755
index 0000000..a08e434
Binary files /dev/null and b/hosting/locale/de/LC_MESSAGES/django.mo differ
diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po
new file mode 100755
index 0000000..de0b1e4
--- /dev/null
+++ b/hosting/locale/de/LC_MESSAGES/django.po
@@ -0,0 +1,1472 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR , YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-12-03 10:44+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: LANGUAGE \n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: hosting/forms.py:40
+msgid "Your username and/or password were incorrect."
+msgstr "Dein Benutzername und/oder Dein Passwort ist falsch."
+
+#: hosting/forms.py:43
+msgid "Your account is not activated yet."
+msgstr "Dein Account wurde noch nicht aktiviert."
+
+#: hosting/forms.py:52
+msgid "User does not exist"
+msgstr "Der Benutzer existiert nicht"
+
+#: hosting/forms.py:63
+msgid "Choose a product"
+msgstr "Wähle ein Produkt"
+
+#: hosting/forms.py:67 hosting/forms.py:72 hosting/forms.py:119
+#: hosting/forms.py:124
+msgid "Amount in CHF"
+msgstr "Betrag"
+
+#: hosting/forms.py:75
+msgid "Recurring monthly"
+msgstr "monatlich wiederkehrend"
+
+#: hosting/forms.py:89 hosting/forms.py:136
+msgid "Amount field does not match"
+msgstr "Betragsfeld stimmt nicht überein"
+
+#: hosting/forms.py:96 hosting/forms.py:143
+msgid "Recurring field does not match"
+msgstr "Betragsfeld stimmt nicht überein"
+
+#: hosting/forms.py:108
+msgid "Product name"
+msgstr "Produkt"
+
+#: hosting/forms.py:115
+msgid "Monthly subscription"
+msgstr "Monatliches Abonnement"
+
+#: hosting/forms.py:117
+msgid "Yearly subscription"
+msgstr "Jährliches Abonnement"
+
+#: hosting/forms.py:125
+msgid "One time payment"
+msgstr "Einmalzahlung"
+
+#: hosting/forms.py:148
+msgid "Confirm Password"
+msgstr "Passwort Bestätigung"
+
+#: hosting/forms.py:150
+msgid "Password"
+msgstr "Passwort"
+
+#: hosting/forms.py:158
+msgid "Enter your name or company name"
+msgstr "Gib Deinen Namen oder den Name Deines Unternehmens ein"
+
+#: hosting/forms.py:173
+msgid "Paste here your public key"
+msgstr "Füge Deinen Public Key ein"
+
+#: hosting/forms.py:181
+msgid "Give a name to your key"
+msgstr "Gebe Deinem SSH-Key einen Name"
+
+#: hosting/forms.py:186
+msgid "Key name"
+msgstr "Key-Name"
+
+#: hosting/forms.py:198
+msgid "Please input a proper SSH key"
+msgstr "Bitte verwende einen gültigen SSH-Key"
+
+#: hosting/forms.py:214
+msgid "Comma not accepted in the name of the key"
+msgstr "Komma im Namen des Keys wird nicht akzeptiert"
+
+#: hosting/templates/hosting/base_short.html:70
+#: hosting/templates/hosting/includes/_footer.html:29
+msgid "All Rights Reserved"
+msgstr "Alle Rechte vorbehalten"
+
+#: hosting/templates/hosting/bill_detail.html:11 hosting/views.py:890
+msgid "Invoice"
+msgstr "Rechnung"
+
+#: hosting/templates/hosting/bill_detail.html:11
+#: hosting/templates/hosting/order_detail.html:29
+msgid "Order #"
+msgstr "Bestellung #"
+
+#: hosting/templates/hosting/bill_detail.html:25
+msgid "ungleich GmbH"
+msgstr ""
+
+#: hosting/templates/hosting/bill_detail.html:26
+msgid "buchhaltung@ungleich.ch"
+msgstr ""
+
+#: hosting/templates/hosting/bill_detail.html:27
+msgid "Hauptstrasse 14"
+msgstr ""
+
+#: hosting/templates/hosting/bill_detail.html:28
+msgid "CH-8775 Luchsingen"
+msgstr ""
+
+#: hosting/templates/hosting/bill_detail.html:29
+msgid "Mwst-Nummer: CHE-109.549.333 MWST"
+msgstr ""
+
+#: hosting/templates/hosting/bill_detail.html:60
+msgid "Total:"
+msgstr "Gesamt:"
+
+#: hosting/templates/hosting/bill_detail.html:68
+#, python-format
+msgid "Alles Preise in CHF mit 8%% Mehrwertsteuer."
+msgstr "All prices in CHF including 8%% VAT"
+
+#: hosting/templates/hosting/bill_detail.html:69
+msgid "Betrag zahlbar innerhalb von 30 Tagen ab Rechnungseingang."
+msgstr ""
+
+#: hosting/templates/hosting/bill_detail.html:70
+msgid "Kontoverbindung:"
+msgstr ""
+
+#: hosting/templates/hosting/bill_detail.html:73
+msgid "IBAN:"
+msgstr ""
+
+#: hosting/templates/hosting/bill_detail.html:76
+msgid "BIC:"
+msgstr ""
+
+#: hosting/templates/hosting/bill_detail.html:81
+msgid "CH02 0900 0000 6071 8848 8"
+msgstr ""
+
+#: hosting/templates/hosting/bill_detail.html:84
+msgid "POFICHBEXXX"
+msgstr ""
+
+#: hosting/templates/hosting/bills.html:12
+msgid "Customers"
+msgstr "Kunden"
+
+#: hosting/templates/hosting/bills.html:16
+#: hosting/templates/hosting/user_keys.html:25
+msgid "Name"
+msgstr ""
+
+#: hosting/templates/hosting/bills.html:17
+msgid "Email"
+msgstr ""
+
+#: hosting/templates/hosting/bills.html:28
+msgid "View Bill"
+msgstr "Rechnung anzeigen"
+
+#: hosting/templates/hosting/bills.html:41
+#: hosting/templates/hosting/orders.html:45
+#: hosting/templates/hosting/virtual_machines.html:70
+msgid "previous"
+msgstr "vorherige"
+
+#: hosting/templates/hosting/bills.html:47
+#: hosting/templates/hosting/orders.html:51
+#: hosting/templates/hosting/virtual_machines.html:76
+msgid "next"
+msgstr "nächste"
+
+#: hosting/templates/hosting/calculator_form.html:6
+#: hosting/templates/hosting/payment.html:78
+#: hosting/templates/hosting/payment.html:94
+#: hosting/templates/hosting/virtual_machine_detail.html:48
+msgid "Month"
+msgstr "Monat"
+
+#: hosting/templates/hosting/calculator_form.html:8
+msgid "VAT included"
+msgstr "MwSt. inklusive"
+
+#: hosting/templates/hosting/calculator_form.html:15
+msgid "Please enter a value in range 1 - 48."
+msgstr "Bitte gib einen Wert von 1 bis 48 ein."
+
+#: hosting/templates/hosting/calculator_form.html:33
+msgid "Please enter a value in range 1 - 200."
+msgstr "Bitte gib einen Wert von 1 bis 200 ein."
+
+#: hosting/templates/hosting/calculator_form.html:51
+msgid "Please enter a value in range 10 - 2000."
+msgstr "Bitte gib einen Wert von 10 bis 2000 ein."
+
+#: hosting/templates/hosting/calculator_form.html:52
+msgid "GB Storage (SSD)"
+msgstr "GB Storage (SSD)"
+
+#: hosting/templates/hosting/calculator_form.html:86
+msgid "Continue"
+msgstr "Weiter"
+
+#: hosting/templates/hosting/choice_ssh_keys.html:8
+msgid "SSH Key"
+msgstr "SSH Key"
+
+#: hosting/templates/hosting/choice_ssh_keys.html:9
+msgid "Choose a key option in order to access your VM"
+msgstr "Wähle eine Option um Zugriff auf deine VM zu erhalten"
+
+#: hosting/templates/hosting/choice_ssh_keys.html:20
+msgid "Generating a new key pair"
+msgstr "Neuen SSH-Key erstellen"
+
+#: hosting/templates/hosting/choice_ssh_keys.html:21
+msgid "I want to generate a new key pair"
+msgstr "Ich möchte einen neuen SSH-Key erstellen"
+
+#: hosting/templates/hosting/choice_ssh_keys.html:25
+#: hosting/templates/hosting/user_key.html:37
+msgid "Generate"
+msgstr "Generieren"
+
+#: hosting/templates/hosting/choice_ssh_keys.html:30
+msgid "Using existing key"
+msgstr "Nutzung eines existierenden SSH-Keys"
+
+#: hosting/templates/hosting/choice_ssh_keys.html:31
+msgid "I want to use my existing public key"
+msgstr "Ich möchte einen existierenden SSH-Key nutzen"
+
+#: hosting/templates/hosting/choice_ssh_keys.html:34
+msgid "Upload"
+msgstr "Hochladen"
+
+#: hosting/templates/hosting/confirm_reset_password.html:14
+msgid "Set your new password"
+msgstr "Setze Dein neues Passwort"
+
+#: hosting/templates/hosting/confirm_reset_password.html:29
+#: hosting/templates/hosting/reset_password.html:23
+msgid "Reset"
+msgstr "Zurücksetzen"
+
+#: hosting/templates/hosting/confirm_reset_password.html:34
+#: hosting/templates/hosting/reset_password.html:29
+#: hosting/templates/hosting/signup.html:29
+msgid "Already have an account ?"
+msgstr "Hast Du bereits ein Benutzerkonto?"
+
+#: hosting/templates/hosting/confirm_reset_password.html:35
+#: hosting/templates/hosting/reset_password.html:30
+#: hosting/templates/hosting/signup.html:30
+msgid "Login"
+msgstr "Anmelden"
+
+#: hosting/templates/hosting/create_virtual_machine.html:11
+#: hosting/templates/hosting/dashboard.html:15
+msgid "Create VM"
+msgstr "VM erstellen"
+
+#: hosting/templates/hosting/create_virtual_machine.html:12
+msgid "Affordable VM hosting based in Switzerland"
+msgstr "Bezahlbares VM Hosting in der Schweiz"
+
+#: hosting/templates/hosting/dashboard.html:8
+msgid "My Dashboard"
+msgstr "Mein Dashboard"
+
+#: hosting/templates/hosting/dashboard.html:11
+msgid "Welcome"
+msgstr ""
+
+#: hosting/templates/hosting/dashboard.html:21
+msgid "My VMs"
+msgstr "Meine VMs"
+
+#: hosting/templates/hosting/dashboard.html:27
+#: hosting/templates/hosting/user_keys.html:6
+msgid "My SSH Keys"
+msgstr "Meine SSH-Keys"
+
+#: hosting/templates/hosting/dashboard.html:33
+#: hosting/templates/hosting/invoices.html:7
+#: hosting/templates/hosting/orders.html:7
+msgid "My Bills"
+msgstr "Meine Rechnungen"
+
+#: hosting/templates/hosting/dashboard.html:39
+#: hosting/templates/hosting/settings.html:12
+msgid "My Settings"
+msgstr "Meine Einstellungen"
+
+#: hosting/templates/hosting/dashboard.html:45
+#: hosting/templates/hosting/virtual_machine_detail.html:85
+msgid "Support / Contact"
+msgstr "Support / Kontakt"
+
+#: hosting/templates/hosting/emails/new_booked_vm.html:8
+#: hosting/templates/hosting/emails/new_booked_vm.html:22
+#: hosting/templates/hosting/emails/new_booked_vm.txt:3
+#, python-format
+msgid "Your New VM %(vm_name)s"
+msgstr "Deine Neue VM %(vm_name)s"
+
+#: hosting/templates/hosting/emails/new_booked_vm.html:28
+#: hosting/templates/hosting/emails/new_booked_vm.txt:5
+msgid "You have ordered a new virtual machine!"
+msgstr "Du hast eine neue virtuelle Maschine bestellt!"
+
+#: hosting/templates/hosting/emails/new_booked_vm.html:31
+#, python-format
+msgid "Your order of %(vm_name)s has been charged."
+msgstr ""
+"Deine Bestellung von %(vm_name)s wurde entgegengenommen."
+
+#: hosting/templates/hosting/emails/new_booked_vm.html:34
+msgid "You can view your VM detail by clicking the button below."
+msgstr "Um die Rechnung zu sehen, klicke auf den Button unten."
+
+#: hosting/templates/hosting/emails/new_booked_vm.html:38
+msgid "You can log in to your VM by the username puffy ."
+msgstr ""
+"Du kannst Dich auf Deiner VM mit dem user puffy einloggen."
+
+#: hosting/templates/hosting/emails/new_booked_vm.html:45
+#: hosting/templates/hosting/virtual_machines.html:58
+msgid "View Detail"
+msgstr "Details anzeigen"
+
+#: hosting/templates/hosting/emails/new_booked_vm.html:50
+#: hosting/templates/hosting/emails/new_booked_vm.txt:14
+#: hosting/templates/hosting/emails/password_reset_email.html:46
+#: hosting/templates/hosting/emails/password_reset_email.txt:14
+#: hosting/templates/hosting/emails/vm_canceled.html:42
+#: hosting/templates/hosting/emails/vm_canceled.txt:10
+msgid "Your Data Center Light Team"
+msgstr "Dein Data Center Light Team"
+
+#: hosting/templates/hosting/emails/new_booked_vm.txt:6
+#, python-format
+msgid "Your order of %(vm_name)s has been charged."
+msgstr "Deine Bestellung von %(vm_name)s wurde entgegengenommen."
+
+#: hosting/templates/hosting/emails/new_booked_vm.txt:7
+msgid "You can view your VM detail by following the link below."
+msgstr "Um die Rechnung zu sehen, klicke auf den Link unten."
+
+#: hosting/templates/hosting/emails/new_booked_vm.txt:9
+msgid "You can log in to your VM by the username puffy."
+msgstr "Du kannst Dich auf Deiner VM mit dem user puffy einloggen."
+
+#: hosting/templates/hosting/emails/password_reset_email.html:8
+#: hosting/templates/hosting/emails/password_reset_email.html:22
+#: hosting/templates/hosting/emails/password_reset_email.txt:3
+msgid "Password Reset"
+msgstr "Passwort zurücksetzen"
+
+#: hosting/templates/hosting/emails/password_reset_email.html:28
+#: hosting/templates/hosting/emails/password_reset_email.txt:5
+msgid "We received a request to reset your password."
+msgstr "Wir haben eine Anfrage erhalten, um Dein Passwort zurückzusetzen."
+
+#: hosting/templates/hosting/emails/password_reset_email.html:31
+#: hosting/templates/hosting/emails/password_reset_email.txt:6
+msgid "If you didn't make this request you can safely ignore this email."
+msgstr ""
+"Falls Du kein neues Passwort angefragt hast, kannst Du diese E-mail "
+"ignorieren."
+
+#: hosting/templates/hosting/emails/password_reset_email.html:33
+#: hosting/templates/hosting/emails/password_reset_email.txt:7
+msgid "Otherwise, click here to reset your password."
+msgstr "Andernfalls klicke hier, um Dein Passwort zurückzusetzen."
+
+#: hosting/templates/hosting/emails/password_reset_email.html:40
+#: hosting/templates/hosting/emails/password_reset_email.txt:12
+msgid "Thank you!"
+msgstr "Dankeschön!"
+
+#: hosting/templates/hosting/emails/vm_canceled.html:8
+#: hosting/templates/hosting/emails/vm_canceled.html:22
+#: hosting/templates/hosting/emails/vm_canceled.txt:3
+msgid "Virtual Machine Cancellation"
+msgstr "VM Kündigung"
+
+#: hosting/templates/hosting/emails/vm_canceled.html:28
+#, python-format
+msgid ""
+"You are receiving this email because your virtual machine "
+"%(vm_name)s has been cancelled."
+msgstr ""
+"Du erhälst diese E-Mail, da deine virtuelle Maschine %(vm_name)s"
+"strong> gekündigt wurde."
+
+#: hosting/templates/hosting/emails/vm_canceled.html:31
+msgid "You can always order a new VM by clicking the button below."
+msgstr ""
+"Du kannst einfach eine neue VM bestellen, indem Du den Knopf weiter unten "
+"drückst."
+
+#: hosting/templates/hosting/emails/vm_canceled.html:37
+#: hosting/templates/hosting/virtual_machines.html:23
+msgid "CREATE VM"
+msgstr "NEUE VM"
+
+#: hosting/templates/hosting/emails/vm_canceled.txt:5
+#, python-format
+msgid ""
+"You are receiving this email because your virtual machine %(vm_name)s has "
+"been cancelled."
+msgstr ""
+"Du erhälst diese E-Mail, da deine virtuelle Maschine %(vm_name)s gekündigt "
+"wurde."
+
+#: hosting/templates/hosting/emails/vm_canceled.txt:6
+msgid "You can always order a new VM by following the link below."
+msgstr ""
+
+#: hosting/templates/hosting/includes/_card_input.html:9
+msgid "Card Number"
+msgstr "Kreditkartennummer"
+
+#: hosting/templates/hosting/includes/_card_input.html:14
+msgid "Expiry Date"
+msgstr "Ablaufdatum"
+
+#: hosting/templates/hosting/includes/_card_input.html:18
+msgid "CVC"
+msgstr ""
+
+#: hosting/templates/hosting/includes/_card_input.html:23
+msgid "Card Type"
+msgstr "Kartentyp"
+
+#: hosting/templates/hosting/includes/_card_input.html:31
+msgid ""
+"You are not making any payment yet. After placing your order, you will be "
+"taken to the Submit Payment Page."
+msgstr ""
+"Es wird noch keine Bezahlung vorgenommen. Die Bezahlung wird erst ausgelöst, "
+"nachdem Du die Bestellung auf der nächsten Seite bestätigt hast."
+
+#: hosting/templates/hosting/includes/_card_input.html:44
+msgid "SUBMIT"
+msgstr "ABSENDEN"
+
+#: hosting/templates/hosting/includes/_navbar_user.html:10
+msgid "Toggle navigation"
+msgstr "Umschalten"
+
+#: hosting/templates/hosting/includes/_navbar_user.html:24
+msgid "Dashboard"
+msgstr "Dashboard"
+
+#: hosting/templates/hosting/includes/_navbar_user.html:32
+msgid "Logout"
+msgstr "Abmelden"
+
+#: hosting/templates/hosting/invoice_detail.html:18
+#: hosting/templates/hosting/order_detail.html:17
+#, python-format
+msgid "%(page_header_text)s"
+msgstr ""
+
+#: hosting/templates/hosting/invoice_detail.html:35
+msgid "Invoice #"
+msgstr "Rechnung"
+
+#: hosting/templates/hosting/invoice_detail.html:39
+#: hosting/templates/hosting/invoices.html:82
+#: hosting/templates/hosting/order_detail.html:33
+#: hosting/templates/hosting/orders.html:22
+#: hosting/templates/hosting/orders.html:31
+msgid "Date"
+msgstr "Datum"
+
+#: hosting/templates/hosting/invoice_detail.html:50
+#: hosting/templates/hosting/order_detail.html:44
+#: hosting/templates/hosting/virtual_machine_detail.html:53
+#: hosting/templates/hosting/virtual_machines.html:36
+#: hosting/templates/hosting/virtual_machines.html:46
+msgid "Status"
+msgstr ""
+
+#: hosting/templates/hosting/invoice_detail.html:53
+#: hosting/templates/hosting/order_detail.html:47 hosting/views.py:1737
+#: hosting/views.py:1843
+msgid "Terminated"
+msgstr "Beendet"
+
+#: hosting/templates/hosting/invoice_detail.html:55
+#: hosting/templates/hosting/order_detail.html:49
+msgid "Approved"
+msgstr "Akzeptiert"
+
+#: hosting/templates/hosting/invoice_detail.html:57
+#: hosting/templates/hosting/order_detail.html:51
+msgid "Declined"
+msgstr "Abgelehnt"
+
+#: hosting/templates/hosting/invoice_detail.html:65
+#: hosting/templates/hosting/order_detail.html:59
+msgid "Billed to"
+msgstr "Rechnungsadresse"
+
+#: hosting/templates/hosting/invoice_detail.html:74
+#: hosting/templates/hosting/order_detail.html:66
+#: hosting/templates/hosting/order_detail.html:74
+#, fuzzy
+#| msgid "Card Number"
+msgid "VAT Number"
+msgstr "Kreditkartennummer"
+
+#: hosting/templates/hosting/invoice_detail.html:82
+#: hosting/templates/hosting/order_detail.html:83
+msgid "Payment method"
+msgstr "Bezahlmethode"
+
+#: hosting/templates/hosting/invoice_detail.html:85
+#: hosting/templates/hosting/order_detail.html:86
+#: hosting/templates/hosting/order_detail.html:90
+msgid "ending in"
+msgstr "endend in"
+
+#: hosting/templates/hosting/invoice_detail.html:93
+msgid "Invoice summary"
+msgstr ""
+
+#: hosting/templates/hosting/invoice_detail.html:106
+#: hosting/templates/hosting/invoice_detail.html:186
+#: hosting/templates/hosting/invoices.html:27
+#: hosting/templates/hosting/invoices.html:81
+#: hosting/templates/hosting/order_detail.html:105
+#: hosting/templates/hosting/order_detail.html:182
+msgid "Product"
+msgstr "Produkt"
+
+#: hosting/templates/hosting/invoice_detail.html:115
+#: hosting/templates/hosting/invoices.html:28
+#: hosting/templates/hosting/order_detail.html:116
+msgid "Period"
+msgstr "Periode"
+
+#: hosting/templates/hosting/invoice_detail.html:124
+#: hosting/templates/hosting/order_detail.html:123
+#: hosting/templates/hosting/payment.html:20
+#: hosting/templates/hosting/virtual_machine_detail.html:38
+msgid "Cores"
+msgstr "Prozessorkerne"
+
+#: hosting/templates/hosting/invoice_detail.html:132
+#: hosting/templates/hosting/order_detail.html:131
+#: hosting/templates/hosting/payment.html:25
+#: hosting/templates/hosting/virtual_machine_detail.html:39
+msgid "Memory"
+msgstr "Arbeitsspeicher"
+
+#: hosting/templates/hosting/invoice_detail.html:136
+#: hosting/templates/hosting/order_detail.html:135
+#: hosting/templates/hosting/payment.html:30
+msgid "Disk space"
+msgstr "Festplattenkapazität"
+
+#: hosting/templates/hosting/invoice_detail.html:148
+#: hosting/templates/hosting/order_detail.html:147
+msgid "Subtotal"
+msgstr "Zwischensumme"
+
+#: hosting/templates/hosting/invoice_detail.html:154
+#: hosting/templates/hosting/order_detail.html:152
+msgid "VAT for"
+msgstr ""
+
+#: hosting/templates/hosting/invoice_detail.html:156
+#: hosting/templates/hosting/order_detail.html:154
+msgid "VAT"
+msgstr "Mehrwertsteuer"
+
+#: hosting/templates/hosting/invoice_detail.html:164
+#: hosting/templates/hosting/order_detail.html:162
+#: hosting/templates/hosting/payment.html:87
+msgid "Discount"
+msgstr "Rabatt"
+
+#: hosting/templates/hosting/invoice_detail.html:177
+#: hosting/templates/hosting/order_detail.html:175
+#: hosting/templates/hosting/payment.html:72
+msgid "Total"
+msgstr "Gesamt"
+
+#: hosting/templates/hosting/invoice_detail.html:192
+#: hosting/templates/hosting/invoices.html:29
+#: hosting/templates/hosting/invoices.html:83
+#: hosting/templates/hosting/order_detail.html:188
+#: hosting/templates/hosting/orders.html:23
+#: hosting/templates/hosting/orders.html:32
+msgid "Amount"
+msgstr "Betrag"
+
+#: hosting/templates/hosting/invoice_detail.html:198
+#: hosting/templates/hosting/order_detail.html:193
+msgid "Description"
+msgstr "Beschreibung"
+
+#: hosting/templates/hosting/invoice_detail.html:204
+#: hosting/templates/hosting/order_detail.html:199
+msgid "Recurring"
+msgstr "wiederkehrend"
+
+#: hosting/templates/hosting/invoice_detail.html:206
+#: hosting/templates/hosting/order_detail.html:201
+#: hosting/templates/hosting/orders.html:48
+#: hosting/templates/hosting/virtual_machines.html:73
+msgid "of"
+msgstr "von"
+
+#: hosting/templates/hosting/invoice_detail.html:207
+#: hosting/templates/hosting/order_detail.html:202
+msgid "each year"
+msgstr "jedes Jahr"
+
+#: hosting/templates/hosting/invoice_detail.html:210
+#: hosting/templates/hosting/order_detail.html:205
+msgid "of every month"
+msgstr "jeden Monat"
+
+#: hosting/templates/hosting/invoice_detail.html:231
+#: hosting/templates/hosting/order_detail.html:242
+#: hosting/templates/hosting/virtual_machine_detail.html:98
+msgid "BACK TO LIST"
+msgstr "ZURÜCK ZUR LISTE"
+
+#: hosting/templates/hosting/invoice_detail.html:235
+#: hosting/templates/hosting/order_detail.html:275
+msgid "Some problem encountered. Please try again later."
+msgstr "Ein Problem ist aufgetreten. Bitte versuche es später noch einmal."
+
+#: hosting/templates/hosting/invoices.html:19
+#, fuzzy
+#| msgid "Description"
+msgid "Subscriptions"
+msgstr "Beschreibung"
+
+#: hosting/templates/hosting/invoices.html:20
+#, fuzzy
+#| msgid "One time payment"
+msgid "One-time payments"
+msgstr "Einmalzahlung"
+
+#: hosting/templates/hosting/invoices.html:26
+msgid "VM ID"
+msgstr ""
+
+#: hosting/templates/hosting/invoices.html:27
+msgid "IP Address"
+msgstr "IP-Adresse"
+
+#: hosting/templates/hosting/login.html:14
+#: hosting/templates/hosting/login.html:24
+msgid "Log in"
+msgstr "Anmelden"
+
+#: hosting/templates/hosting/login.html:31
+#: hosting/templates/hosting/resend_activation_link.html:29
+msgid "Don't have an account yet ?"
+msgstr "Besitzt du kein Benutzerkonto?"
+
+#: hosting/templates/hosting/login.html:32
+#: hosting/templates/hosting/resend_activation_link.html:30
+#: hosting/templates/hosting/signup.html:14
+#: hosting/templates/hosting/signup.html:23 hosting/views.py:307
+msgid "Sign up"
+msgstr "Registrieren"
+
+#: hosting/templates/hosting/login.html:35
+#: hosting/templates/hosting/resend_activation_link.html:33
+msgid "Forgot your password ?"
+msgstr "Passwort vergessen?"
+
+#: hosting/templates/hosting/login.html:36
+#: hosting/templates/hosting/resend_activation_link.html:14
+msgid "Resend activation link"
+msgstr "Aktivierungslink noch einmal senden"
+
+#: hosting/templates/hosting/notifications.html:9
+msgid "Notifications"
+msgstr "Benachrichtigungen"
+
+#: hosting/templates/hosting/notifications.html:16
+msgid "Unread"
+msgstr "Ungelesen"
+
+#: hosting/templates/hosting/notifications.html:26
+msgid "All"
+msgstr "Alle"
+
+#: hosting/templates/hosting/notifications.html:38
+msgid "Unread notifications"
+msgstr "Ungelesene Benachrichtigungen"
+
+#: hosting/templates/hosting/notifications.html:48
+msgid "Mark as read"
+msgstr "Als gelesen markieren"
+
+#: hosting/templates/hosting/notifications.html:59
+msgid "All notifications"
+msgstr "Alle Benachrichtigungen"
+
+#: hosting/templates/hosting/order_detail.html:90
+#: hosting/templates/hosting/payment.html:117
+#: hosting/templates/hosting/payment.html:131
+#: hosting/templates/hosting/settings.html:45
+#: hosting/templates/hosting/settings.html:51
+msgid "Credit Card"
+msgstr "Kreditkarte"
+
+#: hosting/templates/hosting/order_detail.html:91
+#: hosting/templates/hosting/payment.html:134
+#: hosting/templates/hosting/settings.html:54
+msgid "Expiry"
+msgstr "Gültig bis"
+
+#: hosting/templates/hosting/order_detail.html:102
+msgid "Order summary"
+msgstr "Bestellungsübersicht"
+
+#: hosting/templates/hosting/order_detail.html:221
+#, python-format
+msgid ""
+"By clicking \"Place order\" you agree to our Terms of Service and "
+"this plan will charge your credit card account with %(vm_price)s CHF/month."
+msgstr ""
+"Indem Du auf \"Bestellung aufgeben\" klickst, erklärst Du dich mit unseren "
+"Nutzungsbedingungen einverstanden und Dein Kreditkartenkonto wird mit "
+"%(vm_price)s CHF/Monat belastet."
+
+#: hosting/templates/hosting/order_detail.html:225
+msgid "Place order"
+msgstr "Bestellen"
+
+#: hosting/templates/hosting/order_detail.html:257
+msgid "Processing..."
+msgstr "Abarbeitung..."
+
+#: hosting/templates/hosting/order_detail.html:261
+msgid "Hold tight, we are processing your request"
+msgstr "Bitte warten - wir bearbeiten Deine Anfrage gerade"
+
+#: hosting/templates/hosting/order_detail.html:264
+#: hosting/templates/hosting/virtual_machine_detail.html:116
+#: hosting/templates/hosting/virtual_machine_detail.html:134
+msgid "OK"
+msgstr "Ok"
+
+#: hosting/templates/hosting/order_detail.html:265
+msgid "Close"
+msgstr "Schliessen"
+
+#: hosting/templates/hosting/orders.html:21
+#: hosting/templates/hosting/orders.html:30
+msgid "Order Nr."
+msgstr "Bestellung Nr."
+
+#: hosting/templates/hosting/orders.html:34
+#: hosting/templates/hosting/virtual_machine_detail.html:49
+msgid "See Invoice"
+msgstr "Siehe Rechnung"
+
+#: hosting/templates/hosting/orders.html:48
+#: hosting/templates/hosting/virtual_machines.html:73
+msgid "Page"
+msgstr "Seite"
+
+#: hosting/templates/hosting/payment.html:13
+msgid "Your Order"
+msgstr "Deine Bestellung"
+
+#: hosting/templates/hosting/payment.html:35
+#: hosting/templates/hosting/virtual_machine_detail.html:41
+msgid "Configuration"
+msgstr "Konfiguration"
+
+#: hosting/templates/hosting/payment.html:73
+msgid "including VAT"
+msgstr "inkl. Mehrwertsteuer"
+
+#: hosting/templates/hosting/payment.html:73
+msgid "excluding VAT"
+msgstr "exkl. Mehrwertsteuer"
+
+#: hosting/templates/hosting/payment.html:89
+msgid "Will be applied at checkout"
+msgstr "wird an der Kasse angewendet"
+
+#: hosting/templates/hosting/payment.html:105
+#: hosting/templates/hosting/settings.html:22
+msgid "Billing Address"
+msgstr "Rechnungsadresse"
+
+#: hosting/templates/hosting/payment.html:122
+msgid ""
+"Please select one of the cards that you used before or fill in your credit "
+"card information below. We are using Stripe for payment and do not store your information "
+"in our database."
+msgstr ""
+"Bitte wähle eine der zuvor genutzten Kreditkarten oder gib Deine "
+"Kreditkartendetails unten an. Die Bezahlung wird über Stripe abgewickelt. Wir speichern Deine "
+"Kreditkartendetails nicht in unserer Datenbank."
+
+#: hosting/templates/hosting/payment.html:124
+msgid ""
+"Please fill in your credit card information below. We are using Stripe for payment and do "
+"not store your information in our database."
+msgstr ""
+"Bitte füll Deine Kreditkarteninformationen unten aus. Wir nutzen Stripe für die Bezahlung "
+"und speichern keine Informationen in unserer Datenbank."
+
+#: hosting/templates/hosting/payment.html:132
+#: hosting/templates/hosting/settings.html:52
+msgid "Last"
+msgstr "Letzten"
+
+#: hosting/templates/hosting/payment.html:133
+#: hosting/templates/hosting/settings.html:53
+msgid "Type"
+msgstr "Kartentyp"
+
+#: hosting/templates/hosting/payment.html:137
+#: hosting/templates/hosting/settings.html:91
+msgid "SELECT"
+msgstr "AUSWÄHLEN"
+
+#: hosting/templates/hosting/payment.html:145
+#: hosting/templates/hosting/settings.html:109
+msgid "Add a new credit card"
+msgstr "Eine neue Kreditkarte hinzufügen"
+
+#: hosting/templates/hosting/payment.html:149
+#: hosting/templates/hosting/settings.html:113
+msgid "NEW CARD"
+msgstr "BEARBEITEN"
+
+#: hosting/templates/hosting/payment.html:157
+#: hosting/templates/hosting/settings.html:121
+msgid "New Credit Card"
+msgstr "Neue Kreditkarte"
+
+#: hosting/templates/hosting/payment.html:178
+#: hosting/templates/hosting/settings.html:136
+msgid "Processing"
+msgstr "Weiter"
+
+#: hosting/templates/hosting/payment.html:179
+#: hosting/templates/hosting/settings.html:137
+msgid "Enter your credit card number"
+msgstr "Deine Kreditkartennummer"
+
+#: hosting/templates/hosting/resend_activation_link.html:23
+msgid "Submit"
+msgstr "Absenden"
+
+#: hosting/templates/hosting/reset_password.html:14
+msgid "Password reset"
+msgstr "Passwort zurücksetzen"
+
+#: hosting/templates/hosting/settings.html:18
+#, fuzzy
+#| msgid "Key name"
+msgid "My Username"
+msgstr "Key-Name"
+
+#: hosting/templates/hosting/settings.html:33
+msgid "Your VAT number has been verified"
+msgstr ""
+
+#: hosting/templates/hosting/settings.html:35
+msgid ""
+"Your VAT number is under validation. VAT will be adjusted, once the "
+"validation is complete."
+msgstr ""
+
+#: hosting/templates/hosting/settings.html:40
+msgid "UPDATE"
+msgstr "AKTUALISIEREN"
+
+#: hosting/templates/hosting/settings.html:59
+msgid "REMOVE CARD"
+msgstr "KARTE ENTFERNEN"
+
+#: hosting/templates/hosting/settings.html:68
+msgid "Remove Card"
+msgstr "Karte entfernen"
+
+#: hosting/templates/hosting/settings.html:70
+msgid "Do you want to remove this associated card?"
+msgstr "Möchtest Du den Schlüssel löschen?"
+
+#: hosting/templates/hosting/settings.html:75
+#: hosting/templates/hosting/user_keys.html:37
+#: hosting/templates/hosting/user_keys.html:55
+msgid "Delete"
+msgstr "Löschen"
+
+#: hosting/templates/hosting/settings.html:86
+msgid "DEFAULT"
+msgstr "STANDARD"
+
+#: hosting/templates/hosting/settings.html:100
+msgid "No Credit Cards Added"
+msgstr "Es wurde keine Kreditkarte hinzugefügt"
+
+#: hosting/templates/hosting/settings.html:101
+msgid ""
+"We are using Stripe for payment and do "
+"not store your information in our database."
+msgstr ""
+"Wir nutzen Stripe für "
+"die Bezahlung und speichern keine Informationen in unserer Datenbank."
+
+#: hosting/templates/hosting/user_key.html:26
+msgid "Use your created key to access to the VM"
+msgstr "Benutze deinen erstellten SSH-Key um auf deine VM zugreifen zu können"
+
+#: hosting/templates/hosting/user_key.html:29
+#: hosting/templates/hosting/user_keys.html:17
+msgid "Add SSH Key"
+msgstr "Hinzufügen"
+
+#: hosting/templates/hosting/user_key.html:34
+msgid "Or you can generate a new key pair"
+msgstr "Erstelle dein neues Keypaar"
+
+#: hosting/templates/hosting/user_key.html:46
+msgid "Warning!"
+msgstr "Achtung!"
+
+#: hosting/templates/hosting/user_key.html:46
+msgid "You can download your SSH private key once. Don't loose your key"
+msgstr ""
+"Du kannst deinen privaten SSH Schlüssel nur einmal herunterladen. Beware ihn "
+"sicher auf."
+
+#: hosting/templates/hosting/user_keys.html:15
+msgid ""
+"To generate a new key pair or to upload your existing key, click 'Add Key'"
+msgstr ""
+"Um einen neuen SSH-Key zu erstellen oder um einen vorhandenen SSH-Key "
+"hinzuzufügen, klicke auf 'Hinzufügen'"
+
+#: hosting/templates/hosting/user_keys.html:26
+msgid "Delete Key"
+msgstr "Löschen"
+
+#: hosting/templates/hosting/user_keys.html:27
+msgid "Public Key"
+msgstr ""
+
+#: hosting/templates/hosting/user_keys.html:28
+msgid "Private Key"
+msgstr "Privater Schlüssel"
+
+#: hosting/templates/hosting/user_keys.html:48
+msgid "Delete SSH Key"
+msgstr "SSH Key löschen"
+
+#: hosting/templates/hosting/user_keys.html:50
+msgid "Do you want to delete this key?"
+msgstr "Möchtest Du den Schlüssel löschen?"
+
+#: hosting/templates/hosting/user_keys.html:65
+msgid "Show"
+msgstr "Anzeigen"
+
+#: hosting/templates/hosting/user_keys.html:74
+msgid "Public SSH Key"
+msgstr "Public SSH Key"
+
+#: hosting/templates/hosting/user_keys.html:85
+msgid "Download"
+msgstr ""
+
+#: hosting/templates/hosting/virtual_machine_detail.html:14
+msgid "Your Virtual Machine Detail"
+msgstr "Virtuelle Maschinen Detail"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:17
+msgid "VM Settings"
+msgstr "VM Einstellungen"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:24
+#: hosting/templates/hosting/virtual_machine_detail.html:31
+msgid "Copied"
+msgstr "Kopiert"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:40
+msgid "Disk"
+msgstr "Festplatte"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:45
+msgid "Billing"
+msgstr "Abrechnungen"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:47
+msgid "Current Pricing"
+msgstr "Aktueller Preis"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:55
+msgid "Your VM is"
+msgstr "Deine VM ist"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:56
+msgid "Terminating"
+msgstr "Beenden"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:58
+msgid "Pending"
+msgstr "In Vorbereitung"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:60
+msgid "Online"
+msgstr ""
+
+#: hosting/templates/hosting/virtual_machine_detail.html:62
+msgid "Failed"
+msgstr "Fehlgeschlagen"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:70
+msgid "Terminate VM"
+msgstr "VM Beenden"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:72
+msgid "Sorry, there was an unexpected error. Kindly retry."
+msgstr ""
+"Bitte entschuldige, es scheint ein unerwarteter Fehler aufgetreten zu sein. "
+"Versuche es doch bitte noch einmal."
+
+#: hosting/templates/hosting/virtual_machine_detail.html:78
+msgid "Attention:"
+msgstr "Achtung:"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:79
+msgid "terminating VM can not be reverted."
+msgstr "Das Beenden kann nicht rückgängig gemacht werden."
+
+#: hosting/templates/hosting/virtual_machine_detail.html:90
+msgid "Something doesn't work?"
+msgstr "Etwas funktioniert nicht?"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:90
+msgid "We are here to help you!"
+msgstr "Wir sind hier, um Dir zu helfen!"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:94
+msgid "CONTACT"
+msgstr "KONTAKT"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:110
+msgid "Terminate your Virtual Machine"
+msgstr "Deine Virtuelle Maschine beenden"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:112
+msgid ""
+"Terminated VMs can not be revived and will not be refunded. Do you want to "
+"terminate your VM?"
+msgstr ""
+"Beendete VMs können nicht wiederhergestellt oder erstattet werden. Möchtest "
+"du die VM beenden?"
+
+#: hosting/templates/hosting/virtual_machine_detail.html:132
+#, python-format
+msgid ""
+"Your Virtual Machine %(machine_name)s is successfully "
+"terminated!"
+msgstr ""
+"Deine Virtuelle Machine (VM) %(machine_name)s wurde "
+"erfolgreich beendet!"
+
+#: hosting/templates/hosting/virtual_machines.html:6
+msgid "Virtual Machines"
+msgstr "Virtuelle Maschinen"
+
+#: hosting/templates/hosting/virtual_machines.html:16
+msgid "To create a new virtual machine, click \"Create VM\""
+msgstr "Um eine neue VM zu erzeugen, klicke \"Neue VM erzeugen\""
+
+#: hosting/templates/hosting/virtual_machines.html:19
+#, python-format
+msgid ""
+"To access your VM, add your SSH key here "
+msgstr ""
+"Um auf Deine VM zuzugreifen, füge Deinen SSH-"
+"Key hinzu "
+
+#: hosting/views.py:293 hosting/views.py:318
+msgid "login"
+msgstr "anmelden"
+
+#: hosting/views.py:299
+msgid ""
+"Thank you for signing up. We have sent an email to you. Please follow the "
+"instructions in it to activate your account. Once activated, you can login "
+"using"
+msgstr ""
+"Danke für deine Anmeldung. Wir haben dir eine E-Mail geschickt. Bitte folge "
+"den Anweisungen um deinen Account zu aktivieren. Danach kannst du dich über "
+"diesen"
+
+#: hosting/views.py:302 hosting/views.py:350
+msgid "Go back to"
+msgstr "Zurück"
+
+#: hosting/views.py:319
+msgid "Account activation"
+msgstr "Accountaktivierung"
+
+#: hosting/views.py:326
+msgid "Your account has been activated."
+msgstr "Dein Account wurde aktiviert."
+
+#: hosting/views.py:327
+msgid "You can now"
+msgstr "Du kannst dich nun"
+
+#: hosting/views.py:330
+msgid "Welcome to Data Center Light!"
+msgstr "Willkommen beim Data Center Light!"
+
+#: hosting/views.py:349
+msgid "Sorry. Your request is invalid."
+msgstr "Entschuldigung, deine Anfrage ist ungültig."
+
+#: hosting/views.py:417
+msgid "Password has been reset."
+msgstr "Dein Passwort wurde erfolgreich zurückgesetzt."
+
+#: hosting/views.py:425 hosting/views.py:427
+msgid "Password reset has not been successful."
+msgstr "Dein Passwort konnte nicht zurückgesetzt werden."
+
+#: hosting/views.py:431
+msgid "The reset password link is no longer valid."
+msgstr "Der Link zum Zurücksetzen Deines Passwortes ist nicht mehr gültig."
+
+#: hosting/views.py:595
+msgid "Could not set a default card."
+msgstr ""
+
+#: hosting/views.py:614
+msgid "Card deassociation successful"
+msgstr "Die Verbindung mit der Karte wurde erfolgreich aufgehoben"
+
+#: hosting/views.py:683 hosting/views.py:687
+msgid "Billing address updated successfully"
+msgstr "Die Rechnungsadresse wurde erfolgreich aktualisiert"
+
+#: hosting/views.py:709 hosting/views.py:1101
+#, python-brace-format
+msgid "An error occurred while associating the card. Details: {details}"
+msgstr ""
+"Beim Verbinden der Karte ist ein Fehler aufgetreten. Details: {details}"
+
+#: hosting/views.py:730
+msgid "Successfully associated the card with your account"
+msgstr "Die Karte wurde erfolgreich mit deinem Konto verbunden"
+
+#: hosting/views.py:810
+#, python-brace-format
+msgid "{user} does not have permission to access the card"
+msgstr "{user} hat keine Erlaubnis auf diese Karte zuzugreifen"
+
+#: hosting/views.py:819
+msgid "An error occurred. Details: {}"
+msgstr "Ein Fehler ist aufgetreten. Details: {}"
+
+#: hosting/views.py:834
+msgid "Invalid credit card"
+msgstr "Ungültige Kreditkarte"
+
+#: hosting/views.py:886
+msgid "Confirm Order"
+msgstr "Bestellung Bestätigen"
+
+#: hosting/views.py:981 hosting/views.py:1497
+msgid ""
+"The VM you are looking for is unavailable at the moment. Please contact Data "
+"Center Light support."
+msgstr "Kontaktiere den Data Center Light Support."
+
+#: hosting/views.py:989
+msgid "In order to create a VM, you need to create/upload your SSH KEY first."
+msgstr ""
+"Um eine VM zu erstellen musst du zuerst einen SSH-Key erstellen / hochladen."
+
+#: hosting/views.py:1113 hosting/views.py:1229
+msgid "Error."
+msgstr "Fehler"
+
+#: hosting/views.py:1115 hosting/views.py:1231
+msgid ""
+"There was a payment related error. On close of this popup, you will be "
+"redirected back to the payment page."
+msgstr ""
+"Es ist ein Fehler bei der Zahlung betreten. Du wirst nach dem Schliessen vom "
+"Popup zur Bezahlseite weitergeleitet"
+
+#: hosting/views.py:1266
+msgid "Thank you for the order."
+msgstr "Danke für Deine Bestellung."
+
+#: hosting/views.py:1268
+msgid ""
+"Your VM will be up and running in a few moments. We will send you a "
+"confirmation email as soon as it is ready."
+msgstr ""
+"Deine VM ist gleich bereit. Wir senden Dir eine Bestätigungsemail, sobald Du "
+"auf sie zugreifen kannst."
+
+#: hosting/views.py:1575
+msgid "Invalid number of cores"
+msgstr "Ungültige Anzahle CPU-Kerne"
+
+#: hosting/views.py:1587
+msgid "Invalid calculator properties"
+msgstr ""
+
+#: hosting/views.py:1595 hosting/views.py:1597 hosting/views.py:1599
+#: hosting/views.py:1601
+msgid "Invalid RAM size"
+msgstr "Ungültige RAM-Grösse"
+
+#: hosting/views.py:1605
+msgid "Invalid storage size"
+msgstr "Ungültige Speicher-Grösse"
+
+#: hosting/views.py:1632
+#, python-brace-format
+msgid "Incorrect pricing name. Please contact support{support_email}"
+msgstr ""
+"Ungültige Preisbezeichnung. Bitte kontaktiere den Support{support_email}"
+
+#: hosting/views.py:1710
+msgid ""
+"We could not find the requested VM. Please "
+"contact Data Center Light Support."
+msgstr "Kontaktiere den Data Center Light Support."
+
+#: hosting/views.py:1770
+msgid ""
+"We could not find the requested VM. Please contact Data Center Light Support."
+msgstr ""
+"Wir konnten die gesucht VM nicht finden. Kontaktiere den Data Center Light "
+"Support."
+
+#: hosting/views.py:1833
+msgid "Error terminating VM"
+msgstr "Fehler beenden VM"
+
+#: hosting/views.py:1864
+msgid ""
+"VM terminate action timed out. Please contact support@datacenterlight.ch for "
+"further information."
+msgstr ""
+"VM beendet wegen Zeitüberschreitung. Bitte kontaktiere "
+"support@datacenterlight.ch für weitere Informationen."
+
+#: hosting/views.py:1873
+#, python-format
+msgid "Virtual Machine %(vm_name)s Cancelled"
+msgstr "Virtuelle Maschine %(vm_name)s Kündigung"
+
+#: hosting/views.py:1975
+msgid "There was an error processing your request. Please try again."
+msgstr ""
+"Es gab einen Fehler bei der Bearbeitung Deine Anfrage. Bitte versuche es "
+"noch einmal."
+
+#~ msgid "You are not permitted to do this operation"
+#~ msgstr "Du hast keine Erlaubnis um diese Operation durchzuführen"
+
+#~ msgid "The selected card does not exist"
+#~ msgstr "Die ausgewählte Karte existiert nicht"
+
+#~ msgid "You seem to have already added this card"
+#~ msgstr "Es scheint, als hättest du diese Karte bereits hinzugefügt"
+
+#, python-format
+#~ msgid "This key exists already with the name \"%(name)s\""
+#~ msgstr "Der SSH-Key mit dem Name \"%(name)s\" existiert bereits"
+
+#~ msgid "Add your public SSH key"
+#~ msgstr "Füge deinen öffentlichen SSH-Key hinzu"
+
+#~ msgid "Do you want to cancel your Virtual Machine"
+#~ msgstr "Bist Du sicher, dass Du Deine virtuelle Maschine beenden willst"
+
+#~ msgid "Reset your password"
+#~ msgstr "Passwort zurücksetzen"
+
+#~ msgid "My VM page"
+#~ msgstr "Meine VM page"
+
+#~ msgid "VM %(VM_ID)s terminated successfully"
+#~ msgstr "VM %(VM_ID)s erfolgreich beendet"
+
+#~ msgid "days"
+#~ msgstr "Tage"
+
+#~ msgid "New Virtual Machine"
+#~ msgstr "Neue virtuelle Maschine"
+
+#~ msgid "Step 1. Select VM Template:"
+#~ msgstr "Wähle eine Vorlage"
+
+#~ msgid "Step2. Select VM Configuration"
+#~ msgstr "Wähle eine Konfiguration"
+
+#~ msgid "Price "
+#~ msgstr "Preis"
+
+#~ msgid "CHF/Month"
+#~ msgstr "CHF/Monat"
+
+#~ msgid "Start VM"
+#~ msgstr "VM jetzt starten"
+
+#~ msgid "View Invoice"
+#~ msgstr "Zur Rechnung"
+
+#~ msgid ""
+#~ "You're receiving this mail because your virtual machine [%(vm_name)s] has "
+#~ "been cancelled. \n"
+#~ "You can see your order status by clicking [my VM page] below. \n"
+#~ "If you want to order a new virtual machine, you can do it by clicking this link . \n"
+#~ msgstr ""
+#~ "Du erhälst diese E-Mail, da deine virtuelle Maschine [%(vm_name)s] "
+#~ "gekündigt wurde. \n"
+#~ "Um deinen Auftragsstatus zu sehen, klicke auf die [my VM page] unten. \n"
+#~ "Falls du eine neue virtuelle Maschine bestellen möchtest, kannst du dies "
+#~ "tun, indem du diesen "
+#~ "Link klickst . \n"
+
+#~ msgid "Finish Configuration"
+#~ msgstr "Konfiguration beenden"
+
+#~ msgid "My Virtual Machines"
+#~ msgstr "Meine virtuellen Maschinen"
+
+#~ msgid "My Orders"
+#~ msgstr "Meine Bestellungen"
+
+#~ msgid "SSH Keys"
+#~ msgstr "SSH Keys"
+
+#~ msgid "Notifications "
+#~ msgstr "Benachrichtigungen"
+
+#~ msgid "You are not making any payment here."
+#~ msgstr "Es wird noch keine Bezahlung vorgenommen"
+
+#~ msgid "Your SSH Keys"
+#~ msgstr "Deine SSH Keys"
+
+#~ msgid "Cancel Order"
+#~ msgstr "Bestellung stornieren"
+
+#~ msgid "Do you want to delete your order?"
+#~ msgstr "Willst du deine Bestellung löschen?"
+
+#~ msgid "Ip not assigned yet"
+#~ msgstr "Ip nicht zugewiesen"
+
+#~ msgid "Current status"
+#~ msgstr "Aktueller Status"
+
+#~ msgid "Terminate Virtual Machine"
+#~ msgstr "Virtuelle Maschine beenden"
+
+#~ msgid "Ipv4"
+#~ msgstr "IPv4"
+
+#~ msgid "Ipv6"
+#~ msgstr "IPv6"
+
+#~ msgid "Cancel"
+#~ msgstr "Beenden"
+
+#~ msgid "Add SSH key"
+#~ msgstr "Hinzufügen"
+
+#~ msgid "Keys"
+#~ msgstr "Keys"
+
+#~ msgid "You haven been logged out"
+#~ msgstr "Du wurdest abgemeldet"
+
+#~ msgid "How it works"
+#~ msgstr "So funktioniert es"
+
+#~ msgid "Your infrastructure"
+#~ msgstr "Deine Infrastruktur"
+
+#~ msgid "Our inftrastructure"
+#~ msgstr "Unsere Infrastruktur"
+
+#~ msgid "Pricing"
+#~ msgstr "Preise"
+
+#~ msgid "Access Key"
+#~ msgstr "SSH Key"
+
+#~ msgid "Upload your own key. "
+#~ msgstr "Lade Deinen Key hoch"
+
+#~ msgid "Generate Key Pair"
+#~ msgstr "Schlüsselpaar generieren"
+
+#~ msgid "Billing Amount"
+#~ msgstr "Rechnungsbetrag"
+
+#~ msgid "Payment Details"
+#~ msgstr "Rechnungsdetails"
+
+#~ msgid "CARD NUMBER"
+#~ msgstr "Kreditkartennummer"
+
+#~ msgid "EXPIRATION DATE"
+#~ msgstr "Ablaufdatum"
+
+#~ msgid "Copy to Clipboard"
+#~ msgstr "Kopieren"
+
+#~ msgid ""
+#~ "Your SSH private key was already generated and downloaded, if you lost "
+#~ "it, contact us. "
+#~ msgstr ""
+#~ "Dein privater SSH Key wurde bereits generiert und heruntergeladen. Falls "
+#~ "Du ihn verloren hast, kontaktiere uns."
diff --git a/hosting/mailer.py b/hosting/mailer.py
deleted file mode 100644
index 73163fa..0000000
--- a/hosting/mailer.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# import six
-from django.core.mail import send_mail
-from django.core.mail import EmailMultiAlternatives
-from django.template.loader import render_to_string
-
-
-from django.conf import settings
-
-
-class BaseEmail(object):
-
- def __init__(self, *args, **kwargs):
- self.to = kwargs.get('to')
- self.template_name = kwargs.get('template_name')
- self.template_path = kwargs.get('template_path')
- self.subject = kwargs.get('subject')
- self.context = kwargs.get('context', {})
- self.template_full_path = '%s%s' % (self.template_path, self.template_name)
- text_content = render_to_string('%s.txt' % self.template_full_path, self.context)
- html_content = render_to_string('%s.html' % self.template_full_path, self.context)
-
- self.email = EmailMultiAlternatives(self.subject, text_content)
- self.email.attach_alternative(html_content, "text/html")
- if 'from_address' in kwargs:
- self.email.from_email = kwargs.get('from_address')
- else:
- self.email.from_email = '(ungleich) ungleich Support '
- self.email.to = [kwargs.get('to', 'info@ungleich.ch')]
-
- def send(self):
- self.email.send()
\ No newline at end of file
diff --git a/hosting/management/__init__.py b/hosting/management/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/hosting/management/commands/__init__.py b/hosting/management/commands/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/hosting/management/commands/create_vm_types.py b/hosting/management/commands/create_vm_types.py
new file mode 100755
index 0000000..0b5f8df
--- /dev/null
+++ b/hosting/management/commands/create_vm_types.py
@@ -0,0 +1,106 @@
+from django.core.management.base import BaseCommand
+from hosting.models import VirtualMachineType
+
+
+class Command(BaseCommand):
+ help = 'Create VM types'
+
+ def get_data(self):
+
+ return [
+ {
+ 'base_price': 10,
+ 'core_price': 5,
+ 'memory_price': 2,
+ 'disk_size_price': 0.6,
+ 'cores': 1,
+ 'memory': 2,
+ 'disk_size': 10
+ },
+ {
+ 'base_price': 10,
+ 'core_price': 5,
+ 'memory_price': 2,
+ 'disk_size_price': 0.6,
+ 'cores': 1,
+ 'memory': 2,
+ 'disk_size': 100
+ },
+ {
+ 'base_price': 10,
+ 'core_price': 5,
+ 'memory_price': 2,
+ 'disk_size_price': 0.6,
+ 'cores': 2,
+ 'memory': 4,
+ 'disk_size': 20
+ },
+ {
+ 'base_price': 10,
+ 'core_price': 5,
+ 'memory_price': 2,
+ 'disk_size_price': 0.6,
+ 'cores': 4,
+ 'memory': 8,
+ 'disk_size': 40
+ },
+ {
+ 'base_price': 10,
+ 'core_price': 5,
+ 'memory_price': 2,
+ 'disk_size_price': 0.6,
+ 'cores': 16,
+ 'memory': 8,
+ 'disk_size': 40
+ },
+ ]
+
+ # not used
+ # hetzner = {
+ # 'base_price': 10,
+ # 'core_price': 5,
+ # 'memory_price': 2,
+ # 'disk_size_price': 0.6,
+ # 'description': 'VM auf einzelner HW, Raid1, kein HA',
+ # 'location': 'DE'
+ # }
+
+ # return {
+ # # 'hetzner_nug': {
+ # # 'base_price': 5,
+ # # 'memory_price': 2,
+ # # 'core_price': 2,
+ # # 'disk_size_price': 0.5,
+ # # 'description': 'VM ohne Uptime Garantie'
+ # # },
+ # 'hetzner': hetzner,
+ # # 'hetzner_raid6': {
+ # # 'base_price': hetzner['base_price']*1.2,
+ # # 'core_price': hetzner['core_price']*1.2,
+ # # 'memory_price': hetzner['memory_price']*1.2,
+ # # 'disk_size_price': hetzner['disk_size_price']*1.2,
+ # # 'description': 'VM auf einzelner HW, Raid1, kein HA'
+
+ # # },
+ # # 'hetzner_glusterfs': {
+ # # 'base_price': hetzner['base_price']*1.4,
+ # # 'core_price': hetzner['core_price']*1.4,
+ # # 'memory_price': hetzner['memory_price']*1.4,
+ # # 'disk_size_price': hetzner['disk_size_price']*1.4,
+ # # 'description': 'VM auf einzelner HW, Raid1, kein HA'
+ # # },
+ # 'bern': {
+ # 'base_price': 12,
+ # 'core_price': 25,
+ # 'memory_price': 7,
+ # 'disk_size_price': 0.70,
+ # 'description': "VM in Bern, HA Setup ohne HA Garantie",
+ # 'location': 'CH',
+ # }
+ # }
+
+ def handle(self, *args, **options):
+
+ vm_data = self.get_data()
+ for vm in vm_data:
+ VirtualMachineType.objects.create(**vm)
diff --git a/hosting/management/commands/fetch_stripe_bills.py b/hosting/management/commands/fetch_stripe_bills.py
new file mode 100755
index 0000000..b3331dd
--- /dev/null
+++ b/hosting/management/commands/fetch_stripe_bills.py
@@ -0,0 +1,81 @@
+import datetime
+import logging
+
+from django.core.management.base import BaseCommand
+
+from hosting.models import MonthlyHostingBill
+from membership.models import CustomUser
+from utils.stripe_utils import StripeUtils
+
+logger = logging.getLogger(__name__)
+
+
+class Command(BaseCommand):
+ help = '''Fetches invoices from Stripe and creates bills for a given
+ customer in the MonthlyHostingBill model'''
+
+ def add_arguments(self, parser):
+ parser.add_argument('customer_email', nargs='+', type=str)
+
+ def handle(self, *args, **options):
+ try:
+ for email in options['customer_email']:
+ self.stdout.write(
+ self.style.SUCCESS(
+ "---------------------------------------------")
+ )
+ stripe_utils = StripeUtils()
+ user = CustomUser.objects.get(email=email)
+ if hasattr(user, 'stripecustomer'):
+ self.stdout.write(self.style.SUCCESS(
+ 'Found %s. Fetching bills for him.' % email))
+ mhb = MonthlyHostingBill.objects.filter(
+ customer=user.stripecustomer).last()
+ created_gt = {}
+ if mhb is not None:
+ # fetch only invoices which is created after
+ # mhb.created, because we already have invoices till
+ # this date
+ created_gt = int(mhb.created.timestamp())
+
+ all_invoices_response = stripe_utils.get_all_invoices(
+ user.stripecustomer.stripe_id,
+ created_gt=created_gt
+ )
+ if all_invoices_response['error'] is not None:
+ self.stdout.write(self.style.ERROR(all_invoices_response['error']))
+ user.import_stripe_bill_remark += "{}: {},".format(datetime.datetime.now(), all_invoices_response['error'])
+ user.save()
+ continue
+ all_invoices = all_invoices_response['response_object']
+ self.stdout.write(self.style.SUCCESS("Obtained {} invoices".format(len(all_invoices) if all_invoices is not None else 0)))
+ num_invoice_created = 0
+ for invoice in all_invoices:
+ invoice['customer'] = user.stripecustomer
+ try:
+ existing_mhb = MonthlyHostingBill.objects.get(invoice_id=invoice['invoice_id'])
+ logger.debug("Invoice %s exists already. Not importing." % invoice['invoice_id'])
+ except MonthlyHostingBill.DoesNotExist as dne:
+ logger.debug("Invoice id %s does not exist" % invoice['invoice_id'])
+
+ if MonthlyHostingBill.create(invoice) is not None:
+ num_invoice_created += 1
+ else:
+ user.import_stripe_bill_remark += "{}: Import failed - {},".format(
+ datetime.datetime.now(),
+ invoice['invoice_id'])
+ user.save()
+ logger.error("Did not import invoice for %s"
+ "" % str(invoice))
+ self.stdout.write(
+ self.style.SUCCESS("Number of invoices imported = %s" % num_invoice_created)
+ )
+ else:
+ self.stdout.write(self.style.SUCCESS(
+ 'Customer email %s does not have a stripe customer.' % email))
+ user.import_stripe_bill_remark += "{}: No stripecustomer,".format(
+ datetime.datetime.now()
+ )
+ user.save()
+ except Exception as e:
+ print(" *** Error occurred. Details {}".format(str(e)))
diff --git a/hosting/management/commands/import_usercarddetails.py b/hosting/management/commands/import_usercarddetails.py
new file mode 100755
index 0000000..de5a91f
--- /dev/null
+++ b/hosting/management/commands/import_usercarddetails.py
@@ -0,0 +1,45 @@
+from django.core.management.base import BaseCommand
+
+from hosting.models import UserCardDetail
+from membership.models import CustomUser
+from utils.stripe_utils import StripeUtils
+
+
+class Command(BaseCommand):
+ help = '''Imports the usercard details of all customers. Created just for
+ multiple card support.'''
+
+ def handle(self, *args, **options):
+ try:
+ stripe_utils = StripeUtils()
+ for user in CustomUser.objects.all():
+ if hasattr(user, 'stripecustomer'):
+ if user.stripecustomer:
+ card_details_resp = stripe_utils.get_card_details(
+ user.stripecustomer.stripe_id
+ )
+ card_details = card_details_resp['response_object']
+ if card_details:
+ ucd = UserCardDetail.get_or_create_user_card_detail(
+ stripe_customer=user.stripecustomer,
+ card_details=card_details
+ )
+ UserCardDetail.save_default_card_local(
+ user.stripecustomer.stripe_id,
+ ucd.card_id
+ )
+ print("Saved user card details for {}".format(
+ user.email
+ ))
+ else:
+ print(" --- Could not get card details for "
+ "{}".format(user.email))
+ print(" --- Error: {}".format(
+ card_details_resp['error']
+ ))
+ else:
+ print(" === {} does not have a StripeCustomer object".format(
+ user.email
+ ))
+ except Exception as e:
+ print(" *** Error occurred. Details {}".format(str(e)))
diff --git a/hosting/management/commands/import_vat_rates.py b/hosting/management/commands/import_vat_rates.py
new file mode 100755
index 0000000..f779133
--- /dev/null
+++ b/hosting/management/commands/import_vat_rates.py
@@ -0,0 +1,44 @@
+from django.core.management.base import BaseCommand
+import csv
+from hosting.models import VATRates
+
+
+class Command(BaseCommand):
+ help = '''Imports VAT Rates. Assume vat rates of format https://github.com/kdeldycke/vat-rates/blob/master/vat_rates.csv'''
+
+ def add_arguments(self, parser):
+ parser.add_argument('csv_file', nargs='+', type=str)
+
+ def handle(self, *args, **options):
+ try:
+ for c_file in options['csv_file']:
+ print("c_file = %s" % c_file)
+ with open(c_file, mode='r') as csv_file:
+ csv_reader = csv.DictReader(csv_file)
+ line_count = 0
+ for row in csv_reader:
+ if line_count == 0:
+ line_count += 1
+ obj, created = VATRates.objects.get_or_create(
+ start_date=row["start_date"],
+ stop_date=row["stop_date"] if row["stop_date"] is not "" else None,
+ territory_codes=row["territory_codes"],
+ currency_code=row["currency_code"],
+ rate=row["rate"],
+ rate_type=row["rate_type"],
+ description=row["description"]
+ )
+ if created:
+ self.stdout.write(self.style.SUCCESS(
+ '%s. %s - %s - %s - %s' % (
+ line_count,
+ obj.start_date,
+ obj.stop_date,
+ obj.territory_codes,
+ obj.rate
+ )
+ ))
+ line_count+=1
+
+ except Exception as e:
+ print(" *** Error occurred. Details {}".format(str(e)))
diff --git a/hosting/managers.py b/hosting/managers.py
new file mode 100755
index 0000000..c474d61
--- /dev/null
+++ b/hosting/managers.py
@@ -0,0 +1,9 @@
+from django.db import models
+
+
+class VMPlansManager(models.Manager):
+
+ def active(self, user, **kwargs):
+ return self.prefetch_related('hosting_orders__customer__user').\
+ filter(hosting_orders__customer__user=user, hosting_orders__approved=True, **kwargs)\
+ .distinct()
diff --git a/hosting/migrations/0001_initial.py b/hosting/migrations/0001_initial.py
new file mode 100644
index 0000000..c741f90
--- /dev/null
+++ b/hosting/migrations/0001_initial.py
@@ -0,0 +1,261 @@
+# Generated by Django 4.2.7 on 2023-12-07 10:47
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+import utils.mixins
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ('datacenterlight', '0008_dclcalculatorpluginmodel_vm_templates_to_show'),
+ ('membership', '0001_initial'),
+ ('utils', '__first__'),
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='GenericProduct',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('product_name', models.CharField(default='', max_length=128)),
+ ('product_slug', models.SlugField(help_text='An mandatory unique slug for the product', unique=True)),
+ ('product_description', models.CharField(default='', max_length=500)),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ('product_price', models.DecimalField(decimal_places=2, max_digits=6)),
+ ('product_vat', models.DecimalField(decimal_places=4, default=0, max_digits=6)),
+ ('product_is_subscription', models.BooleanField(default=True)),
+ ('product_subscription_interval', models.CharField(default='month', help_text='Choose between `year` and `month`', max_length=10)),
+ ('exclude_vat_calculations', models.BooleanField(default=False, help_text='When checked VAT calculations are excluded for this product')),
+ ],
+ bases=(utils.mixins.AssignPermissionsMixin, models.Model),
+ ),
+ migrations.CreateModel(
+ name='HostingOrder',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('vm_id', models.IntegerField(default=0)),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ('approved', models.BooleanField(default=False)),
+ ('last4', models.CharField(max_length=4)),
+ ('cc_brand', models.CharField(max_length=128)),
+ ('stripe_charge_id', models.CharField(max_length=100, null=True)),
+ ('price', models.FloatField()),
+ ('subscription_id', models.CharField(max_length=100, null=True)),
+ ('generic_payment_description', models.CharField(max_length=500, null=True)),
+ ('billing_address', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='utils.billingaddress')),
+ ('customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='membership.stripecustomer')),
+ ('generic_product', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='hosting.genericproduct')),
+ ],
+ options={
+ 'permissions': (('pr_view_hostingorder', 'View Hosting Order'),),
+ },
+ bases=(utils.mixins.AssignPermissionsMixin, models.Model),
+ ),
+ migrations.CreateModel(
+ name='HostingPlan',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('disk_size', models.FloatField(default=0.0)),
+ ('cpu_cores', models.FloatField(default=0.0)),
+ ('memory', models.FloatField(default=0.0)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='IncompletePaymentIntents',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('completed_at', models.DateTimeField(null=True)),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ('payment_intent_id', models.CharField(max_length=100)),
+ ('request', models.TextField()),
+ ('stripe_api_cus_id', models.CharField(max_length=30)),
+ ('card_details_response', models.TextField()),
+ ('stripe_subscription_id', models.CharField(max_length=100, null=True)),
+ ('stripe_charge_id', models.CharField(max_length=100, null=True)),
+ ('gp_details', models.TextField()),
+ ('billing_address_data', models.TextField()),
+ ],
+ bases=(utils.mixins.AssignPermissionsMixin, models.Model),
+ ),
+ migrations.CreateModel(
+ name='IncompleteSubscriptions',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ('completed_at', models.DateTimeField(null=True)),
+ ('subscription_id', models.CharField(max_length=100)),
+ ('subscription_status', models.CharField(max_length=30)),
+ ('name', models.CharField(max_length=50)),
+ ('email', models.EmailField(max_length=254)),
+ ('request', models.TextField()),
+ ('stripe_api_cus_id', models.CharField(max_length=30)),
+ ('card_details_response', models.TextField()),
+ ('stripe_subscription_obj', models.TextField()),
+ ('stripe_onetime_charge', models.TextField()),
+ ('gp_details', models.TextField()),
+ ('specs', models.TextField()),
+ ('vm_template_id', models.PositiveIntegerField(default=0)),
+ ('template', models.TextField()),
+ ('billing_address_data', models.TextField()),
+ ],
+ bases=(utils.mixins.AssignPermissionsMixin, models.Model),
+ ),
+ migrations.CreateModel(
+ name='StripeTaxRate',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('tax_rate_id', models.CharField(max_length=100, unique=True)),
+ ('jurisdiction', models.CharField(max_length=10)),
+ ('inclusive', models.BooleanField(default=False)),
+ ('display_name', models.CharField(max_length=100)),
+ ('percentage', models.FloatField(default=0)),
+ ('description', models.CharField(max_length=100)),
+ ],
+ bases=(utils.mixins.AssignPermissionsMixin, models.Model),
+ ),
+ migrations.CreateModel(
+ name='VATRates',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('start_date', models.DateField(blank=True, null=True)),
+ ('stop_date', models.DateField(blank=True, null=True)),
+ ('territory_codes', models.TextField(blank=True, default='')),
+ ('currency_code', models.CharField(max_length=10)),
+ ('rate', models.FloatField()),
+ ('rate_type', models.TextField(blank=True, default='')),
+ ('description', models.TextField(blank=True, default='')),
+ ],
+ bases=(utils.mixins.AssignPermissionsMixin, models.Model),
+ ),
+ migrations.CreateModel(
+ name='VMDetail',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('vm_id', models.IntegerField(default=0)),
+ ('disk_size', models.FloatField(default=0.0)),
+ ('cores', models.FloatField(default=0.0)),
+ ('memory', models.FloatField(default=0.0)),
+ ('configuration', models.CharField(default='', max_length=128)),
+ ('ipv4', models.TextField(default='')),
+ ('ipv6', models.TextField(default='')),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ('terminated_at', models.DateTimeField(null=True)),
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='UserHostingKey',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('public_key', models.TextField()),
+ ('private_key', models.FileField(blank=True, upload_to='private_keys')),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ('name', models.CharField(max_length=100)),
+ ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='UserCardDetail',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('last4', models.CharField(max_length=4)),
+ ('brand', models.CharField(max_length=128)),
+ ('card_id', models.CharField(blank=True, default='', max_length=100)),
+ ('fingerprint', models.CharField(max_length=100)),
+ ('exp_month', models.IntegerField()),
+ ('exp_year', models.IntegerField()),
+ ('preferred', models.BooleanField(default=False)),
+ ('stripe_customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='membership.stripecustomer')),
+ ],
+ options={
+ 'permissions': (('pr_view_usercarddetail', 'View User Card'),),
+ },
+ bases=(utils.mixins.AssignPermissionsMixin, models.Model),
+ ),
+ migrations.CreateModel(
+ name='OrderDetail',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('cores', models.IntegerField(default=0)),
+ ('memory', models.IntegerField(default=0)),
+ ('hdd_size', models.IntegerField(default=0)),
+ ('ssd_size', models.IntegerField(default=0)),
+ ('vm_template', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='datacenterlight.vmtemplate')),
+ ],
+ bases=(utils.mixins.AssignPermissionsMixin, models.Model),
+ ),
+ migrations.CreateModel(
+ name='MonthlyHostingBill',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('created', models.DateTimeField(help_text='When the invoice was created')),
+ ('receipt_number', models.CharField(help_text='The receipt number that is generated on Stripe', max_length=100)),
+ ('invoice_number', models.CharField(help_text='The invoice number that is generated on Stripe', max_length=100)),
+ ('paid_at', models.DateTimeField(help_text='Date on which the bill was paid')),
+ ('period_start', models.DateTimeField()),
+ ('period_end', models.DateTimeField()),
+ ('billing_reason', models.CharField(max_length=25)),
+ ('discount', models.PositiveIntegerField()),
+ ('total', models.IntegerField()),
+ ('lines_data_count', models.IntegerField()),
+ ('invoice_id', models.CharField(max_length=100, unique=True)),
+ ('lines_meta_data_csv', models.TextField(default='')),
+ ('subscription_ids_csv', models.TextField(default='')),
+ ('customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='membership.stripecustomer')),
+ ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hosting.hostingorder')),
+ ],
+ options={
+ 'permissions': (('pr_view_monthlyhostingbill', 'View Monthly Hosting'),),
+ },
+ bases=(utils.mixins.AssignPermissionsMixin, models.Model),
+ ),
+ migrations.AddField(
+ model_name='hostingorder',
+ name='order_detail',
+ field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='hosting.orderdetail'),
+ ),
+ migrations.AddField(
+ model_name='hostingorder',
+ name='vm_pricing',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='datacenterlight.vmpricing'),
+ ),
+ migrations.CreateModel(
+ name='HostingBillLineItem',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('amount', models.IntegerField()),
+ ('description', models.CharField(max_length=255)),
+ ('discountable', models.BooleanField()),
+ ('metadata', models.CharField(max_length=128)),
+ ('period_start', models.DateTimeField()),
+ ('period_end', models.DateTimeField()),
+ ('proration', models.BooleanField()),
+ ('quantity', models.PositiveIntegerField()),
+ ('unit_amount', models.PositiveIntegerField()),
+ ('monthly_hosting_bill', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hosting.monthlyhostingbill')),
+ ('stripe_plan', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='datacenterlight.stripeplan')),
+ ],
+ options={
+ 'permissions': (('pr_view_hostingbilllineitem', 'View Monthly Hosting Bill Line Item'),),
+ },
+ bases=(utils.mixins.AssignPermissionsMixin, models.Model),
+ ),
+ migrations.CreateModel(
+ name='HostingBill',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('total_price', models.FloatField(default=0.0)),
+ ('billing_address', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='utils.billingaddress')),
+ ('customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='membership.stripecustomer')),
+ ],
+ options={
+ 'permissions': (('pr_view_hostingbill', 'View Hosting Bill'),),
+ },
+ bases=(utils.mixins.AssignPermissionsMixin, models.Model),
+ ),
+ ]
diff --git a/hosting/mixins.py b/hosting/mixins.py
old mode 100644
new mode 100755
index 849cf2f..e863b8d
--- a/hosting/mixins.py
+++ b/hosting/mixins.py
@@ -1,181 +1,36 @@
-from django.contrib.auth import authenticate, login
-from django.contrib.auth.forms import SetPasswordForm
-from django.contrib.auth.tokens import default_token_generator
-from django.http import HttpResponseRedirect
-from django.shortcuts import render
-from django.utils.encoding import force_bytes
-from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
-from django.utils.translation import gettext_lazy as _
-from django.urls import reverse_lazy
-from django.views.decorators.cache import cache_control
-from django.views.generic import FormView, CreateView
+from django.shortcuts import redirect
from django.conf import settings
-from django.contrib import messages
-from guardian.shortcuts import assign_perm
+from django.urls import reverse
+from django.utils.decorators import method_decorator
+from django.views.decorators.cache import cache_control
-from .mailer import BaseEmail
-from hosting.models import CustomUser
+from opennebula_api.serializers import VirtualMachineTemplateSerializer
+from opennebula_api.opennebula_manager import OpenNebulaManager
-# Create your views here.
+from .models import HostingPlan
-class SignupViewMixin(CreateView):
- model = CustomUser
- success_url = None
+class ProcessVMSelectionMixin(object):
- def get_success_url(self):
- next_url = self.request.POST.get('next') if self.request.POST.get(
- 'next') \
- else self.success_url
+ def post(self, request, *args, **kwargs):
- return next_url
+ template_id = int(request.POST.get('vm_template_id'))
+ configuration_id = int(request.POST.get('configuration'))
+ template = OpenNebulaManager().get_template(template_id)
+ data = VirtualMachineTemplateSerializer(template).data
+ configuration = HostingPlan.objects.get(id=configuration_id)
- def form_valid(self, form):
- name = form.cleaned_data.get('name')
- email = form.cleaned_data.get('email')
- password = form.cleaned_data.get('password')
+ request.session['template'] = data
+ request.session['specs'] = configuration.serialize()
- CustomUser.register(name, password, email)
- auth_user = authenticate(email=email, password=password)
- login(self.request, auth_user)
-
- return HttpResponseRedirect(self.get_success_url())
+ if not request.user.is_authenticated():
+ request.session['next'] = reverse('hosting:payment')
+ return redirect(reverse('hosting:login'))
+ return redirect(reverse('hosting:payment'))
-class LoginViewMixin(FormView):
- success_url = None
-
- def get_success_url(self):
- next_url = self.request.POST.get('next', self.success_url)
- if not next_url:
- return self.success_url
- return next_url
-
- def form_valid(self, form):
- email = form.cleaned_data.get('email')
- password = form.cleaned_data.get('password')
- auth_user = authenticate(email=email, password=password)
-
- if auth_user:
- login(self.request, auth_user)
- return HttpResponseRedirect(self.get_success_url())
-
- return HttpResponseRedirect(self.get_success_url())
-
- # @cache_control(no_cache=True, must_revalidate=True, no_store=True)
- def get(self, request, *args, **kwargs):
- if self.request.user.is_authenticated:
- return HttpResponseRedirect(self.get_success_url())
-
- return super(LoginViewMixin, self).get(request, *args, **kwargs)
-
-
-class ResendActivationLinkViewMixin(FormView):
- success_message = _(
- "An email with the activation link has been sent to you")
-
- def generate_email_context(self, user):
- context = {
- 'base_url': "{0}://{1}".format(self.request.scheme,
- self.request.get_host()),
- 'activation_link': reverse_lazy(
- 'hosting:validate',
- kwargs={'validate_slug': user.validation_slug}
- ),
- 'dcl_text': settings.DCL_TEXT,
- }
+class HostingContextMixin(object):
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ #context['MULTISITE_CMS_FALLBACK'] = settings.MULTISITE_CMS_FALLBACK
return context
-
- def form_valid(self, form):
- email = form.cleaned_data.get('email')
- user = CustomUser.objects.get(email=email)
- messages.add_message(self.request, messages.SUCCESS,
- self.success_message)
- context = self.generate_email_context(user)
- email_data = {
- 'subject': '{dcl_text} {account_activation}'.format(
- dcl_text=settings.DCL_TEXT,
- account_activation=_('Account Activation')
- ),
- 'to': email,
- 'context': context,
- 'template_name': self.email_template_name,
- 'template_path': self.email_template_path,
- 'from_address': settings.DCL_SUPPORT_FROM_ADDRESS
- }
- email = BaseEmail(**email_data)
- email.send()
- return HttpResponseRedirect(self.get_success_url())
-
-
-class PasswordResetViewMixin(FormView):
- success_message = _(
- "The link to reset your password has been sent to your email")
- site = ''
-
- def test_generate_email_context(self, user):
- context = {
- 'user': user,
- 'token': default_token_generator.make_token(user),
- 'uid': urlsafe_base64_encode(force_bytes(user.pk)),
- 'site_name': 'ungleich' if self.site != 'dcl' else settings.DCL_TEXT,
- 'base_url': "{0}://{1}".format(self.request.scheme,
- self.request.get_host())
- }
- return context
-
- def form_valid(self, form):
- email = form.cleaned_data.get('email')
- user = CustomUser.objects.get(email=email)
- messages.add_message(self.request, messages.SUCCESS,
- self.success_message)
- context = self.test_generate_email_context(user)
- email_data = {
- 'subject': _('Password Reset'),
- 'to': email,
- 'context': context,
- 'template_name': 'password_reset_email',
- 'template_path': self.template_email_path
- }
- if self.site == 'dcl':
- email_data['from_address'] = settings.DCL_SUPPORT_FROM_ADDRESS
- email = BaseEmail(**email_data)
- email.send()
-
- return HttpResponseRedirect(self.get_success_url())
-
-
-class PasswordResetConfirmViewMixin(FormView):
- form_class = SetPasswordForm
-
- def post(self, request, uidb64=None, token=None, *arg, **kwargs):
- try:
- uid = urlsafe_base64_decode(uidb64)
- user = CustomUser.objects.get(pk=uid)
- except (TypeError, ValueError, OverflowError, CustomUser.DoesNotExist):
- user = None
-
- form = self.form_class(request.POST)
-
- if user is not None and default_token_generator.check_token(user,
- token):
- if form.is_valid():
- new_password = form.cleaned_data['new_password2']
- user.set_password(new_password)
- user.save()
- messages.success(request, _('Password has been reset.'))
- return self.form_valid(form)
- else:
- messages.error(request,
- _('Password reset has not been successful.'))
- form.add_error(None,
- _('Password reset has not been successful.'))
- return self.form_invalid(form)
-
- else:
- messages.error(request,
- _('The reset password link is no longer valid.'))
- form.add_error(None,
- _('The reset password link is no longer valid.'))
- return self.form_invalid(form)
-
diff --git a/hosting/models.py b/hosting/models.py
index 28b25be..9ffa1c5 100644
--- a/hosting/models.py
+++ b/hosting/models.py
@@ -1,425 +1,55 @@
-import unicodedata
+import json
import logging
-import random
import os
+from datetime import datetime
-from django.db import models
-from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
-from django.contrib.sites.models import Site
-from django.core.exceptions import ValidationError
-from django.utils.translation import gettext_lazy as _
-from django.conf import settings
-from django.contrib.auth.hashers import make_password
-from django.urls import reverse
-from django.db import IntegrityError, models
-from guardian.shortcuts import assign_perm
-
-from .fields import CountryField
-from .mailer import BaseEmail
-from dynamicweb2.ldap_manager import LdapManager
-from dynamicweb2.stripe_utils import StripeUtils
-from django.utils.crypto import get_random_string
+import pytz
from Crypto.PublicKey import RSA
-
+from dateutil.relativedelta import relativedelta
+from django.db import models
+from django.utils import timezone
from django.utils.functional import cached_property
-# Create your models here.
+from datacenterlight.models import VMPricing, VMTemplate, StripePlan
+from membership.models import StripeCustomer, CustomUser
+from utils.mixins import AssignPermissionsMixin
+from utils.models import BillingAddress
+from utils.stripe_utils import StripeUtils
logger = logging.getLogger(__name__)
-def get_validation_slug():
- return make_password(None)
+class HostingPlan(models.Model):
+ disk_size = models.FloatField(default=0.0)
+ cpu_cores = models.FloatField(default=0.0)
+ memory = models.FloatField(default=0.0)
-
-def validate_name(value):
- valid_chars = [char for char in value if (char.isalpha() or char == "-" or char == " ")]
- if len(valid_chars) < len(value):
- raise ValidationError(
- _('%(value)s is not a valid name. A valid name can only include letters, spaces or -'),
- params={'value': value},
- )
-
-
-class MyUserManager(BaseUserManager):
- def create_user(self, email, name, password=None):
- """
- Creates and saves a User with the given email,name and password.
- """
-
- if not email:
- raise ValueError('Users must have an email address')
-
- user = self.model(
- email=self.normalize_email(email),
- name=name,
- validation_slug=make_password(None)
- )
- user.is_admin = False
- user.set_password(password)
- user.save(using=self._db)
- user.create_ldap_account(password)
- return user
-
- def create_superuser(self, email, name, password):
- """
- Creates and saves a superuser with the given email, name and password.
- """
- user = self.create_user(email,
- password=password,
- name=name,
- )
- user.is_admin = True
- user.is_active = True
- user.is_superuser = True
- user.save(using=self._db)
- return user
-
-
-class CustomUser(AbstractBaseUser, PermissionsMixin):
- VALIDATED_CHOICES = ((0, 'Not validated'), (1, 'Validated'))
- site = models.ForeignKey(Site, default=1, on_delete=models.CASCADE)
- name = models.CharField(max_length=50, validators=[validate_name])
- email = models.EmailField(unique=True)
- username = models.CharField(max_length=60, unique=True, null=True)
- validated = models.IntegerField(choices=VALIDATED_CHOICES, default=0)
- in_ldap = models.BooleanField(default=False)
- # By default, we initialize the validation_slug with appropriate value
- # This is required for User(page) admin
- validation_slug = models.CharField(
- db_index=True, unique=True, max_length=50,
- default=get_validation_slug
- )
- is_admin = models.BooleanField(
- _('staff status'),
- default=False,
- help_text=_(
- 'Designates whether the user can log into this admin site.'),
- )
- import_stripe_bill_remark = models.TextField(
- default="",
- help_text="Indicates any issues while importing stripe bills"
- )
-
- objects = MyUserManager()
-
- USERNAME_FIELD = "email"
- REQUIRED_FIELDS = ['name', 'password']
-
- # Define the groups field with a related_name to avoid clash
- groups = models.ManyToManyField(
- 'auth.Group',
- related_name='custom_user_set', # Define a unique related_name
- blank=True,
- verbose_name='groups',
- help_text='The groups this user belongs to.',
- )
-
- # Define the user_permissions field with a related_name to avoid clash
- user_permissions = models.ManyToManyField(
- 'auth.Permission',
- related_name='custom_user_permission_set', # Define a unique related_name
- blank=True,
- verbose_name='user permissions',
- help_text='Specific permissions for this user.',
- )
-
- @classmethod
- def register(cls, name, password, email, app='digital_glarus',
- base_url=None, send_email=True, account_details=None):
- user = cls.objects.filter(email=email).first()
- if not user:
- user = cls.objects.create_user(name=name, email=email,
- password=password)
- if user:
- if app == 'dcl':
- dcl_text = settings.DCL_TEXT
- user.is_active = False
- if send_email is True:
- email_data = {
- 'subject': '{dcl_text} {account_activation}'.format(
- dcl_text=dcl_text,
- account_activation=_('Account Activation')
- ),
- 'from_address': settings.DCL_SUPPORT_FROM_ADDRESS,
- 'to': user.email,
- 'context': {'base_url': base_url,
- 'activation_link': reverse(
- 'hosting:validate',
- kwargs={
- 'validate_slug': user.validation_slug}),
- 'dcl_text': dcl_text
- },
- 'template_name': 'user_activation',
- 'template_path': 'hosting/emails/'
- }
- if account_details:
- email_data['context'][
- 'account_details'] = account_details
- email = BaseEmail(**email_data)
- email.send()
- return user
- else:
- return None
- else:
- return None
-
- @classmethod
- def get_all_members(cls):
- return cls.objects.filter(
- stripecustomer__membershiporder__isnull=False)
-
- @classmethod
- def validate_url(cls, validation_slug):
- user = cls.objects.filter(validation_slug=validation_slug).first()
- if user:
- user.validated = 1
- user.save()
- return True
- return False
-
- @classmethod
- def get_random_password(cls):
- return get_random_string(24)
-
- def is_superuser(self):
- return False
-
- def get_full_name(self):
- # The user is identified by their email address
- return self.email
-
- def get_short_name(self):
- # The user is identified by their email address
- return self.email
-
- def get_first_and_last_name(self, full_name):
- first_name, *last_name = full_name.split(" ")
- last_name = " ".join(last_name)
- return first_name, last_name
-
- def assign_username(self, user):
- if not user.username:
- ldap_manager = LdapManager()
-
- # Try to come up with a username
- first_name, last_name = self.get_first_and_last_name(user.name)
- user.username = unicodedata.normalize('NFKD', first_name + last_name)
- user.username = "".join([char for char in user.username if char.isalnum()]).lower()
- exist = True
- while exist:
- # Check if it exists
- exist, entries = ldap_manager.check_user_exists(user.username)
- if exist:
- # If username exists in ldap, come up with a new user name and check it again
- user.username = user.username + str(random.randint(0, 2 ** 10))
- else:
- # If username does not exists in ldap, try to save it in database
- try:
- user.save()
- except IntegrityError:
- # If username exists in database then come up with a new username
- user.username = user.username + str(random.randint(0, 2 ** 10))
- exist = True
-
- def create_ldap_account(self, password):
- # create ldap account for user if it does not exists already.
- if self.in_ldap:
- return
- self.assign_username(self)
- ldap_manager = LdapManager()
- try:
- user_exists_in_ldap, entries = ldap_manager.check_user_exists(self.username)
- except Exception:
- logger.exception("Exception occur while searching for user in LDAP")
- else:
- if not user_exists_in_ldap:
- # IF no ldap account
- first_name, last_name = self.get_first_and_last_name(self.name)
- if not last_name:
- last_name = first_name
- ldap_manager.create_user(self.username, password=password,
- firstname=first_name, lastname=last_name,
- email=self.email)
- else:
- # User exists already in LDAP, but with a dummy credential
- # We are here implies that the user has successfully
- # authenticated against Django db, and a corresponding user
- # exists in LDAP.
- # We just update the LDAP credentials once again, assuming it
- # was set to a dummy value while migrating users from Django to
- # LDAP
- ldap_manager.change_password(self.username, password)
- self.in_ldap = True
- self.save()
-
- def __str__(self): # __unicode__ on Python 2
- return self.email
-
- # def has_perm(self, perm, obj=None):
- # "Does the user have a specific permission?"
- # # Simplest possible answer: Yes, always
- # return self.is_admin
-
- def has_module_perms(self, app_label):
- "Does the user have permissions to view the app `app_label`?"
- # Simplest possible answer: Yes, always
- return self.is_admin
-
- @property
- def is_staff(self):
- "Is the user a member of staff?"
- # Simplest possible answer: All admins are staff
- return self.is_admin
-
- @is_staff.setter
- def is_staff(self, value):
- self._is_staff = value
-
-
-class StripeCustomer(models.Model):
- user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
- stripe_id = models.CharField(unique=True, max_length=100)
-
- def __str__(self):
- return "%s - %s" % (self.stripe_id, self.user.email)
-
- @classmethod
- def create_stripe_api_customer(cls, email=None, id_payment_method=None,
- customer_name=None):
- """
- This method creates a Stripe API customer with the given
- email, token and customer_name. This is different from
- get_or_create method below in that it does not create a
- CustomUser and associate the customer created in stripe
- with it, while get_or_create does that before creating the
- stripe user.
- """
- stripe_utils = StripeUtils()
- stripe_data = stripe_utils.create_customer(
- id_payment_method, email, customer_name)
- if stripe_data.get('response_object'):
- stripe_cus_id = stripe_data.get('response_object').get('id')
- return stripe_cus_id
- else:
- return None
-
- @classmethod
- def get_or_create(cls, email=None, token=None, id_payment_method=None):
- """
- Check if there is a registered stripe customer with that email
- or create a new one
- """
- try:
- stripe_utils = StripeUtils()
- stripe_customer = cls.objects.get(user__email=email)
- # check if user is not in stripe but in database
- customer = stripe_utils.check_customer(stripe_customer.stripe_id,
- stripe_customer.user, token)
- if "deleted" in customer and customer["deleted"]:
- raise StripeCustomer.DoesNotExist()
- return stripe_customer
- except StripeCustomer.DoesNotExist:
- user = CustomUser.objects.get(email=email)
- stripe_utils = StripeUtils()
- stripe_data = stripe_utils.create_customer(token, email, user.name)
- if stripe_data.get('response_object'):
- stripe_cus_id = stripe_data.get('response_object').get('id')
- if hasattr(user, 'stripecustomer'):
- # User already had a Stripe account and we are here
- # because the account was deleted in dashboard
- # So, we simply update the stripe_id
- user.stripecustomer.stripe_id = stripe_cus_id
- user.stripecustomer.save()
- stripe_customer = user.stripecustomer
- else:
- # The user never had an associated Stripe account
- # So, create one
- stripe_customer = StripeCustomer.objects.create(
- user=user, stripe_id=stripe_cus_id
- )
- return stripe_customer
- else:
- return None
-
-
-class BaseBillingAddress(models.Model):
- cardholder_name = models.CharField(max_length=100, default="")
- street_address = models.CharField(max_length=100)
- city = models.CharField(max_length=50)
- postal_code = models.CharField(max_length=50)
- country = CountryField()
- vat_number = models.CharField(max_length=100, default="", blank=True)
- stripe_tax_id = models.CharField(max_length=100, default="", blank=True)
- vat_number_validated_on = models.DateTimeField(blank=True, null=True)
- vat_validation_status = models.CharField(max_length=25, default="",
- blank=True)
-
- class Meta:
- abstract = True
-
-
-class BillingAddress(BaseBillingAddress):
- def __str__(self):
- if self.vat_number:
- return "%s, %s, %s, %s, %s, %s %s %s %s" % (
- self.cardholder_name, self.street_address, self.city,
- self.postal_code, self.country, self.vat_number,
- self.stripe_tax_id, self.vat_number_validated_on,
- self.vat_validation_status
- )
- else:
- return "%s, %s, %s, %s, %s" % (
- self.cardholder_name, self.street_address, self.city,
- self.postal_code, self.country
- )
-
-
-class UserBillingAddress(BaseBillingAddress):
- user = models.ForeignKey(CustomUser, related_name='billing_addresses', on_delete=models.CASCADE)
- current = models.BooleanField(default=True)
-
- def __str__(self):
- if self.vat_number:
- return "%s, %s, %s, %s, %s, %s %s %s %s" % (
- self.cardholder_name, self.street_address, self.city,
- self.postal_code, self.country, self.vat_number,
- self.stripe_tax_id, self.vat_number_validated_on,
- self.vat_validation_status
- )
- else:
- return "%s, %s, %s, %s, %s" % (
- self.cardholder_name, self.street_address, self.city,
- self.postal_code, self.country
- )
-
- def to_dict(self):
+ def serialize(self):
return {
- 'Cardholder Name': self.cardholder_name,
- 'Street Address': self.street_address,
- 'City': self.city,
- 'Postal Code': self.postal_code,
- 'Country': self.country,
- 'VAT Number': self.vat_number
+ 'id': self.id,
+ 'cpu': self.cpu_cores,
+ 'memory': self.memory,
+ 'disk_size': self.disk_size,
+ 'price': self.price(),
}
+ @classmethod
+ def get_serialized_configs(cls):
+ return [cfg.serialize()
+ for cfg in cls.objects.all()]
-class AssignPermissionsMixin(object):
- permissions = tuple()
- user = None
- obj = None
- kwargs = dict()
-
- def assign_permissions(self, user):
- for permission in self.permissions:
- assign_perm(permission, user, self)
+ def price(self):
+ price = self.disk_size * 0.6
+ price += self.cpu_cores * 5
+ price += self.memory * 2
+ return price
class OrderDetail(AssignPermissionsMixin, models.Model):
- # vm_template = models.ForeignKey(
- # VMTemplate, blank=True, null=True, default=None,
- # on_delete=models.SET_NULL
- # )
+ vm_template = models.ForeignKey(
+ VMTemplate, blank=True, null=True, default=None,
+ on_delete=models.SET_NULL
+ )
cores = models.IntegerField(default=0)
memory = models.IntegerField(default=0)
hdd_size = models.IntegerField(default=0)
@@ -427,10 +57,10 @@ class OrderDetail(AssignPermissionsMixin, models.Model):
def __str__(self):
return "Not available" if self.vm_template is None else (
- "%s - %s, %s cores, %s GB RAM, %s GB SSD" % (
- self.vm_template.name, self.vm_template.vm_type, self.cores,
- self.memory, self.ssd_size
- )
+ "%s - %s, %s cores, %s GB RAM, %s GB SSD" % (
+ self.vm_template.name, self.vm_template.vm_type, self.cores,
+ self.memory, self.ssd_size
+ )
)
@@ -483,7 +113,7 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
stripe_charge_id = models.CharField(max_length=100, null=True)
price = models.FloatField()
subscription_id = models.CharField(max_length=100, null=True)
- # vm_pricing = models.ForeignKey(VMPricing)
+ vm_pricing = models.ForeignKey(VMPricing, on_delete=models.CASCADE)
order_detail = models.ForeignKey(
OrderDetail, null=True, blank=True, default=None,
on_delete=models.SET_NULL
@@ -495,11 +125,11 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
generic_payment_description = models.CharField(
max_length=500, null=True
)
- permissions = ('u_view_hostingorder',)
+ permissions = ('pr_view_hostingorder',)
class Meta:
permissions = (
- ('u_view_hostingorder', 'View Hosting Order'),
+ ('pr_view_hostingorder', 'View Hosting Order'),
)
def __str__(self):
@@ -597,74 +227,354 @@ class UserHostingKey(models.Model):
# self.save(update_fields=['public_key'])
return private_key, public_key
- def delete(self, *args, **kwargs):
+ def delete(self,*args,**kwargs):
if bool(self.private_key) and os.path.isfile(self.private_key.path):
logger.debug("Removing private key {}".format(self.private_key.path))
os.remove(self.private_key.path)
else:
logger.debug("No private_key to remove")
- super(UserHostingKey, self).delete(*args, **kwargs)
+ super(UserHostingKey, self).delete(*args,**kwargs)
-def get_anonymous_user_instance(CustomUser):
- return CustomUser(email='anonymous@ungleich.ch')
+class HostingBill(AssignPermissionsMixin, models.Model):
+ customer = models.ForeignKey(StripeCustomer, on_delete=models.CASCADE)
+ billing_address = models.ForeignKey(BillingAddress, on_delete=models.CASCADE)
+ total_price = models.FloatField(default=0.0)
+
+ permissions = ('pr_view_hostingbill',)
+
+ class Meta:
+ permissions = (
+ ('pr_view_hostingbill', 'View Hosting Bill'),
+ )
+
+ def __str__(self):
+ return "%s" % (self.customer.user.email)
+
+ @classmethod
+ def create(cls, customer=None, billing_address=None):
+ instance = cls.objects.create(customer=customer,
+ billing_address=billing_address)
+ return instance
-class VATRates(AssignPermissionsMixin, models.Model):
- start_date = models.DateField(blank=True, null=True)
- stop_date = models.DateField(blank=True, null=True)
- territory_codes = models.TextField(blank=True, default='')
- currency_code = models.CharField(max_length=10)
- rate = models.FloatField()
- rate_type = models.TextField(blank=True, default='')
- description = models.TextField(blank=True, default='')
+class MonthlyHostingBill(AssignPermissionsMixin, models.Model):
+ """
+ Corresponds to Invoice object of Stripe
+ """
+ customer = models.ForeignKey(StripeCustomer, on_delete=models.CASCADE)
+ order = models.ForeignKey(HostingOrder, on_delete=models.CASCADE)
+ created = models.DateTimeField(help_text="When the invoice was created")
+ receipt_number = models.CharField(
+ help_text="The receipt number that is generated on Stripe",
+ max_length=100
+ )
+ invoice_number = models.CharField(
+ help_text="The invoice number that is generated on Stripe",
+ max_length=100
+ )
+ paid_at = models.DateTimeField(help_text="Date on which the bill was paid")
+ period_start = models.DateTimeField()
+ period_end = models.DateTimeField()
+ billing_reason = models.CharField(max_length=25)
+ discount = models.PositiveIntegerField()
+ total = models.IntegerField()
+ lines_data_count = models.IntegerField()
+ invoice_id = models.CharField(unique=True, max_length=100)
+ lines_meta_data_csv = models.TextField(default="")
+ subscription_ids_csv = models.TextField(default="")
+
+ permissions = ('pr_view_monthlyhostingbill',)
+
+ class Meta:
+ permissions = (
+ ('pr_view_monthlyhostingbill', 'View Monthly Hosting'),
+ )
+
+ @classmethod
+ def create(cls, args):
+ # Try to infer the HostingOrder from subscription id or VM_ID
+ if len(args['subscription_ids_csv']) > 0:
+ sub_ids = [sub_id.strip() for sub_id in args['subscription_ids_csv'].split(",")]
+ set_sub_ids = set(sub_ids)
+ if len(set_sub_ids) == 1:
+ # the multiple line items belong to the same subscription
+ sub_id = set_sub_ids.pop()
+ try:
+ args['order'] = HostingOrder.objects.get(
+ subscription_id=sub_id
+ )
+ except HostingOrder.DoesNotExist as dne:
+ logger.error("Hosting order for {} doesn't exist".format(
+ sub_id
+ ))
+ args['order'] = None
+ else:
+ logger.debug(
+ "More than one subscriptions"
+ "for MonthlyHostingBill {}".format(args['invoice_id'])
+ )
+ logger.debug("SUB_IDS={}".format(','.join(sub_ids)))
+ logger.debug("Not importing invoices")
+ return None
+ elif len(args['lines_meta_data_csv']) > 0:
+ vm_ids = [vm_id.strip() for vm_id in args['lines_meta_data_csv'].split(",")]
+ if len(vm_ids) == 1:
+ args['order'] = HostingOrder.objects.get(vm_id=vm_ids[0])
+ else:
+ logger.debug(
+ "More than one VM_ID"
+ "for MonthlyHostingBill {}".format(args['invoice_id'])
+ )
+ logger.debug("VM_IDS={}".format(','.join(vm_ids)))
+ logger.debug("Not importing invoices")
+ return None
+ else:
+ logger.debug("Neither subscription id nor vm_id available")
+ logger.debug("Can't import invoice")
+ return None
+ if args['order'] is None:
+ logger.error(
+ "Order is None for {}".format(args['invoice_id']))
+ return None
+ instance = cls.objects.create(
+ created=datetime.utcfromtimestamp(
+ args['created']).replace(tzinfo=pytz.utc),
+ receipt_number=(
+ args['receipt_number']
+ if args['receipt_number'] is not None else ''
+ ),
+ invoice_number=(
+ args['invoice_number']
+ if args['invoice_number'] is not None else ''
+ ),
+ paid_at=datetime.utcfromtimestamp(
+ args['paid_at']).replace(tzinfo=pytz.utc),
+ period_start=datetime.utcfromtimestamp(
+ args['period_start']).replace(tzinfo=pytz.utc),
+ period_end=datetime.utcfromtimestamp(
+ args['period_end']).replace(tzinfo=pytz.utc),
+ billing_reason=(
+ args['billing_reason']
+ if args['billing_reason'] is not None else ''
+ ),
+ discount=args['discount'],
+ total=args['total'],
+ lines_data_count=args['lines_data_count'],
+ invoice_id=args['invoice_id'],
+ lines_meta_data_csv=args['lines_meta_data_csv'],
+ customer=args['customer'],
+ order=args['order'],
+ subscription_ids_csv=args['subscription_ids_csv'],
+ )
+
+ if 'line_items' in args:
+ line_items = args['line_items']
+ for item in line_items:
+ stripe_plan = None
+ if item.type == "subscription" or item.type == "invoiceitem":
+ # Check stripe plan and prepare it for linking to bill item
+ stripe_plan_id = item.plan.id
+ try:
+ stripe_plan = StripePlan.objects.get(
+ stripe_plan_id=stripe_plan_id
+ )
+ except StripePlan.DoesNotExist as dne:
+ logger.error(
+ "StripePlan %s doesn't exist" % stripe_plan_id
+ )
+ if stripe_plan_id is not None:
+ # Create Stripe Plan because we don't have it
+ stripe_plan = StripePlan.objects.create(
+ stripe_plan_id=stripe_plan_id,
+ stripe_plan_name=item.plan.name,
+ amount=item.plan.amount,
+ interval=item.plan.interval
+ )
+ logger.debug("Creatd StripePlan " + stripe_plan_id)
+ line_item_instance = HostingBillLineItem.objects.create(
+ monthly_hosting_bill=instance,
+ amount=item.amount,
+ # description seems to be set to null in the Stripe
+ # response for an invoice
+ description="" if item.description is None else item.description,
+ discountable=item.discountable,
+ metadata=json.dumps(item.metadata),
+ period_start=datetime.utcfromtimestamp(item.period.start).replace(tzinfo=pytz.utc), period_end=datetime.utcfromtimestamp(item.period.end).replace(tzinfo=pytz.utc),
+ proration=item.proration,
+ quantity=item.quantity,
+ # Strange that line item does not have unit_amount but api
+ # states that it is present
+ # https://stripe.com/docs/api/invoiceitems/object#invoiceitem_object-unit_amount
+ # So, for the time being I set the unit_amount to 0 if not
+ # found in the line item
+ unit_amount=item.unit_amount if hasattr(item, "unit_amount") else 0,
+ stripe_plan=stripe_plan
+ )
+ line_item_instance.assign_permissions(instance.customer.user)
+ instance.assign_permissions(instance.customer.user)
+ return instance
+
+ def total_in_chf(self):
+ """
+ Returns amount in chf. The total amount in this model is in cents.
+ Hence we multiply it by 0.01 to obtain the result
+
+ :return:
+ """
+ return self.total * 0.01
+
+ def discount_in_chf(self):
+ """
+ Returns discount in chf.
+
+ :return:
+ """
+ return self.discount * 0.01
+
+ def get_vm_id(self):
+ """
+ Returns the VM_ID metadata if set in this MHB else returns None
+ :return:
+ """
+ return_value = None
+ if len(self.lines_meta_data_csv) > 0:
+ vm_ids = [vm_id.strip() for vm_id in
+ self.lines_meta_data_csv.split(",")]
+ unique_vm_ids=set(vm_ids)
+ unique_vm_ids.discard("")
+ if len(unique_vm_ids) == 1:
+ vm_id = unique_vm_ids.pop()
+ logger.debug("Getting invoice for {}".format(vm_id))
+ return vm_id
+ else:
+ logger.debug(
+ "More than one VM_ID"
+ "for MonthlyHostingBill {}".format(self.invoice_id)
+ )
+ logger.debug("VM_IDS={}".format(unique_vm_ids))
+ return return_value
+
+ def get_period_start(self):
+ """
+ Return the period start of the invoice for the line items
+ :return:
+ """
+ items = HostingBillLineItem.objects.filter(monthly_hosting_bill=self)
+ if len(items) > 0:
+ return items[0].period_start
+ else:
+ return self.period_start
+
+ def get_period_end(self):
+ """
+ Return the period end of the invoice for the line items
+ :return:
+ """
+ items = HostingBillLineItem.objects.filter(monthly_hosting_bill=self)
+ if len(items) > 0:
+ return items[0].period_end
+ else:
+ return self.period_end
-class StripeTaxRate(AssignPermissionsMixin, models.Model):
- tax_rate_id = models.CharField(max_length=100, unique=True)
- jurisdiction = models.CharField(max_length=10)
- inclusive = models.BooleanField(default=False)
- display_name = models.CharField(max_length=100)
- percentage = models.FloatField(default=0)
- description = models.CharField(max_length=100)
+class HostingBillLineItem(AssignPermissionsMixin, models.Model):
+ """
+ Corresponds to InvoiceItem object of Stripe
+ """
+ monthly_hosting_bill = models.ForeignKey(MonthlyHostingBill,
+ on_delete=models.CASCADE)
+ stripe_plan = models.ForeignKey(StripePlan, null=True,
+ on_delete=models.CASCADE)
+ amount = models.IntegerField()
+ description = models.CharField(max_length=255)
+ discountable = models.BooleanField()
+ metadata = models.CharField(max_length=128)
+ period_start = models.DateTimeField()
+ period_end = models.DateTimeField()
+ proration = models.BooleanField()
+ quantity = models.PositiveIntegerField()
+ unit_amount = models.PositiveIntegerField()
+ permissions = ('pr_view_hostingbilllineitem',)
+
+ class Meta:
+ permissions = (
+ ('pr_view_hostingbilllineitem', 'View Monthly Hosting Bill Line Item'),
+ )
+
+ def amount_in_chf(self):
+ """
+ Returns amount in chf. The amount in this model is in cents (as in
+ Stripe). Hence we multiply it by 0.01 to obtain the result
+
+ :return:
+ """
+ return self.amount * 0.01
+
+ def unit_amount_in_chf(self):
+ """
+ Returns unit amount in chf. If its 0, we obtain it from amount and
+ quantity.
+
+ :return:
+ """
+ if self.unit_amount == 0:
+ return round((self.amount / self.quantity) * 0.01, 2)
+ else:
+ return self.unit_amount * 0.01
+
+ def get_item_detail_str(self):
+ """
+ Returns line item html string representation
+ :return:
+ """
+ item_detail = ""
+ # metadata is a dict; a dict with nothing has two chars at least {}
+ if self.metadata is not None and len(self.metadata) > 2:
+ try:
+ vm_dict = json.loads(self.metadata)
+ item_detail = "VM ID: {} ".format(vm_dict["VM_ID"])
+ except ValueError as ve:
+ logger.error(
+ "Could not parse VM in metadata {}. Detail {}".format(
+ self.metadata, str(ve)
+ )
+ )
+ vm_conf = StripeUtils.get_vm_config_from_stripe_id(
+ self.stripe_plan.stripe_plan_id
+ )
+ if vm_conf is not None:
+ item_detail += ("Cores : {}RAM : {} GB "
+ "SSD : {} GB ").format(
+ vm_conf['cores'], int(float(vm_conf['ram'])),
+ vm_conf['ssd']
+ )
+ return item_detail
-class IncompletePaymentIntents(AssignPermissionsMixin, models.Model):
- completed_at = models.DateTimeField(null=True)
+class VMDetail(models.Model):
+ user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
+ vm_id = models.IntegerField(default=0)
+ disk_size = models.FloatField(default=0.0)
+ cores = models.FloatField(default=0.0)
+ memory = models.FloatField(default=0.0)
+ configuration = models.CharField(default='', max_length=128)
+ ipv4 = models.TextField(default='')
+ ipv6 = models.TextField(default='')
created_at = models.DateTimeField(auto_now_add=True)
- payment_intent_id = models.CharField(max_length=100)
- request = models.TextField()
- stripe_api_cus_id = models.CharField(max_length=30)
- card_details_response = models.TextField()
- stripe_subscription_id = models.CharField(max_length=100, null=True)
- stripe_charge_id = models.CharField(max_length=100, null=True)
- gp_details = models.TextField()
- billing_address_data = models.TextField()
+ terminated_at = models.DateTimeField(null=True)
-
-class IncompleteSubscriptions(AssignPermissionsMixin, models.Model):
- created_at = models.DateTimeField(auto_now_add=True)
- completed_at = models.DateTimeField(null=True)
- subscription_id = models.CharField(max_length=100)
- subscription_status = models.CharField(max_length=30)
- name = models.CharField(max_length=50)
- email = models.EmailField()
- request = models.TextField()
- stripe_api_cus_id = models.CharField(max_length=30)
- card_details_response = models.TextField()
- stripe_subscription_obj = models.TextField()
- stripe_onetime_charge = models.TextField()
- gp_details = models.TextField()
- specs = models.TextField()
- vm_template_id = models.PositiveIntegerField(default=0)
- template = models.TextField()
- billing_address_data = models.TextField()
+ def end_date(self):
+ end_date = self.terminated_at if self.terminated_at else timezone.now()
+ months = relativedelta(end_date, self.created_at).months or 1
+ end_date = self.created_at + relativedelta(months=months, days=-1)
+ return end_date
class UserCardDetail(AssignPermissionsMixin, models.Model):
- permissions = ('view_usercarddetail',)
- stripe_customer = models.ForeignKey(StripeCustomer)
+ permissions = ('pr_view_usercarddetail',)
+ stripe_customer = models.ForeignKey(StripeCustomer, on_delete=models.CASCADE)
last4 = models.CharField(max_length=4)
brand = models.CharField(max_length=128)
card_id = models.CharField(max_length=100, blank=True, default='')
@@ -675,7 +585,7 @@ class UserCardDetail(AssignPermissionsMixin, models.Model):
class Meta:
permissions = (
- ('view_usercarddetail', 'View User Card'),
+ ('pr_view_usercarddetail', 'View User Card'),
)
@classmethod
@@ -821,68 +731,52 @@ class UserCardDetail(AssignPermissionsMixin, models.Model):
return None
-class VMPricing(models.Model):
- name = models.CharField(max_length=255, unique=True)
- vat_inclusive = models.BooleanField(default=True)
- vat_percentage = models.DecimalField(
- max_digits=7, decimal_places=5, blank=True, default=0
- )
- cores_unit_price = models.DecimalField(
- max_digits=7, decimal_places=5, default=0
- )
- ram_unit_price = models.DecimalField(
- max_digits=7, decimal_places=5, default=0
- )
- ssd_unit_price = models.DecimalField(
- max_digits=7, decimal_places=5, default=0
- )
- hdd_unit_price = models.DecimalField(
- max_digits=7, decimal_places=6, default=0
- )
- discount_name = models.CharField(max_length=255, null=True, blank=True)
- discount_amount = models.DecimalField(
- max_digits=6, decimal_places=2, default=0
- )
- stripe_coupon_id = models.CharField(max_length=255, null=True, blank=True)
+class VATRates(AssignPermissionsMixin, models.Model):
+ start_date = models.DateField(blank=True, null=True)
+ stop_date = models.DateField(blank=True, null=True)
+ territory_codes = models.TextField(blank=True, default='')
+ currency_code = models.CharField(max_length=10)
+ rate = models.FloatField()
+ rate_type = models.TextField(blank=True, default='')
+ description = models.TextField(blank=True, default='')
- def __str__(self):
- display_str = self.name + ' => ' + ' - '.join([
- '{}/Core'.format(self.cores_unit_price.normalize()),
- '{}/GB RAM'.format(self.ram_unit_price.normalize()),
- '{}/GB SSD'.format(self.ssd_unit_price.normalize()),
- '{}/GB HDD'.format(self.hdd_unit_price.normalize()),
- '{}% VAT'.format(self.vat_percentage.normalize())
- if not self.vat_inclusive else 'VAT-Incl',
- ])
- if self.discount_amount:
- display_str = ' - '.join([
- display_str,
- '{} {}'.format(
- self.discount_amount,
- self.discount_name if self.discount_name else 'Discount'
- )
- ])
- return display_str
- @classmethod
- def get_vm_pricing_by_name(cls, name):
- try:
- pricing = VMPricing.objects.get(name=name)
- except Exception as e:
- logger.error(
- "Error getting VMPricing with name {name}. "
- "Details: {details}. Attempting to return default"
- "pricing.".format(name=name, details=str(e))
- )
- pricing = VMPricing.get_default_pricing()
- return pricing
+class StripeTaxRate(AssignPermissionsMixin, models.Model):
+ tax_rate_id = models.CharField(max_length=100, unique=True)
+ jurisdiction = models.CharField(max_length=10)
+ inclusive = models.BooleanField(default=False)
+ display_name = models.CharField(max_length=100)
+ percentage = models.FloatField(default=0)
+ description = models.CharField(max_length=100)
- @classmethod
- def get_default_pricing(cls):
- """ Returns the default pricing or None """
- try:
- default_pricing = VMPricing.objects.get(name='default')
- except Exception as e:
- logger.error(str(e))
- default_pricing = None
- return default_pricing
+
+class IncompletePaymentIntents(AssignPermissionsMixin, models.Model):
+ completed_at = models.DateTimeField(null=True)
+ created_at = models.DateTimeField(auto_now_add=True)
+ payment_intent_id = models.CharField(max_length=100)
+ request = models.TextField()
+ stripe_api_cus_id = models.CharField(max_length=30)
+ card_details_response = models.TextField()
+ stripe_subscription_id = models.CharField(max_length=100, null=True)
+ stripe_charge_id = models.CharField(max_length=100, null=True)
+ gp_details = models.TextField()
+ billing_address_data = models.TextField()
+
+
+class IncompleteSubscriptions(AssignPermissionsMixin, models.Model):
+ created_at = models.DateTimeField(auto_now_add=True)
+ completed_at = models.DateTimeField(null=True)
+ subscription_id = models.CharField(max_length=100)
+ subscription_status = models.CharField(max_length=30)
+ name = models.CharField(max_length=50)
+ email = models.EmailField()
+ request = models.TextField()
+ stripe_api_cus_id = models.CharField(max_length=30)
+ card_details_response = models.TextField()
+ stripe_subscription_obj = models.TextField()
+ stripe_onetime_charge = models.TextField()
+ gp_details = models.TextField()
+ specs = models.TextField()
+ vm_template_id = models.PositiveIntegerField(default=0)
+ template = models.TextField()
+ billing_address_data = models.TextField()
\ No newline at end of file
diff --git a/hosting/requirements.txt b/hosting/requirements.txt
deleted file mode 100644
index 4c397ae..0000000
--- a/hosting/requirements.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-asgiref==3.7.2
-certifi==2023.11.17
-charset-normalizer==3.3.2
-Django==4.2.7
-idna==3.4
-ldap3==2.9.1
-pyasn1==0.5.1
-pycryptodome==3.19.0
-python-dotenv==1.0.0
-requests==2.31.0
-sqlparse==0.4.4
-stripe==7.5.0
-typing_extensions==4.8.0
-urllib3==2.1.0
diff --git a/hosting/templates/hosting/base_short.html b/hosting/templates/hosting/base_short.html
index 693274c..8022f87 100755
--- a/hosting/templates/hosting/base_short.html
+++ b/hosting/templates/hosting/base_short.html
@@ -1,4 +1,4 @@
-{% load static i18n %}
+{% load static i18n cms_tags sekizai_tags %}
@@ -14,7 +14,7 @@
ungleich
-
+
@@ -29,14 +29,14 @@
{% block css_extra %}
{% endblock css_extra %}
-{# {% render_block "css" postprocessor "compressor.contrib.sekizai.compress" %}#}
-{# {% render_block "js" postprocessor "compressor.contrib.sekizai.compress" %}#}
+ {% render_block "css" postprocessor "compressor.contrib.sekizai.compress" %}
+ {% render_block "js" postprocessor "compressor.contrib.sekizai.compress" %}
-
+
-
+
@@ -52,7 +52,7 @@
{% include "gdpr_banner.html" %}
-{# {% cms_toolbar %}#}
+ {% cms_toolbar %}
{% block navbar %}
{% include "hosting/includes/_navbar_user.html" %}
@@ -72,17 +72,17 @@
{% else %}
{% endif %}
-
+
-
+
diff --git a/hosting/templates/hosting/create_virtual_machine.html b/hosting/templates/hosting/create_virtual_machine.html
index 5c4bc3c..c2266c0 100755
--- a/hosting/templates/hosting/create_virtual_machine.html
+++ b/hosting/templates/hosting/create_virtual_machine.html
@@ -1,5 +1,5 @@
{% extends "hosting/base_short.html" %}
-{% load staticfiles bootstrap3 i18n cms_tags %}
+{% load static bootstrap3 i18n cms_tags %}
{% block content %}
diff --git a/hosting/templates/hosting/dashboard.html b/hosting/templates/hosting/dashboard.html
index bacdbd5..ebec43d 100755
--- a/hosting/templates/hosting/dashboard.html
+++ b/hosting/templates/hosting/dashboard.html
@@ -11,31 +11,31 @@
{% trans "Welcome" %} {{request.user.name}}
-
+
{% trans "Create VM" %}
-
+
{% trans "My VMs" %}
-
+
{% trans "My SSH Keys" %}
-
+
{% trans "My Bills" %}
-
+
{% trans "My Settings" %}
diff --git a/hosting/templates/hosting/emails/vm_charged.html b/hosting/templates/hosting/emails/vm_charged.html
index 5efa2a3..e11f6ce 100755
--- a/hosting/templates/hosting/emails/vm_charged.html
+++ b/hosting/templates/hosting/emails/vm_charged.html
@@ -1,4 +1,4 @@
-{% load static %}
+{% load static from static %}
diff --git a/hosting/templates/hosting/includes/_navbar_transparent.html b/hosting/templates/hosting/includes/_navbar_transparent.html
index 8098497..8a97ae1 100755
--- a/hosting/templates/hosting/includes/_navbar_transparent.html
+++ b/hosting/templates/hosting/includes/_navbar_transparent.html
@@ -5,7 +5,7 @@
diff --git a/hosting/templates/hosting/includes/_navbar_user.html b/hosting/templates/hosting/includes/_navbar_user.html
index 1a69fc2..644543f 100755
--- a/hosting/templates/hosting/includes/_navbar_user.html
+++ b/hosting/templates/hosting/includes/_navbar_user.html
@@ -13,7 +13,7 @@
{% endif %}
-
+
{% if request.user.is_authenticated %}
diff --git a/hosting/templates/hosting/login.html b/hosting/templates/hosting/login.html
index 0645a3b..4c9aa1f 100755
--- a/hosting/templates/hosting/login.html
+++ b/hosting/templates/hosting/login.html
@@ -1,5 +1,5 @@
{% extends "hosting/base_short.html" %}
-{% load i18n static bootstrap3 %}
+{% load i18n static bootstrap3%}
{% block navbar %}
{% include 'hosting/includes/_navbar_transparent.html' %}
diff --git a/hosting/templatetags/custom_tags.py b/hosting/templatetags/custom_tags.py
deleted file mode 100644
index 93fd171..0000000
--- a/hosting/templatetags/custom_tags.py
+++ /dev/null
@@ -1,27 +0,0 @@
-
-import logging
-
-from django import template
-from django.urls import resolve, reverse
-from django.utils.translation import activate, get_language
-
-logger = logging.getLogger(__name__)
-
-register = template.Library()
-
-
-@register.simple_tag(takes_context=True)
-def change_lang(context, lang=None, *args, **kwargs):
-
- path = context['request'].path
- url_parts = resolve(path)
-
- url = path
- cur_language = get_language()
- try:
- activate(lang)
- url = reverse(url_parts.view_name, kwargs=url_parts.kwargs)
- finally:
- activate(cur_language)
-
- return "%s" % url
diff --git a/hosting/urls.py b/hosting/urls.py
old mode 100644
new mode 100755
index fd9eac6..fa1e006
--- a/hosting/urls.py
+++ b/hosting/urls.py
@@ -1,40 +1,75 @@
from django.urls import re_path
-from django.contrib.auth import views as auth_views
-from .views import SSHKeyCreateView, AskSSHKeyView, PaymentOrderView, OrderConfirmationView
+from utils.views import SSHKeyCreateView, AskSSHKeyView
from .views import (
- #PaymentVMView,
+ DjangoHostingView, RailsHostingView, PaymentVMView, NodeJSHostingView,
LoginView, SignupView, SignupValidateView, SignupValidatedView, IndexView,
- #OrdersHostingListView, OrdersHostingDetailView,
- #VirtualMachinesPlanListView, VirtualMachineView, OrdersHostingDeleteView,
- #MarkAsReadNotificationView,
+ # NotificationsView, MarkAsReadNotificationView,
+ OrdersHostingListView, OrdersHostingDetailView,
+ VirtualMachinesPlanListView, VirtualMachineView, OrdersHostingDeleteView,
PasswordResetView, PasswordResetConfirmView,
- #HostingPricingView, CreateVirtualMachinesView, HostingBillListView,
- #HostingBillDetailView, SSHKeyDeleteView, SSHKeyListView,
- #SSHKeyChoiceView, DashboardView, SettingsView,
- ResendActivationEmailView, DashboardView, CustomLogoutView
- #InvoiceListView, InvoiceDetailView, CheckUserVM
+ HostingPricingView, CreateVirtualMachinesView, HostingBillListView,
+ HostingBillDetailView, SSHKeyDeleteView, SSHKeyListView,
+ SSHKeyChoiceView, DashboardView, SettingsView, ResendActivationEmailView,
+ InvoiceListView, InvoiceDetailView, CustomLogoutView
)
-
app_name = 'hosting'
-
urlpatterns = [
- #re_path(r'/', IndexView.as_view(), name='index'),
+ re_path(r'index/?$', IndexView.as_view(), name='index'),
+ re_path(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'),
+ # re_path(r'checkvm/?$', CheckUserVM.as_view(), name='check_vm'),
+ re_path(r'dashboard/?$', DashboardView.as_view(), name='dashboard'),
+ re_path(r'nodejs/?$', NodeJSHostingView.as_view(), name='nodejshosting'),
+ re_path(r'rails/?$', RailsHostingView.as_view(), name='railshosting'),
+ re_path(r'pricing/?$', HostingPricingView.as_view(), name='pricing'),
+ re_path(r'payment/?$', PaymentVMView.as_view(), name='payment'),
+ re_path(r'settings/?$', SettingsView.as_view(), name='settings'),
+ re_path(r'orders/?$', OrdersHostingListView.as_view(), name='orders'),
+ re_path(r'invoices/?$', InvoiceListView.as_view(), name='invoices'),
+ re_path(r'order-confirmation/?$', OrdersHostingDetailView.as_view(),
+ name='order-confirmation'),
+ re_path(r'^add-ssh-key/?$', AskSSHKeyView.as_view(),
+ name='add_ssh_key'),
+ re_path(r'orders/(?P\d+)/?$', OrdersHostingDetailView.as_view(),
+ name='orders'),
+ re_path(r'invoice/(?P[-\w]+)/?$', InvoiceDetailView.as_view(),
+ name='invoices'),
+ re_path(r'bills/?$', HostingBillListView.as_view(), name='bills'),
+ re_path(r'bills/(?P\d+)/?$', HostingBillDetailView.as_view(),
+ name='bills'),
+ re_path(r'cancel_order/(?P\d+)/?$',
+ OrdersHostingDeleteView.as_view(), name='delete_order'),
+ re_path(r'create_virtual_machine/?$', CreateVirtualMachinesView.as_view(),
+ name='create_virtual_machine'),
+ re_path(r'my-virtual-machines/?$',
+ VirtualMachinesPlanListView.as_view(), name='virtual_machines'),
+ re_path(r'my-virtual-machines/(?P\d+)/?$', VirtualMachineView.as_view(),
+ name='virtual_machines'),
+ re_path(r'ssh_keys/?$', SSHKeyListView.as_view(),
+ name='ssh_keys'),
+ re_path(r'ssh_keys_choice/?$', SSHKeyChoiceView.as_view(),
+ name='choice_ssh_keys'),
+ re_path(r'delete_ssh_key/(?P\d+)/?$', SSHKeyDeleteView.as_view(),
+ name='delete_ssh_key'),
+ re_path(r'delete_card/(?P[\w\-]+)/$', SettingsView.as_view(),
+ name='delete_card'),
+ re_path(r'create_ssh_key/?$', SSHKeyCreateView.as_view(),
+ name='create_ssh_key'),
+ # re_path(r'^notifications/$', NotificationsView.as_view(),
+ # name='notifications'),
+ # re_path(r'^notifications/(?P\d+)/?$', MarkAsReadNotificationView.as_view(),
+ # name='read_notification'),
re_path(r'login/?$', LoginView.as_view(), name='login'),
re_path(r'signup/?$', SignupView.as_view(), name='signup'),
re_path(r'signup-validate/?$', SignupValidateView.as_view(),
- name='signup-validate'),
+ name='signup-validate'),
re_path(r'resend-activation-link/?$', ResendActivationEmailView.as_view(),
- name='resend_activation_link'),
+ name='resend_activation_link'),
re_path(r'reset-password/?$', PasswordResetView.as_view(),
- name='reset_password'),
+ name='reset_password'),
re_path(r'reset-password-confirm/(?P[0-9A-Za-z]+)-(?P.+)/$',
PasswordResetConfirmView.as_view(), name='reset_password_confirm'),
- re_path('^logout/', CustomLogoutView.as_view(), name='logout'),
+ re_path(r'^logout/?$', CustomLogoutView.as_view(), name='logout'),
re_path(r'^validate/(?P.*)/$',
- SignupValidatedView.as_view(), name='validate'),
- re_path(r'dashboard/?$', DashboardView.as_view(), name='dashboard'),
- re_path(r'^payment/?$', PaymentOrderView.as_view(), name='payment'),
- re_path(r'^order-confirmation/?$', OrderConfirmationView.as_view(),
- name='order_confirmation'),
-]
\ No newline at end of file
+ SignupValidatedView.as_view(), name='validate')
+]
diff --git a/hosting/views.py b/hosting/views.py
old mode 100644
new mode 100755
index 4d46464..c457535
--- a/hosting/views.py
+++ b/hosting/views.py
@@ -1,51 +1,266 @@
-import json
-import uuid
import logging
+import uuid
+from datetime import datetime
+from urllib.parse import quote
+from time import sleep
import stripe
+from django import forms
from django.conf import settings
-from django.contrib.auth import authenticate, login
-from django.contrib.auth.tokens import default_token_generator
+from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
+from django.contrib.auth.tokens import default_token_generator
from django.contrib.auth.views import LogoutView
+from django.core.exceptions import ValidationError
from django.core.files.base import ContentFile
-from django.http import HttpResponseRedirect, Http404, JsonResponse
+from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.urls import reverse_lazy, reverse
+from django.db.models import Q
+from django.http import (
+ Http404, HttpResponseRedirect, HttpResponse, JsonResponse
+)
+from django.shortcuts import redirect, render
from django.utils.decorators import method_decorator
+from django.utils.html import escape
+
from django.utils.http import urlsafe_base64_decode
from django.utils.safestring import mark_safe
-from django.views import View
-from django.views.generic import CreateView, TemplateView, FormView, DetailView
-from django.utils.translation import gettext_lazy as _, get_language
+from django.utils.translation import get_language, gettext_lazy as _
from django.views.decorators.cache import never_cache, cache_control
-from django.contrib import messages
-from django.shortcuts import render
+from django.views.generic import (
+ View, CreateView, FormView, ListView, DetailView, DeleteView,
+ TemplateView, UpdateView
+)
+from guardian.mixins import PermissionRequiredMixin
+from oca.pool import WrongIdError
+# from rest_framework.renderers import JSONRenderer
+# from rest_framework.response import Response
+# from rest_framework.views import APIView
+# from stored_messages.api import mark_read
+# from stored_messages.models import Message
+# from stored_messages.settings import stored_messages_settings
-from dynamicweb2.ldap_manager import LdapManager
-from dynamicweb2.stripe_utils import StripeUtils
-from hosting.forms import HostingUserLoginForm, HostingUserSignupForm, ResendActivationEmailForm, \
- PasswordResetRequestForm, UserHostingKeyForm, BillingAddressForm, BillingAddressFormSignup, ProductPaymentForm, \
- GenericPaymentForm
-from hosting.mailer import BaseEmail
-from hosting.mixins import LoginViewMixin, ResendActivationLinkViewMixin, PasswordResetViewMixin, \
- PasswordResetConfirmViewMixin
-from hosting.models import CustomUser, UserHostingKey, GenericProduct, StripeCustomer, HostingOrder, UserCardDetail, \
- BillingAddress, IncompletePaymentIntents, StripeTaxRate, IncompleteSubscriptions
-from hosting.utils import get_vat_rate_for_country, validate_vat_number, get_vm_price_for_given_vat, \
- get_all_public_keys, create_incomplete_intent_request, get_error_response_dict, show_error
-
-decorators = [never_cache]
+from datacenterlight.cms_models import DCLCalculatorPluginModel
+from datacenterlight.models import VMTemplate, VMPricing
+from datacenterlight.utils import (
+ create_vm, get_cms_integration, validate_vat_number
+)
+from hosting.models import UserCardDetail, StripeTaxRate
+from membership.models import CustomUser, StripeCustomer
+from opennebula_api.opennebula_manager import OpenNebulaManager
+from opennebula_api.serializers import (
+ VirtualMachineSerializer, VirtualMachineTemplateSerializer,
+ VMTemplateSerializer
+)
+from utils.forms import (
+ BillingAddressForm, PasswordResetRequestForm, UserBillingAddressForm,
+ ResendActivationEmailForm
+)
+from utils.hosting_utils import get_all_public_keys
+from utils.hosting_utils import (
+ get_vm_price_with_vat, get_vm_price_for_given_vat, HostingUtils,
+ get_vat_rate_for_country
+)
+from utils.ldap_manager import LdapManager
+from utils.mailer import BaseEmail
+from utils.stripe_utils import StripeUtils
+from utils.tasks import send_plain_email_task
+from utils.views import (
+ PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin,
+ ResendActivationLinkViewMixin
+)
+from .forms import (
+ HostingUserSignupForm, HostingUserLoginForm, UserHostingKeyForm,
+ generate_ssh_key_name
+)
+from .mixins import ProcessVMSelectionMixin, HostingContextMixin
+from .models import (
+ HostingOrder, HostingBill, HostingPlan, UserHostingKey, VMDetail,
+ GenericProduct, MonthlyHostingBill
+)
logger = logging.getLogger(__name__)
-class LoginView(LoginViewMixin):
+CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a \
+ backend connection error. please try again in a few \
+ minutes."
+
+
+decorators = [never_cache]
+
+
+class DashboardView(LoginRequiredMixin, View):
+ template_name = "hosting/dashboard.html"
+ login_url = reverse_lazy('hosting:login')
+
+ def get_context_data(self, **kwargs):
+ context = {}
+ return context
+
+ @method_decorator(decorators)
+ def get(self, request, *args, **kwargs):
+ context = self.get_context_data()
+ context['has_invoices'] = False
+ try:
+ bills = []
+ if hasattr(self.request.user, 'stripecustomer'):
+ bills = MonthlyHostingBill.objects.filter(
+ customer=self.request.user.stripecustomer
+ )
+ if len(bills) > 0:
+ context['has_invoices'] = True
+ except MonthlyHostingBill.DoesNotExist as dne:
+ logger.error("{}'s monthly hosting bill not imported ?".format(
+ self.request.user.email
+ ))
+ return render(request, self.template_name, context)
+
+
+class DjangoHostingView(ProcessVMSelectionMixin, View):
+ template_name = "hosting/django.html"
+
+ def get_context_data(self, **kwargs):
+ HOSTING = 'django'
+ templates = OpenNebulaManager().get_templates()
+ data = VirtualMachineTemplateSerializer(templates, many=True).data
+ configuration_options = HostingPlan.get_serialized_configs()
+ context = {
+ 'hosting': HOSTING,
+ 'hosting_long': "Django",
+ # 'configuration_detail': configuration_detail,
+ 'domain': "django-hosting.ch",
+ 'google_analytics': "UA-62285904-6",
+ 'vm_types': data,
+ 'email': "info@django-hosting.ch",
+ 'configuration_options': configuration_options,
+ 'templates': templates,
+ }
+
+ return context
+
+ def get(self, request, *args, **kwargs):
+ request.session['hosting_url'] = reverse('hosting:djangohosting')
+ context = self.get_context_data()
+
+ return render(request, self.template_name, context)
+
+
+class RailsHostingView(ProcessVMSelectionMixin, View):
+ template_name = "hosting/rails.html"
+
+ def get_context_data(self, **kwargs):
+ HOSTING = 'rails'
+
+ templates = OpenNebulaManager().get_templates()
+ configuration_options = HostingPlan.get_serialized_configs()
+
+ context = {
+ 'hosting': HOSTING,
+ 'hosting_long': "Ruby On Rails",
+ 'domain': "rails-hosting.ch",
+ 'google_analytics': "UA-62285904-5",
+ 'email': "info@rails-hosting.ch",
+ 'configuration_options': configuration_options,
+ 'templates': templates,
+ }
+ return context
+
+ def get(self, request, *args, **kwargs):
+ request.session['hosting_url'] = reverse('hosting:railshosting')
+ context = self.get_context_data()
+ return render(request, self.template_name, context)
+
+
+class NodeJSHostingView(ProcessVMSelectionMixin, View):
+ template_name = "hosting/nodejs.html"
+
+ def get_context_data(self, **kwargs):
+ HOSTING = 'nodejs'
+ templates = OpenNebulaManager().get_templates()
+ configuration_options = HostingPlan.get_serialized_configs()
+
+ context = {
+ 'hosting': HOSTING,
+ 'hosting_long': "NodeJS",
+ # 'configuration_detail': configuration_detail,
+ 'domain': "node-hosting.ch",
+ 'google_analytics': "UA-62285904-7",
+ 'email': "info@node-hosting.ch",
+ 'templates': templates,
+ 'configuration_options': configuration_options,
+
+ }
+ return context
+
+ def get(self, request, *args, **kwargs):
+ request.session['hosting_url'] = reverse('hosting:nodejshosting')
+ context = self.get_context_data()
+
+ return render(request, self.template_name, context)
+
+
+class HostingPricingView(ProcessVMSelectionMixin, View):
+ template_name = "hosting/hosting_pricing.html"
+
+ def get_context_data(self, **kwargs):
+ # configuration_options = dict(VirtualMachinePlan.VM_CONFIGURATION)
+ templates = OpenNebulaManager().get_templates()
+ configuration_options = HostingPlan.get_serialized_configs()
+
+ context = {
+ # 'configuration_options': configuration_options,
+ 'email': "info@django-hosting.ch",
+ 'templates': templates,
+ 'configuration_options': configuration_options,
+
+ }
+
+ return context
+
+ def get(self, request, *args, **kwargs):
+ request.session['hosting_url'] = reverse('hosting:djangohosting')
+ context = self.get_context_data()
+
+ return render(request, self.template_name, context)
+
+
+class IndexView(View):
+ template_name = "hosting/index.html"
+
+ def get_context_data(self, **kwargs):
+ templates = OpenNebulaManager().get_templates()
+ data = VirtualMachineTemplateSerializer(templates, many=True).data
+
+ context = {
+ 'hosting': "nodejs",
+ 'hosting_long': "NodeJS",
+ 'domain': "node-hosting.ch",
+ 'google_analytics': "UA-62285904-7",
+ 'email': "info@node-hosting.ch",
+ 'vm_types': data
+ # 'vm_types': VirtualMachineType.get_serialized_vm_types(),
+ }
+ return context
+
+ @method_decorator(decorators)
+ def get(self, request, *args, **kwargs):
+ context = self.get_context_data()
+ return render(request, self.template_name, context)
+
+
+class LoginView(HostingContextMixin, LoginViewMixin):
template_name = "hosting/login.html"
form_class = HostingUserLoginForm
success_url = reverse_lazy('hosting:dashboard')
+ @method_decorator(decorators)
+ def get(self, request, *args, **kwargs):
+ context = self.get_context_data()
+ return render(request, self.template_name, context)
-class SignupView(CreateView):
+
+class SignupView(HostingContextMixin, CreateView):
template_name = 'hosting/signup.html'
form_class = HostingUserSignupForm
model = CustomUser
@@ -63,7 +278,7 @@ class SignupView(CreateView):
this_base_url = "{0}://{1}".format(self.request.scheme,
self.request.get_host())
CustomUser.register(name, password, email,
- app='dcl', base_url=this_base_url, send_email=settings.SEND_EMAIL)
+ app='dcl', base_url=this_base_url)
return HttpResponseRedirect(reverse_lazy('hosting:signup-validate'))
@@ -74,7 +289,7 @@ class SignupView(CreateView):
return super(SignupView, self).get(request, *args, **kwargs)
-class SignupValidateView(TemplateView):
+class SignupValidateView(HostingContextMixin, TemplateView):
template_name = "hosting/signup_validate.html"
def get_context_data(self, **kwargs):
@@ -82,7 +297,7 @@ class SignupValidateView(TemplateView):
login_url = '' + str(_('login')) + ' '
home_url = 'Data Center Light '
+ reverse('datacenterlight:index') + '">Data Center Light '
message = '{signup_success_message} {lurl} \
{go_back} {hurl}.'.format(
signup_success_message=_(
@@ -98,7 +313,7 @@ class SignupValidateView(TemplateView):
return context
-class SignupValidatedView(SignupValidateView):
+class SignupValidatedView(SignupValidateView, HostingContextMixin):
template_name = "hosting/signup_validate.html"
def get_context_data(self, **kwargs):
@@ -133,7 +348,7 @@ class SignupValidatedView(SignupValidateView):
email.send()
else:
home_url = '
Data Center Light '
message = '{sorry_message}
{go_back_to} {hurl}'.format(
sorry_message=_("Sorry. Your request is invalid."),
@@ -151,7 +366,8 @@ class SignupValidatedView(SignupValidateView):
return super(SignupValidatedView, self).get(request, *args, **kwargs)
-class ResendActivationEmailView(ResendActivationLinkViewMixin):
+class ResendActivationEmailView(HostingContextMixin,
+ ResendActivationLinkViewMixin):
template_name = 'hosting/resend_activation_link.html'
form_class = ResendActivationEmailForm
success_url = reverse_lazy('hosting:login')
@@ -159,7 +375,7 @@ class ResendActivationEmailView(ResendActivationLinkViewMixin):
email_template_name = 'user_activation'
-class PasswordResetView(PasswordResetViewMixin):
+class PasswordResetView(HostingContextMixin, PasswordResetViewMixin):
site = 'dcl'
template_name = 'hosting/reset_password.html'
form_class = PasswordResetRequestForm
@@ -167,7 +383,8 @@ class PasswordResetView(PasswordResetViewMixin):
template_email_path = 'hosting/emails/'
-class PasswordResetConfirmView(PasswordResetConfirmViewMixin):
+class PasswordResetConfirmView(HostingContextMixin,
+ PasswordResetConfirmViewMixin):
template_name = 'hosting/confirm_reset_password.html'
success_url = reverse_lazy('hosting:login')
@@ -176,10 +393,10 @@ class PasswordResetConfirmView(PasswordResetConfirmViewMixin):
uid = urlsafe_base64_decode(uidb64)
user = CustomUser.objects.get(pk=uid)
- # opennebula_client = OpenNebulaManager(
- # email=user.username,
- # password=user.password,
- # )
+ opennebula_client = OpenNebulaManager(
+ email=user.username,
+ password=user.password,
+ )
except (TypeError, ValueError, OverflowError, CustomUser.DoesNotExist):
user = None
@@ -222,543 +439,587 @@ class PasswordResetConfirmView(PasswordResetConfirmViewMixin):
return self.form_invalid(form)
-class SSHKeyCreateView(FormView):
- form_class = UserHostingKeyForm
- model = UserHostingKey
- template_name = 'hosting/user_key.html'
+# class NotificationsView(LoginRequiredMixin, TemplateView):
+# template_name = 'hosting/notifications.html'
+# login_url = reverse_lazy('hosting:login')
+#
+# def get_context_data(self, **kwargs):
+# context = super(NotificationsView, self).get_context_data(**kwargs)
+# backend = stored_messages_settings.STORAGE_BACKEND()
+# unread_notifications = backend.inbox_list(self.request.user)
+# read_notifications = backend.archive_list(self.request.user)
+# context.update({
+# 'unread_notifications': unread_notifications,
+# 'all_notifications': read_notifications + unread_notifications
+# })
+# return context
+#
+#
+# class MarkAsReadNotificationView(LoginRequiredMixin, UpdateView):
+# model = Message
+# success_url = reverse_lazy('hosting:notifications')
+# login_url = reverse_lazy('hosting:login')
+# fields = '__all__'
+#
+# def post(self, *args, **kwargs):
+# message = self.get_object()
+# backend = stored_messages_settings.STORAGE_BACKEND()
+# backend.archive_store([self.request.user], message)
+# mark_read(self.request.user, message)
+# return HttpResponseRedirect(reverse('hosting:notifications'))
+
+
+class SSHKeyDeleteView(LoginRequiredMixin, DeleteView):
login_url = reverse_lazy('hosting:login')
- context_object_name = "virtual_machine"
success_url = reverse_lazy('hosting:ssh_keys')
+ model = UserHostingKey
- def get_form_kwargs(self):
- kwargs = super(SSHKeyCreateView, self).get_form_kwargs()
- kwargs.update({'request': self.request})
- return kwargs
+ def get_object(self, queryset=None):
+ """ Hook to ensure UserHostingKey object is owned by request.user.
+ We reply with a Http404 if the user is not the owner of the key.
+ """
+ obj = super(SSHKeyDeleteView, self).get_object()
+ if not obj.user == self.request.user:
+ raise Http404
+ return obj
- def form_valid(self, form):
- form.save()
- if settings.DCL_SSH_KEY_NAME_PREFIX in form.instance.name:
- content = ContentFile(form.cleaned_data.get('private_key'))
- filename = form.cleaned_data.get(
- 'name') + '_' + str(uuid.uuid4())[:8] + '_private.pem'
- form.instance.private_key.save(filename, content)
- context = self.get_context_data()
-
- next_url = self.request.session.get(
- 'next',
- reverse_lazy('hosting:create_virtual_machine')
+ def delete(self, request, *args, **kwargs):
+ owner = self.request.user
+ manager = OpenNebulaManager(
+ email=owner.username,
+ password=owner.password
)
+ pk = self.kwargs.get('pk')
+ # Get user ssh key
+ public_key = UserHostingKey.objects.get(pk=pk).public_key
+ keys = UserHostingKey.objects.filter(user=self.request.user)
+ keys_to_save = [k.public_key for k in keys if k.public_key != public_key]
+ manager.save_key_in_opennebula_user('\n'.join(keys_to_save), update_type=0)
- if 'next' in self.request.session:
- context.update({
- 'next_url': next_url
- })
- del (self.request.session['next'])
+ return super(SSHKeyDeleteView, self).delete(request, *args, **kwargs)
- if form.cleaned_data.get('private_key'):
- context.update({
- 'private_key': form.cleaned_data.get('private_key'),
- 'key_name': form.cleaned_data.get('name'),
- 'form': UserHostingKeyForm(request=self.request),
- })
- if self.request.user.is_authenticated:
- owner = self.request.user
- # manager = OpenNebulaManager(
- # email=owner.username,
- # password=owner.password
- # )
- # keys_to_save = get_all_public_keys(self.request.user)
- # manager.save_key_in_opennebula_user('\n'.join(keys_to_save))
- else:
- self.request.session["new_user_hosting_key_id"] = form.instance.id
- return HttpResponseRedirect(self.success_url)
+class SSHKeyListView(LoginRequiredMixin, ListView):
+ template_name = "hosting/user_keys.html"
+ login_url = reverse_lazy('hosting:login')
+ context_object_name = "keys"
+ model = UserHostingKey
+ paginate_by = 10
+ ordering = '-id'
+
+ def get_queryset(self):
+ user = self.request.user
+ self.queryset = UserHostingKey.objects.filter(user=user)
+ return super(SSHKeyListView, self).get_queryset()
+
+ @method_decorator(decorators)
+ def render_to_response(self, context, **response_kwargs):
+ if not self.queryset:
+ return HttpResponseRedirect(reverse('hosting:choice_ssh_keys'))
+ return super(SSHKeyListView, self).render_to_response(context,
+ **response_kwargs)
+
+
+class SSHKeyChoiceView(LoginRequiredMixin, View):
+ template_name = "hosting/choice_ssh_keys.html"
+ login_url = reverse_lazy('hosting:login')
+
+ @method_decorator(decorators)
+ def get(self, request, *args, **kwargs):
+ context = {}
+ return render(request, self.template_name, context)
+
+ @method_decorator(decorators)
+ def post(self, request, *args, **kwargs):
+ name = generate_ssh_key_name()
+ private_key, public_key = UserHostingKey.generate_keys()
+ content = ContentFile(private_key)
+ ssh_key = UserHostingKey.objects.create(
+ user=request.user, public_key=public_key, name=name)
+ filename = name + '_' + str(uuid.uuid4())[:8] + '_private.pem'
+ ssh_key.private_key.save(filename, content)
+ owner = self.request.user
+ manager = OpenNebulaManager(
+ email=owner.username,
+ password=owner.password
+ )
+ keys = get_all_public_keys(request.user)
+ manager.save_key_in_opennebula_user('\n'.join(keys))
+ return redirect(reverse_lazy('hosting:ssh_keys'), foo='bar')
+
+
+@method_decorator(decorators, name='dispatch')
+class SettingsView(LoginRequiredMixin, FormView):
+ template_name = "hosting/settings.html"
+ login_url = reverse_lazy('hosting:login')
+ form_class = BillingAddressForm
+ permission_required = ['view_usercarddetail']
+
+ def get_form(self, form_class):
+ """
+ Check if the user already saved contact details. If so, then show
+ the form populated with those details, to let user change them.
+ """
+ return form_class(
+ instance=self.request.user.billing_addresses.first(),
+ **self.get_form_kwargs())
+
+ def get_context_data(self, **kwargs):
+ context = super(SettingsView, self).get_context_data(**kwargs)
+ # Get user
+ user = self.request.user
+ stripe_customer = None
+ if hasattr(user, 'stripecustomer'):
+ stripe_customer = user.stripecustomer
+ stripe_utils = StripeUtils()
+ cards_list_request = stripe_utils.get_available_payment_methods(
+ stripe_customer
+ )
+ cards_list = cards_list_request.get('response_object')
+ context.update({
+ 'cards_list': cards_list,
+ 'stripe_key': settings.STRIPE_API_PUBLIC_KEY
+ })
+
+ return context
def post(self, request, *args, **kwargs):
+ if 'card' in request.POST and request.POST['card'] != '':
+ card_id = escape(request.POST['card'])
+ UserCardDetail.set_default_card(
+ stripe_api_cus_id=request.user.stripecustomer.stripe_id,
+ stripe_source_id=card_id
+ )
+ stripe_utils = StripeUtils()
+ card_details = stripe_utils.get_cards_details_from_payment_method(
+ card_id
+ )
+ if not card_details.get('response_object'):
+ logger.debug("Could not find card %s in stripe" % card_id)
+ messages.add_message(request, messages.ERROR,
+ _("Could not set a default card."))
+ return HttpResponseRedirect(reverse_lazy('hosting:settings'))
+ card_details_response = card_details['response_object']
+ msg = _(
+ ("Your {brand} card ending in {last4} set as "
+ "default card").format(
+ brand=card_details_response['brand'],
+ last4=card_details_response['last4']
+ )
+ )
+ messages.add_message(request, messages.SUCCESS, msg)
+ return HttpResponseRedirect(reverse_lazy('hosting:settings'))
+ if 'delete_card' in request.POST:
+ card = self.kwargs.get('pk')
+ stripe_utils = StripeUtils()
+ stripe_utils.dissociate_customer_card(
+ request.user.stripecustomer.stripe_id,
+ card
+ )
+ msg = _("Card deassociation successful")
+ messages.add_message(request, messages.SUCCESS, msg)
+ return HttpResponseRedirect(reverse_lazy('hosting:settings'))
form = self.get_form()
- required = 'add_ssh' in self.request.POST
- form.fields['name'].required = required
- form.fields['public_key'].required = required
if form.is_valid():
- return self.form_valid(form)
+ if 'billing-form' in request.POST:
+ current_billing_address = self.request.user.billing_addresses.last()
+ billing_address_data = form.cleaned_data
+ billing_address_data.update({
+ 'user': self.request.user.id
+ })
+ billing_address_user_form = UserBillingAddressForm(
+ instance=self.request.user.billing_addresses.order_by('-id').first(),
+ data=billing_address_data)
+ billing_address = billing_address_user_form.save()
+ billing_address.stripe_tax_id = ''
+ billing_address.vat_number_validated_on = None
+ billing_address.vat_validation_status = ''
+ billing_address.save()
+ vat_number = billing_address_user_form.cleaned_data.get(
+ 'vat_number').strip()
+ logger.debug("Vat number = %s" % vat_number)
+ if vat_number:
+ try:
+ stripe_customer = request.user.stripecustomer
+ except StripeCustomer.DoesNotExist as dne:
+ logger.debug(
+ "User %s does not have a stripecustomer. "
+ "Creating one." % request.user.email)
+ stripe_customer = StripeCustomer.get_or_create(
+ email=request.user.email,
+ token=None)
+ request.user.stripecustomer = stripe_customer
+ request.user.save()
+ validate_result = validate_vat_number(
+ stripe_customer_id=request.user.stripecustomer.stripe_id,
+ billing_address_id=billing_address.id,
+ is_user_ba=True
+ )
+ logger.debug("validate_result = %s" % str(validate_result))
+ if 'error' in validate_result and validate_result['error']:
+ messages.add_message(
+ request, messages.ERROR,
+ "VAT Number validation error: %s" % validate_result["error"],
+ extra_tags='error'
+ )
+ billing_address = current_billing_address
+ if billing_address:
+ billing_address.save()
+ email_data = {
+ 'subject': "%s updated VAT number to %s but failed" %
+ (request.user.email, vat_number),
+ 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
+ 'to': settings.DCL_ERROR_EMAILS_TO_LIST,
+ 'body': "\n".join(
+ ["%s=%s" % (k, v) for (k, v) in
+ validate_result.items()]),
+ }
+ else:
+ email_data = {
+ 'subject': "%s updated VAT number to %s" % (
+ request.user.email, vat_number
+ ),
+ 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
+ 'to': settings.DCL_ERROR_EMAILS_TO_LIST,
+ 'body': "\n".join(
+ ["%s=%s" % (k, v) for (k, v) in
+ validate_result.items()]),
+ }
+ msg = _("Billing address updated successfully")
+ messages.add_message(request, messages.SUCCESS, msg)
+ send_plain_email_task.delay(email_data)
+ else:
+ msg = _("Billing address updated successfully")
+ messages.add_message(request, messages.SUCCESS, msg)
+ else:
+ id_payment_method = request.POST.get('id_payment_method', None)
+ stripe_utils = StripeUtils()
+ card_details = stripe_utils.get_cards_details_from_payment_method(
+ id_payment_method
+ )
+ if not card_details.get('response_object'):
+ form.add_error("__all__", card_details.get('error'))
+ return self.render_to_response(self.get_context_data())
+ stripe_customer = StripeCustomer.get_or_create(
+ email=request.user.email, id_payment_method=id_payment_method
+ )
+ card = card_details['response_object']
+ acc_result = stripe_utils.associate_customer_card(
+ request.user.stripecustomer.stripe_id,
+ id_payment_method,
+ set_as_default=True
+ )
+ if acc_result['response_object'] is None:
+ msg = _(
+ 'An error occurred while associating the card.'
+ ' Details: {details}'.format(
+ details=acc_result['error']
+ )
+ )
+ messages.add_message(request, messages.ERROR, msg)
+ return self.render_to_response(self.get_context_data())
+ preferred = False
+ if stripe_customer.usercarddetail_set.count() == 0:
+ preferred = True
+ UserCardDetail.create(
+ stripe_customer=stripe_customer,
+ last4=card['last4'],
+ brand=card['brand'],
+ fingerprint=card['fingerprint'],
+ exp_month=card['exp_month'],
+ exp_year=card['exp_year'],
+ card_id=card['card_id'],
+ preferred=preferred
+ )
+ msg = _(
+ "Successfully associated the card with your account"
+ )
+ messages.add_message(request, messages.SUCCESS, msg)
+ return self.render_to_response(self.get_context_data())
+ else:
+ billing_address_data = form.cleaned_data
+ return self.form_invalid(form)
+
+
+class PaymentVMView(LoginRequiredMixin, FormView):
+ template_name = 'hosting/payment.html'
+ login_url = reverse_lazy('hosting:login')
+ form_class = BillingAddressForm
+
+ def get_form_kwargs(self):
+ current_billing_address = self.request.user.billing_addresses.last()
+ form_kwargs = super(PaymentVMView, self).get_form_kwargs()
+ if not current_billing_address:
+ return form_kwargs
+
+ form_kwargs.update({
+ 'initial': {
+ 'cardholder_name': current_billing_address.cardholder_name,
+ 'street_address': current_billing_address.street_address,
+ 'city': current_billing_address.city,
+ 'postal_code': current_billing_address.postal_code,
+ 'country': current_billing_address.country,
+ 'vat_number': current_billing_address.vat_number
+ }
+ })
+ return form_kwargs
+
+ def get_context_data(self, **kwargs):
+ context = super(PaymentVMView, self).get_context_data(**kwargs)
+ # Get user
+ user = self.request.user
+ if hasattr(user, 'stripecustomer'):
+ stripe_customer = user.stripecustomer
+ else:
+ stripe_customer = None
+ cards_list = UserCardDetail.get_all_cards_list(
+ stripe_customer=stripe_customer
+ )
+ context.update({
+ 'stripe_key': settings.STRIPE_API_PUBLIC_KEY,
+ 'vm_pricing': VMPricing.get_vm_pricing_by_name(
+ self.request.session.get('specs', {}).get('pricing_name')
+ ),
+ 'cards_list': cards_list,
+ })
+
+ return context
+
+ @method_decorator(decorators)
+ def get(self, request, *args, **kwargs):
+ if 'next' in request.session:
+ del request.session['next']
+ HostingUtils.clear_items_from_list(
+ request.session,
+ ['token', 'card_id', 'customer', 'user']
+ )
+ return self.render_to_response(self.get_context_data())
+
+ @method_decorator(decorators)
+ def post(self, request, *args, **kwargs):
+ form = self.get_form()
+ if form.is_valid():
+ # Get billing address data
+ billing_address_data = form.cleaned_data
+ token = form.cleaned_data.get('token')
+ owner = self.request.user
+ if token == '':
+ card_id = form.cleaned_data.get('card')
+ customer = owner.stripecustomer
+ try:
+ user_card_detail = UserCardDetail.objects.get(id=card_id)
+ if not request.user.has_perm(
+ 'view_usercarddetail', user_card_detail
+ ):
+ raise UserCardDetail.DoesNotExist(
+ _("{user} does not have permission to access the "
+ "card").format(user=request.user.email)
+ )
+ except UserCardDetail.DoesNotExist as e:
+ ex = str(e)
+ logger.error("Card Id: {card_id}, Exception: {ex}".format(
+ card_id=card_id, ex=ex
+ )
+ )
+ msg = _("An error occurred. Details: {}".format(ex))
+ messages.add_message(
+ self.request, messages.ERROR, msg,
+ extra_tags='make_charge_error'
+ )
+ return HttpResponseRedirect(
+ reverse('hosting:payment') + '#payment_error'
+ )
+ request.session['card_id'] = user_card_detail.id
+ else:
+ # Get or create stripe customer
+ customer = StripeCustomer.get_or_create(
+ email=owner.email, token=token
+ )
+ if not customer:
+ msg = _("Invalid credit card")
+ messages.add_message(
+ self.request, messages.ERROR, msg,
+ extra_tags='make_charge_error')
+ return HttpResponseRedirect(
+ reverse('hosting:payment') + '#payment_error')
+ request.session['token'] = token
+ request.session['billing_address_data'] = billing_address_data
+ self.request.session['order_confirm_url'] = "{url}?{query_params}".format(
+ url=reverse('hosting:order-confirmation'),
+ query_params='page=payment')
+ return HttpResponseRedirect(reverse('hosting:add_ssh_key'))
else:
return self.form_invalid(form)
-class AskSSHKeyView(SSHKeyCreateView):
- form_class = UserHostingKeyForm
- template_name = "hosting/add_ssh_key.html"
- success_url = reverse_lazy('hosting:order_confirmation')
- context_object_name = "dcl_vm_buy_add_ssh_key"
-
- # @cache_control(no_cache=True, must_revalidate=True, no_store=True)
- def get(self, request, *args, **kwargs):
- context = {
- 'site_url': reverse_lazy('hosting:login'),
- # 'cms_integration': get_cms_integration('default'),
- 'form': UserHostingKeyForm(request=self.request),
- # 'keys': get_all_public_keys(self.request.user)
- }
- return render(request, self.template_name, context)
-
- def post(self, request, *args, **kwargs):
- self.success_url = self.request.session.get("order_confirm_url")
- return super(AskSSHKeyView, self).post(self, request, *args, **kwargs)
-
-
-class IndexView(View):
- template_name = "hosting/index.html"
-
- def get_context_data(self, **kwargs):
- # TODO refactor below
- templates = []
- data = None
-
- context = {
- 'hosting': "nodejs",
- 'hosting_long': "NodeJS",
- 'domain': "node-hosting.ch",
- 'google_analytics': "UA-62285904-7",
- 'email': "info@node-hosting.ch",
- 'vm_types': data
- # 'vm_types': VirtualMachineType.get_serialized_vm_types(),
- }
- return context
-
- @method_decorator(decorators)
- def get(self, request, *args, **kwargs):
- context = self.get_context_data()
- return render(request, self.template_name, context)
-
-
-class DashboardView(LoginRequiredMixin, View):
- template_name = "hosting/dashboard.html"
- login_url = reverse_lazy('hosting:login')
-
- def get_context_data(self, **kwargs):
- context = {}
- return context
-
- @method_decorator(decorators)
- def get(self, request, *args, **kwargs):
- context = self.get_context_data()
- context['has_invoices'] = False
- bills = []
- # try:
- # if hasattr(self.request.user, 'stripecustomer'):
- # bills = MonthlyHostingBill.objects.filter(
- # customer=self.request.user.stripecustomer
- # )
- # if len(bills) > 0:
- # context['has_invoices'] = True
- # except MonthlyHostingBill.DoesNotExist as dne:
- # logger.error("{}'s monthly hosting bill not imported ?".format(
- # self.request.user.email
- # ))
- return render(request, self.template_name, context)
-
-
-class CustomLogoutView(LogoutView):
- next_page = reverse_lazy('hosting:login')
-
-
-class PaymentOrderView(FormView):
- template_name = 'hositng/landing_payment.html'
-
- def get_form_class(self):
- if self.request.user.is_authenticated():
- return BillingAddressForm
- else:
- return BillingAddressFormSignup
-
- def get_context_data(self, **kwargs):
- context = super(PaymentOrderView, self).get_context_data(**kwargs)
- if 'billing_address_data' in self.request.session:
- billing_address_data = self.request.session['billing_address_data']
- else:
- billing_address_data = {}
-
- if self.request.user.is_authenticated():
- if billing_address_data:
- billing_address_form = BillingAddressForm(
- initial=billing_address_data
- )
- else:
- billing_address_form = BillingAddressForm(
- instance=self.request.user.billing_addresses.order_by('-id').first()
- )
- user = self.request.user
- if hasattr(user, 'stripecustomer'):
- stripe_customer = user.stripecustomer
- else:
- stripe_customer = None
- stripe_utils = StripeUtils()
- cards_list_request = stripe_utils.get_available_payment_methods(
- stripe_customer
- )
- cards_list = cards_list_request.get('response_object')
- context.update({'cards_list': cards_list})
- else:
- billing_address_form = BillingAddressFormSignup(
- initial=billing_address_data
- )
-
- context.update({
- 'stripe_key': settings.STRIPE_API_PUBLIC_KEY,
- 'site_url': reverse('hosting:dashboard'),
- 'login_form': HostingUserLoginForm(prefix='login_form'),
- 'billing_address_form': billing_address_form,
- })
-
- if ('generic_payment_type' in self.request.session and
- self.request.session['generic_payment_type'] == 'generic'):
- if 'product_id' in self.request.session:
- product = GenericProduct.objects.get(
- id=self.request.session['product_id']
- )
- context.update({'generic_payment_form': ProductPaymentForm(
- prefix='generic_payment_form',
- initial={'product_name': product.product_name,
- 'amount': float(product.get_actual_price()),
- 'recurring': product.product_is_subscription,
- 'description': product.product_description,
- },
- product_id=product.id
- ), })
- else:
- context.update({'generic_payment_form': GenericPaymentForm(
- prefix='generic_payment_form',
- ), })
- else:
- logger.debug(f"VM creation not implemented")
-
- return context
-
- @cache_control(no_cache=True, must_revalidate=True, no_store=True)
- def get(self, request, *args, **kwargs):
- request.session.pop('vat_validation_status')
- request.session.pop('card_id')
- request.session.pop('token')
- request.session.pop('id_payment_method')
- logger.debug("Session: %s" % str(request.session))
- for key, value in request.session.items():
- logger.debug("Session: %s %s" % (key, value))
- if (('type' in request.GET and request.GET['type'] == 'generic')
- or 'product_slug' in kwargs):
- request.session['generic_payment_type'] = 'generic'
- if 'generic_payment_details' in request.session:
- request.session.pop('generic_payment_details')
- request.session.pop('product_id')
- if 'product_slug' in kwargs:
- logger.debug("Product slug is " + kwargs['product_slug'])
- try:
- product = GenericProduct.objects.get(
- product_slug=kwargs['product_slug']
- )
- except GenericProduct.DoesNotExist as dne:
- logger.error(
- "Product '{}' does "
- "not exist".format(kwargs['product_slug'])
- )
- raise Http404()
- request.session['product_id'] = product.id
- elif 'specs' not in request.session:
- return HttpResponseRedirect(reverse('hosting:dashboard'))
- return self.render_to_response(self.get_context_data())
-
- def post(self, request, *args, **kwargs):
- if 'product' in request.POST:
- # query for the supplied product
- product = None
- try:
- product = GenericProduct.objects.get(
- id=request.POST['generic_payment_form-product_name']
- )
- except GenericProduct.DoesNotExist as dne:
- logger.error(
- "The requested product '{}' does not exist".format(
- request.POST['generic_payment_form-product_name']
- )
- )
- except GenericProduct.MultipleObjectsReturned as mpe:
- logger.error(
- "There seem to be more than one product with "
- "the name {}".format(
- request.POST['generic_payment_form-product_name']
- )
- )
- product = GenericProduct.objects.all(
- product_name=request.
- POST['generic_payment_form-product_name']
- ).first()
- if product is None:
- return JsonResponse({})
- else:
- return JsonResponse({
- 'amount': product.get_actual_price(),
- 'isSubscription': product.product_is_subscription
- })
- if 'login_form' in request.POST:
- login_form = HostingUserLoginForm(
- data=request.POST, prefix='login_form'
- )
- if login_form.is_valid():
- email = login_form.cleaned_data.get('email')
- password = login_form.cleaned_data.get('password')
- auth_user = authenticate(email=email, password=password)
- if auth_user:
- login(self.request, auth_user)
- if 'product_slug' in kwargs:
- return HttpResponseRedirect(
- reverse('show_product',
- kwargs={
- 'product_slug': kwargs['product_slug']}
- )
- )
- return HttpResponseRedirect(
- reverse('hosting:payment')
- )
- else:
- context = self.get_context_data()
- context['login_form'] = login_form
- return self.render_to_response(context)
- if request.user.is_authenticated():
- address_form = BillingAddressForm(
- data=request.POST,
- )
- else:
- address_form = BillingAddressFormSignup(
- data=request.POST,
- )
- if address_form.is_valid():
- # Check if we are in a generic payment case and handle the generic
- # payment details form before we go on to verify payment
- if ('generic_payment_type' in request.session and
- self.request.session['generic_payment_type'] == 'generic'):
- if 'product_id' in request.session:
- generic_payment_form = ProductPaymentForm(
- data=request.POST, prefix='generic_payment_form',
- product_id=request.session['product_id']
- )
- else:
- generic_payment_form = GenericPaymentForm(
- data=request.POST, prefix='generic_payment_form'
- )
- if generic_payment_form.is_valid():
- logger.debug("Generic payment form is valid.")
- if 'product_id' in request.session:
- product = generic_payment_form.product
- else:
- product = generic_payment_form.cleaned_data.get(
- 'product_name'
- )
- user_country_vat_rate = get_vat_rate_for_country(
- address_form.cleaned_data["country"]
- )
- gp_details = {
- "product_name": product.product_name,
- "vat_rate": 0 if product.exclude_vat_calculations else
- user_country_vat_rate * 100,
- "vat_amount": 0 if product.exclude_vat_calculations
- else round(
- float(product.product_price) *
- user_country_vat_rate, 2),
- "vat_country": address_form.cleaned_data["country"],
- "amount_before_vat": round(
- float(product.product_price), 2),
- "amount": product.get_actual_price(
- vat_rate=get_vat_rate_for_country(
- address_form.cleaned_data["country"])
- ),
- "recurring": generic_payment_form.cleaned_data.get(
- 'recurring'
- ),
- "description": generic_payment_form.cleaned_data.get(
- 'description'
- ),
- "product_id": product.id,
- "product_slug": product.product_slug,
- "recurring_interval":
- product.product_subscription_interval,
- "exclude_vat_calculations": product.exclude_vat_calculations
- }
- request.session["generic_payment_details"] = (
- gp_details
- )
- else:
- logger.debug("Generic payment form invalid")
- context = self.get_context_data()
- context['generic_payment_form'] = generic_payment_form
- context['billing_address_form'] = address_form
- return self.render_to_response(context)
- id_payment_method = self.request.POST.get('id_payment_method',
- None)
- if id_payment_method == 'undefined':
- id_payment_method = address_form.cleaned_data.get('card')
- request.session["id_payment_method"] = id_payment_method
- logger.debug("id_payment_method is %s" % id_payment_method)
- if request.user.is_authenticated():
- this_user = {
- 'email': request.user.email,
- 'name': request.user.name
- }
- customer = StripeCustomer.get_or_create(
- email=this_user.get('email'),
- id_payment_method=id_payment_method
- )
- else:
- user_email = address_form.cleaned_data.get('email')
- user_name = address_form.cleaned_data.get('name')
- this_user = {
- 'email': user_email,
- 'name': user_name
- }
- try:
- custom_user = CustomUser.objects.get(email=user_email)
- customer = StripeCustomer.objects.filter(
- user_id=custom_user.id).first()
- if customer is None:
- logger.debug(
- ("User {email} is already registered with us."
- "But, StripeCustomer does not exist for {email}."
- "Hence, creating a new StripeCustomer.").format(
- email=user_email
- )
- )
- customer = StripeCustomer.create_stripe_api_customer(
- email=user_email,
- id_payment_method=id_payment_method,
- customer_name=user_name)
- except CustomUser.DoesNotExist:
- logger.debug(
- ("StripeCustomer does not exist for {email}."
- "Hence, creating a new StripeCustomer.").format(
- email=user_email
- )
- )
- customer = StripeCustomer.create_stripe_api_customer(
- email=user_email,
- id_payment_method=id_payment_method,
- customer_name=user_name)
-
- billing_address = address_form.save()
- request.session["billing_address_id"] = billing_address.id
- request.session['billing_address_data'] = address_form.cleaned_data
- request.session['user'] = this_user
- # Get or create stripe customer
- if not customer:
- address_form.add_error(
- "__all__", "Invalid credit card"
- )
- return self.render_to_response(
- self.get_context_data(
- billing_address_form=address_form
- )
- )
- if type(customer) is StripeCustomer:
- request.session['customer'] = customer.stripe_id
- else:
- request.session['customer'] = customer
-
- vat_number = address_form.cleaned_data.get('vat_number').strip()
- if vat_number:
- validate_result = validate_vat_number(
- stripe_customer_id=request.session['customer'],
- billing_address_id=billing_address.id
- )
-
- if 'error' in validate_result and validate_result['error']:
- messages.add_message(
- request, messages.ERROR, validate_result["error"],
- extra_tags='vat_error'
- )
- return HttpResponseRedirect(
- reverse('hosting:payment') + '#vat_error'
- )
- request.session["vat_validation_status"] = validate_result["status"]
-
- # For generic payment we take the user directly to confirmation
- if ('generic_payment_type' in request.session and
- self.request.session['generic_payment_type'] == 'generic'):
- return HttpResponseRedirect(
- reverse('hosting:order_confirmation'))
- else:
- self.request.session['order_confirm_url'] = reverse('hosting:order_confirmation')
- return HttpResponseRedirect(
- reverse('hosting:add_ssh_key'))
- else:
- context = self.get_context_data()
- context['billing_address_form'] = address_form
- return self.render_to_response(context)
-
-
-class OrderConfirmationView(DetailView, FormView):
+class OrdersHostingDetailView(LoginRequiredMixin, DetailView, FormView):
form_class = UserHostingKeyForm
template_name = "hosting/order_detail.html"
- payment_template_name = 'hosting/landing_payment.html'
context_object_name = "order"
+ login_url = reverse_lazy('hosting:login')
+ permission_required = ['view_hostingorder']
model = HostingOrder
def get_form_kwargs(self):
- kwargs = super(OrderConfirmationView, self).get_form_kwargs()
+ kwargs = super(OrdersHostingDetailView, self).get_form_kwargs()
kwargs.update({'request': self.request})
return kwargs
- @cache_control(no_cache=True, must_revalidate=True, no_store=True)
- def get(self, request, *args, **kwargs):
- context = {}
- # this is amount to be charge/subscribed before VAT and discount
- # and expressed in chf. To convert to cents, multiply by 100
- amount_to_charge = 0
- vm_specs = None
- if (('specs' not in request.session or 'user' not in request.session)
- and 'generic_payment_type' not in request.session):
- return HttpResponseRedirect(reverse('hosting:dashboards'))
- if 'id_payment_method' in self.request.session:
- payment_method = self.request.session['id_payment_method']
- logger.debug("id_payment_method: %s" % payment_method)
- stripe_utils = StripeUtils()
- card_details = stripe_utils.get_cards_details_from_payment_method(
- payment_method
- )
- if not card_details.get('response_object'):
- return HttpResponseRedirect(reverse('hosting:payment'))
- card_details_response = card_details['response_object']
- context['cc_last4'] = card_details_response['last4']
- context['cc_brand'] = card_details_response['brand']
- context['cc_exp_year'] = card_details_response['exp_year']
- context['cc_exp_month'] = '{:02d}'.format(
- card_details_response['exp_month'])
- context['id_payment_method'] = payment_method
- else:
- # TODO check when we go through this case (to me, it seems useless)
- card_id = self.request.session.get('card_id')
- logger.debug("NO id_payment_method, using card: %s" % card_id)
- card_detail = UserCardDetail.objects.get(id=card_id)
- context['cc_last4'] = card_detail.last4
- context['cc_brand'] = card_detail.brand
- context['cc_exp_year'] = card_detail.exp_year
- context['cc_exp_month'] = '{:02d}'.format(card_detail.exp_month)
+ def get_object(self, queryset=None):
+ order_id = self.kwargs.get('pk')
+ try:
+ hosting_order_obj = HostingOrder.objects.get(pk=order_id)
+ logger.debug("Found HostingOrder for id {order_id}".format(
+ order_id=order_id
+ ))
+ except HostingOrder.DoesNotExist:
+ logger.debug("HostingOrder not found for id {order_id}".format(
+ order_id=order_id
+ ))
+ hosting_order_obj = None
+ return hosting_order_obj
- if ('generic_payment_type' in request.session and
- self.request.session['generic_payment_type'] == 'generic'):
- if "vat_validation_status" in request.session and (
- request.session["vat_validation_status"] == "verified" or
- request.session["vat_validation_status"] == "not_needed"):
- request.session['generic_payment_details']['vat_rate'] = 0
- request.session['generic_payment_details']['vat_amount'] = 0
- request.session['generic_payment_details']['amount'] = (
- request.session['generic_payment_details']['amount_before_vat']
- )
- context.update({
- 'generic_payment_details':
- request.session['generic_payment_details'],
- })
- amount_to_charge = request.session['generic_payment_details']['amount']
+ def get_context_data(self, **kwargs):
+ # Get context
+ context = super(
+ OrdersHostingDetailView, self
+ ).get_context_data(**kwargs)
+ obj = self.get_object()
+ owner = self.request.user
+
+ if self.request.GET.get('page') == 'payment':
+ context['page_header_text'] = _('Confirm Order')
+ context['form'] = UserHostingKeyForm(request=self.request)
+ context['keys'] = get_all_public_keys(self.request.user)
else:
- vm_specs = request.session.get('specs')
+ context['page_header_text'] = _('Invoice')
+ if not self.request.user.has_perm(
+ self.permission_required[0], obj
+ ):
+ logger.debug(
+ "User {user} does not have permission on HostingOrder "
+ "{order_id}. Raising 404 error now.".format(
+ user=self.request.user.email,
+ order_id=obj.id if obj else 'None'
+ )
+ )
+ raise Http404
+
+ if obj is not None:
+ if obj.generic_product_id is not None:
+ # generic payment case
+ logger.debug("Generic payment case")
+ context['product_name'] = GenericProduct.objects.get(
+ id=obj.generic_product_id
+ ).product_name
+ else:
+ # invoice for previous order
+ logger.debug("Invoice of VM order")
+ try:
+ vm_detail = VMDetail.objects.get(vm_id=obj.vm_id)
+ context['vm'] = vm_detail.__dict__
+ context['vm']['name'] = '{}-{}'.format(
+ context['vm']['configuration'], context['vm']['vm_id'])
+ user_vat_country = obj.billing_address.country
+ user_country_vat_rate = get_vat_rate_for_country(
+ user_vat_country)
+ price, vat, vat_percent, discount = get_vm_price_for_given_vat(
+ cpu=context['vm']['cores'],
+ ssd_size=context['vm']['disk_size'],
+ memory=context['vm']['memory'],
+ pricing_name=(obj.vm_pricing.name
+ if obj.vm_pricing else 'default'),
+ vat_rate= (
+ user_country_vat_rate * 100
+ if obj.vm_id >= settings.FIRST_VM_ID_AFTER_EU_VAT
+ else settings.PRE_EU_VAT_RATE
+ )
+ )
+ context['vm']["after_eu_vat_intro"] = (
+ True if obj.vm_id >= settings.FIRST_VM_ID_AFTER_EU_VAT
+ else False
+ )
+ context['vm']["price"] = price
+ context['vm']["vat"] = vat
+ context['vm']["vat_percent"] = vat_percent
+ context['vm']["vat_country"] = user_vat_country
+ context['vm']["discount"] = discount
+ context['vm']["total_price"] = round(
+ price + vat - discount['amount'], 2)
+ context['subscription_end_date'] = vm_detail.end_date()
+ except VMDetail.DoesNotExist:
+ try:
+ manager = OpenNebulaManager(
+ email=owner.username, password=owner.password
+ )
+ vm = manager.get_vm(obj.vm_id)
+ context['vm'] = VirtualMachineSerializer(vm).data
+ user_vat_country = obj.billing_address.country
+ user_country_vat_rate = get_vat_rate_for_country(
+ user_vat_country)
+ price, vat, vat_percent, discount = get_vm_price_for_given_vat(
+ cpu=context['vm']['cores'],
+ ssd_size=context['vm']['disk_size'],
+ memory=context['vm']['memory'],
+ pricing_name=(obj.vm_pricing.name
+ if obj.vm_pricing else 'default'),
+ vat_rate=(
+ user_country_vat_rate * 100
+ if obj.vm_id >= settings.FIRST_VM_ID_AFTER_EU_VAT
+ else settings.PRE_EU_VAT_RATE
+ )
+ )
+ context['vm']["after_eu_vat_intro"] = (
+ True if obj.vm_id >= settings.FIRST_VM_ID_AFTER_EU_VAT
+ else False
+ )
+ context['vm']["price"] = price
+ context['vm']["vat"] = vat
+ context['vm']["vat_percent"] = vat_percent
+ context['vm']["vat_country"] = user_vat_country
+ context['vm']["discount"] = discount
+ context['vm']["total_price"] = round(
+ price + vat - discount['amount'], 2)
+ except WrongIdError:
+ messages.error(
+ self.request,
+ _('The VM you are looking for is unavailable at the '
+ 'moment. Please contact Data Center Light support.')
+ )
+ self.kwargs['error'] = 'WrongIdError'
+ context['error'] = 'WrongIdError'
+ except ConnectionRefusedError:
+ messages.error(
+ self.request,
+ _('In order to create a VM, you need to create/upload '
+ 'your SSH KEY first.')
+ )
+ else:
+ # new order, confirm payment
+ if 'token' in self.request.session:
+ token = self.request.session['token']
+ stripe_utils = StripeUtils()
+ card_details = stripe_utils.get_cards_details_from_token(
+ token
+ )
+ if not card_details.get('response_object'):
+ return HttpResponseRedirect(reverse('hosting:payment'))
+ card_details_response = card_details['response_object']
+ context['cc_last4'] = card_details_response['last4']
+ context['cc_brand'] = card_details_response['brand']
+ context['cc_exp_year'] = card_details_response['exp_year']
+ context['cc_exp_month'] = card_details_response['exp_month']
+ else:
+ card_id = self.request.session.get('card_id')
+ card_detail = UserCardDetail.objects.get(id=card_id)
+ context['cc_last4'] = card_detail.last4
+ context['cc_brand'] = card_detail.brand
+ context['cc_exp_year'] = card_detail.exp_year
+ context['cc_exp_month'] = '{:02d}'.format(card_detail.exp_month)
+ context['site_url'] = reverse('hosting:create_virtual_machine')
+ vm_specs = self.request.session.get('specs')
user_vat_country = (
- request.session.get('billing_address_data').get("country")
+ self.request.session.get('billing_address_data').get("country")
)
user_country_vat_rate = get_vat_rate_for_country(user_vat_country)
price, vat, vat_percent, discount = get_vm_price_for_given_vat(
@@ -769,199 +1030,73 @@ class OrderConfirmationView(DetailView, FormView):
vat_rate=user_country_vat_rate * 100
)
vm_specs["price"] = price
- vm_specs["price_after_discount"] = price - discount["amount"]
- amount_to_charge = price
- vat_number = request.session.get('billing_address_data').get("vat_number")
- billing_address = BillingAddress.objects.get(
- id=request.session["billing_address_id"])
- if vat_number:
- validate_result = validate_vat_number(
- stripe_customer_id=request.session['customer'],
- billing_address_id=billing_address.id
- )
- if 'error' in validate_result and validate_result['error']:
- messages.add_message(
- request, messages.ERROR, validate_result["error"],
- extra_tags='vat_error'
- )
- return HttpResponseRedirect(
- reverse('datacenterlight:payment') + '#vat_error'
- )
- request.session["vat_validation_status"] = validate_result["status"]
-
- if user_vat_country.lower() == "ch":
- vm_specs["vat"] = vat
- vm_specs["vat_percent"] = vat_percent
- vm_specs["vat_validation_status"] = "ch_vat"
- elif ("vat_validation_status" in request.session and
- (request.session["vat_validation_status"] == "verified" or
- request.session["vat_validation_status"] == "not_needed")):
- vm_specs["vat_percent"] = 0
- vm_specs["vat"] = 0
- vm_specs["vat_validation_status"] = request.session["vat_validation_status"]
- else:
- vm_specs["vat"] = vat
- vm_specs["vat_percent"] = vat_percent
- vm_specs["vat_validation_status"] = request.session[
- "vat_validation_status"] if "vat_validation_status" in request.session else ""
+ vm_specs["vat"] = vat
+ vm_specs["vat_percent"] = vat_percent
vm_specs["vat_country"] = user_vat_country
- vm_specs["price_with_vat"] = round(price * (1 + vm_specs["vat_percent"] * 0.01), 2)
- vm_specs["price_after_discount"] = round(price - discount['amount'], 2)
- vm_specs["price_after_discount_with_vat"] = round(
- (price - discount['amount']) * (1 + vm_specs["vat_percent"] * 0.01), 2)
- discount["amount_with_vat"] = round(vm_specs["price_with_vat"] - vm_specs["price_after_discount_with_vat"],
- 2)
- vm_specs["total_price"] = vm_specs["price_after_discount_with_vat"]
vm_specs["discount"] = discount
- logger.debug(vm_specs)
- request.session['specs'] = vm_specs
+ vm_specs["total_price"] = round(price + vat - discount['amount'],
+ 2)
+ vm_specs["after_eu_vat_intro"] = True
+ context['vm'] = vm_specs
+ return context
- context.update({
- 'vm': vm_specs,
- 'form': UserHostingKeyForm(request=self.request),
- 'keys': get_all_public_keys(self.request.user)
- })
+ @method_decorator(decorators)
+ def get(self, request, *args, **kwargs):
+ if not self.kwargs.get('pk'):
+ if 'specs' not in self.request.session:
+ return HttpResponseRedirect(
+ reverse('hosting:create_virtual_machine')
+ )
- is_subscription = False
- if ('generic_payment_type' not in request.session or
- (request.session['generic_payment_details']['recurring'])):
- # Obtain PaymentIntent so that we can initiate and charge
- # the customer
- is_subscription = True
- logger.debug("CASE: Subscription")
- else:
- logger.debug("CASE: One time payment")
- stripe_utils = StripeUtils()
- payment_intent_response = stripe_utils.get_payment_intent(
- int(amount_to_charge * 100),
- customer=request.session['customer']
+ if ('token' not in self.request.session and
+ 'card_id' not in self.request.session):
+ return HttpResponseRedirect(reverse('hosting:payment'))
+ self.object = self.get_object()
+ context = self.get_context_data(object=self.object)
+ if 'failed_payment' in context:
+ msg = context['card_details'].get('error')
+ messages.add_message(
+ self.request, messages.ERROR, msg,
+ extra_tags='failed_payment'
)
- payment_intent = payment_intent_response.get(
- 'response_object')
- if not payment_intent:
- logger.error("Could not create payment_intent %s" %
- str(payment_intent_response))
- else:
- logger.debug("payment_intent.client_secret = %s" %
- str(payment_intent.client_secret))
- context.update({
- 'payment_intent_secret': payment_intent.client_secret
- })
- logger.debug("Request %s" % create_incomplete_intent_request(
- self.request))
- logger.debug("%s" % str(payment_intent))
- logger.debug("customer %s" % request.session['customer'])
- logger.debug("card_details_response %s" % card_details_response)
- logger.debug("request.session[generic_payment_details] %s" % request.session["generic_payment_details"])
- logger.debug("request.session[billing_address_data] %s" % request.session["billing_address_data"])
- IncompletePaymentIntents.objects.create(
- request=create_incomplete_intent_request(self.request),
- payment_intent_id=payment_intent.id,
- stripe_api_cus_id=request.session['customer'],
- card_details_response=json.dumps(card_details_response),
- stripe_subscription_id=None,
- stripe_charge_id=None,
- gp_details=json.dumps(request.session["generic_payment_details"]),
- billing_address_data=json.dumps(request.session["billing_address_data"])
+ return HttpResponseRedirect(
+ reverse('hosting:payment') + '#payment_error'
)
- logger.debug("IncompletePaymentIntent done")
+ return self.render_to_response(context)
- context.update({
- 'site_url': reverse('datacenterlight:index'),
- 'page_header_text': _('Confirm Order'),
- 'billing_address_data': (
- request.session.get('billing_address_data')
- ),
- #'cms_integration': get_cms_integration('default'),
- 'error_msg': get_error_response_dict("Error", request),
- 'success_msg': {
- 'msg_title': _("Thank you !"),
- 'msg_body': _("Your product will be provisioned as soon as "
- "we receive the payment."),
- 'redirect': reverse('hosting:invoices') if
- request.user.is_authenticated() else
- reverse('datacenterlight:index')
- },
- 'stripe_key': settings.STRIPE_API_PUBLIC_KEY,
- 'is_subscription': str(is_subscription).lower()
- })
- return render(request, self.template_name, context)
-
- def post(self, request, *args, **kwargs):
- stripe_onetime_charge = None
- stripe_customer_obj = None
- gp_details = None
- specs = None
- vm_template_id = 0
- template = None
- user = request.session.get('user')
- stripe_api_cus_id = request.session.get('customer')
+ @method_decorator(decorators)
+ def post(self, request):
+ template = request.session.get('template')
+ specs = request.session.get('specs')
stripe_utils = StripeUtils()
- logger.debug("user=%s stripe_api_cus_id=%s" % (user, stripe_api_cus_id))
- card_details_response = None
- new_user_hosting_key_id = None
- card_id = None
- generic_payment_type = None
- generic_payment_details = None
- stripe_subscription_obj = None
- if 'generic_payment_details' in request.session:
- generic_payment_details = request.session[
- 'generic_payment_details']
- if 'generic_payment_type' in request.session:
- generic_payment_type = request.session['generic_payment_type']
- if 'new_user_hosting_key_id' in self.request.session:
- new_user_hosting_key_id = request.session[
- 'new_user_hosting_key_id']
- if 'card_id' in request.session:
- card_id = request.session.get('card_id')
- req = {
- 'scheme': self.request.scheme,
- 'host': self.request.get_host(),
- 'language': get_language(),
- 'new_user_hosting_key_id': new_user_hosting_key_id,
- 'card_id': card_id,
- 'generic_payment_type': generic_payment_type,
- 'generic_payment_details': generic_payment_details,
- 'user': user
- }
-
- if 'id_payment_method' in request.session:
- card_details = stripe_utils.get_cards_details_from_payment_method(
- request.session.get('id_payment_method')
+ # We assume that if the user is here, his/her StripeCustomer
+ # object already exists
+ stripe_customer_id = request.user.stripecustomer.id
+ billing_address_data = request.session.get('billing_address_data')
+ vm_template_id = template.get('id', 1)
+ stripe_api_cus_id = request.user.stripecustomer.stripe_id
+ logger.debug("template=%s specs=%s stripe_customer_id=%s "
+ "billing_address_data=%s vm_template_id=%s "
+ "stripe_api_cus_id=%s" % (
+ template, specs, stripe_customer_id, billing_address_data,
+ vm_template_id, stripe_api_cus_id)
+ )
+ if 'id_payment_method' in self.request.session:
+ card_details = stripe_utils.get_cards_details_from_token(
+ request.session['token']
)
- logger.debug(
- "card_details=%s" % (card_details))
if not card_details.get('response_object'):
- msg = card_details.get('error')
- return show_error(msg, self.request)
+ return HttpResponseRedirect(reverse('hosting:payment'))
card_details_response = card_details['response_object']
card_details_dict = {
'last4': card_details_response['last4'],
'brand': card_details_response['brand'],
'card_id': card_details_response['card_id']
}
- stripe_customer_obj = StripeCustomer.objects.filter(
- stripe_id=stripe_api_cus_id).first()
- if stripe_customer_obj:
- ucd = UserCardDetail.get_user_card_details(
- stripe_customer_obj, card_details_response
- )
- if not ucd:
- acc_result = stripe_utils.associate_customer_card(
- stripe_api_cus_id, request.session['id_payment_method'],
- set_as_default=True
- )
- if acc_result['response_object'] is None:
- msg = _(
- 'An error occurred while associating the card.'
- ' Details: {details}'.format(
- details=acc_result['error']
- )
- )
- return show_error(msg, self.request)
- else:
- # Associate PaymentMethod with the stripe customer
- # and set it as the default source
+ ucd = UserCardDetail.get_user_card_details(
+ request.user.stripecustomer, card_details_response
+ )
+ if not ucd:
acc_result = stripe_utils.associate_customer_card(
stripe_api_cus_id, request.session['id_payment_method'],
set_as_default=True
@@ -973,8 +1108,22 @@ class OrderConfirmationView(DetailView, FormView):
details=acc_result['error']
)
)
- return show_error(msg, self.request)
- elif 'card_id' in request.session:
+ messages.add_message(self.request, messages.ERROR, msg,
+ extra_tags='failed_payment')
+ response = {
+ 'status': False,
+ 'redirect': "{url}#{section}".format(
+ url=reverse('hosting:payment'),
+ section='payment_error'),
+ 'msg_title': str(_('Error.')),
+ 'msg_body': str(
+ _('There was a payment related error.'
+ ' On close of this popup, you will be redirected'
+ ' back to the payment page.')
+ )
+ }
+ return JsonResponse(response)
+ else:
card_id = request.session.get('card_id')
user_card_detail = UserCardDetail.objects.get(id=card_id)
card_details_dict = {
@@ -982,264 +1131,143 @@ class OrderConfirmationView(DetailView, FormView):
'brand': user_card_detail.brand,
'card_id': user_card_detail.card_id
}
- UserCardDetail.set_default_card(
- stripe_api_cus_id=stripe_api_cus_id,
- stripe_source_id=user_card_detail.card_id
+ if not user_card_detail.preferred:
+ UserCardDetail.set_default_card(
+ stripe_api_cus_id=stripe_api_cus_id,
+ stripe_source_id=user_card_detail.card_id
+ )
+ cpu = specs.get('cpu')
+ memory = specs.get('memory')
+ disk_size = specs.get('disk_size')
+ amount_to_be_charged = specs.get('price')
+ discount = specs.get('discount')
+ plan_name = StripeUtils.get_stripe_plan_name(
+ cpu=cpu,
+ memory=memory,
+ disk_size=disk_size,
+ price=amount_to_be_charged
+ )
+ stripe_plan_id = StripeUtils.get_stripe_plan_id(
+ cpu=cpu,
+ ram=memory,
+ ssd=disk_size,
+ version=1,
+ app='dcl',
+ price=amount_to_be_charged
+ )
+ stripe_plan = stripe_utils.get_or_create_stripe_plan(
+ amount=amount_to_be_charged,
+ name=plan_name,
+ stripe_plan_id=stripe_plan_id)
+ # Create StripeTaxRate if applicable to the user
+ stripe_tax_rate = None
+ if specs["vat_percent"] > 0:
+ try:
+ stripe_tax_rate = StripeTaxRate.objects.get(
+ description="VAT for %s" % specs["vat_country"]
+ )
+ print("Stripe Tax Rate exists")
+ except StripeTaxRate.DoesNotExist as dne:
+ print("StripeTaxRate does not exist")
+ tax_rate_obj = stripe.TaxRate.create(
+ display_name="VAT",
+ description="VAT for %s" % specs["vat_country"],
+ jurisdiction=specs["vat_country"],
+ percentage=specs["vat_percent"] * 100,
+ inclusive=False,
+ )
+ stripe_tax_rate = StripeTaxRate.objects.create(
+ display_name=tax_rate_obj.display_name,
+ description=tax_rate_obj.description,
+ jurisdiction=tax_rate_obj.jurisdiction,
+ percentage=tax_rate_obj.percentage,
+ inclusive=False,
+ tax_rate_id=tax_rate_obj.id
+ )
+ logger.debug("Created StripeTaxRate %s" %
+ stripe_tax_rate.tax_rate_id)
+ subscription_result = stripe_utils.subscribe_customer_to_plan(
+ stripe_api_cus_id,
+ [{"plan": stripe_plan.get('response_object').stripe_plan_id}],
+ coupon=(discount['stripe_coupon_id']
+ if 'name' in discount and
+ discount['name'] is not None and
+ 'ipv6' in discount['name'].lower() and
+ discount['stripe_coupon_id']
+ else ""),
+ tax_rates=[stripe_tax_rate.tax_rate_id] if stripe_tax_rate else [],
+ default_payment_method=request.session['id_payment_method']
+ )
+ stripe_subscription_obj = subscription_result.get('response_object')
+ latest_invoice = stripe.Invoice.retrieve(stripe_subscription_obj.latest_invoice)
+ ret = stripe.PaymentIntent.confirm(
+ latest_invoice.payment_intent
+ )
+ if ret.status == 'requires_source_action' or ret.status == 'requires_action':
+ pi = stripe.PaymentIntent.retrieve(
+ latest_invoice.payment_intent
)
- logger.debug("card_details_dict=%s" % card_details_dict)
- else:
+ context = {
+ 'sid': stripe_subscription_obj.id,
+ 'payment_intent_secret': pi.client_secret,
+ 'STRIPE_PUBLISHABLE_KEY': settings.STRIPE_API_PUBLIC_KEY,
+ 'showSCA': True
+ }
+ return JsonResponse(context)
+ # Check if the subscription was approved and is active
+ if (stripe_subscription_obj is None or
+ stripe_subscription_obj.status != 'active'):
+ # At this point, we have created a Stripe API card and
+ # associated it with the customer; but the transaction failed
+ # due to some reason. So, we would want to dissociate this card
+ # here.
+ # ...
+
+ msg = subscription_result.get('error')
+ messages.add_message(self.request, messages.ERROR, msg,
+ extra_tags='failed_payment')
response = {
'status': False,
'redirect': "{url}#{section}".format(
- url=reverse('datacenterlight:payment'),
+ url=reverse('hosting:payment'),
section='payment_error'),
'msg_title': str(_('Error.')),
'msg_body': str(
_('There was a payment related error.'
' On close of this popup, you will be redirected back to'
- ' the payment page.'))
+ ' the payment page.')
+ )
}
return JsonResponse(response)
- if ('generic_payment_type' in request.session and
- self.request.session['generic_payment_type'] == 'generic'):
- gp_details = self.request.session['generic_payment_details']
- logger.debug("gp_details=%s" % gp_details)
- if gp_details['recurring']:
- # generic recurring payment
- logger.debug("Commencing a generic recurring payment")
- if ('generic_payment_type' not in request.session or
- (request.session['generic_payment_details']['recurring'])):
- recurring_interval = 'month'
- logger.debug("'generic_payment_type' not in request.session or"
- "(request.session['generic_payment_details']['recurring']")
- if 'generic_payment_details' in request.session:
- vat_percent = request.session['generic_payment_details']['vat_rate']
- vat_country = request.session['generic_payment_details']['vat_country']
- if 'discount' in request.session['generic_payment_details']:
- discount = request.session['generic_payment_details']['discount']
- else:
- discount = {'name': '', 'amount': 0, 'coupon_id': ''}
- amount_to_be_charged = (
- round(
- request.session['generic_payment_details']['amount_before_vat'],
- 2
- )
- )
- plan_name = "generic-{0}-{1:.2f}".format(
- request.session['generic_payment_details']['product_id'],
- amount_to_be_charged
- )
- stripe_plan_id = plan_name
- recurring_interval = request.session['generic_payment_details']['recurring_interval']
- if recurring_interval == "year":
- plan_name = "{}-yearly".format(plan_name)
- stripe_plan_id = plan_name
- else:
- template = request.session.get('template')
- specs = request.session.get('specs')
- vm_template_id = template.get('id', 1)
-
- cpu = specs.get('cpu')
- memory = specs.get('memory')
- disk_size = specs.get('disk_size')
- amount_to_be_charged = specs.get('price')
- vat_percent = specs.get('vat_percent')
- vat_country = specs.get('vat_country')
- discount = specs.get('discount')
- plan_name = StripeUtils.get_stripe_plan_name(
- cpu=cpu,
- memory=memory,
- disk_size=disk_size,
- price=amount_to_be_charged
- )
- stripe_plan_id = StripeUtils.get_stripe_plan_id(
- cpu=cpu,
- ram=memory,
- ssd=disk_size,
- version=1,
- app='dcl',
- price=amount_to_be_charged
- )
- logger.debug(specs)
- stripe_plan = stripe_utils.get_or_create_stripe_plan(
- amount=amount_to_be_charged,
- name=plan_name,
- stripe_plan_id=stripe_plan_id,
- interval=recurring_interval
+ if 'token' in request.session:
+ ucd = UserCardDetail.get_or_create_user_card_detail(
+ stripe_customer=self.request.user.stripecustomer,
+ card_details=card_details_response
)
- # Create StripeTaxRate if applicable to the user
- logger.debug("vat_percent = %s, vat_country = %s" %
- (vat_percent, vat_country)
- )
- stripe_tax_rate = None
- if vat_percent > 0:
- try:
- stripe_tax_rate = StripeTaxRate.objects.get(
- description="VAT for %s" % vat_country
- )
- print("Stripe Tax Rate exists")
- except StripeTaxRate.DoesNotExist as dne:
- print("StripeTaxRate does not exist")
- tax_rate_obj = stripe.TaxRate.create(
- display_name="VAT",
- description="VAT for %s" % vat_country,
- jurisdiction=vat_country,
- percentage=vat_percent,
- inclusive=False,
- )
- stripe_tax_rate = StripeTaxRate.objects.create(
- display_name=tax_rate_obj.display_name,
- description=tax_rate_obj.description,
- jurisdiction=tax_rate_obj.jurisdiction,
- percentage=tax_rate_obj.percentage,
- inclusive=False,
- tax_rate_id=tax_rate_obj.id
- )
- logger.debug("Created StripeTaxRate %s" %
- stripe_tax_rate.tax_rate_id)
- subscription_result = stripe_utils.subscribe_customer_to_plan(
- stripe_api_cus_id,
- [{"plan": stripe_plan.get('response_object').stripe_plan_id}],
- coupon=(discount['stripe_coupon_id']
- if 'name' in discount and
- discount['name'] is not None and
- 'ipv6' in discount['name'].lower() and
- discount['stripe_coupon_id']
- else ""),
- tax_rates=[stripe_tax_rate.tax_rate_id] if stripe_tax_rate else [],
- default_payment_method=request.session['id_payment_method']
+ UserCardDetail.save_default_card_local(
+ self.request.user.stripecustomer.stripe_id,
+ ucd.card_id
)
- stripe_subscription_obj = subscription_result.get('response_object')
- logger.debug(stripe_subscription_obj)
- latest_invoice = stripe.Invoice.retrieve(
- stripe_subscription_obj.latest_invoice)
- subscription_status = ''
- if stripe_subscription_obj:
- subscription_status = stripe_subscription_obj.status
+ user = {
+ 'name': self.request.user.name,
+ 'email': self.request.user.email,
+ 'username': self.request.user.username,
+ 'pass': self.request.user.password,
+ 'request_scheme': request.scheme,
+ 'request_host': request.get_host(),
+ 'language': get_language(),
+ }
- # Check if the subscription was approved and is active
- if (stripe_subscription_obj is None
- or (stripe_subscription_obj.status != 'active'
- and stripe_subscription_obj.status != 'incomplete')):
- # At this point, we have created a Stripe API card and
- # associated it with the customer; but the transaction failed
- # due to some reason. So, we would want to dissociate this card
- # here.
- # ...
- msg = subscription_result.get('error')
- return show_error(msg, self.request)
- elif stripe_subscription_obj.status == 'incomplete':
- # Store params so that they can be retrieved later
- IncompleteSubscriptions.objects.create(
- subscription_id=stripe_subscription_obj.id,
- subscription_status=subscription_status,
- name=user.get('name'),
- email=user.get('email'),
- request=json.dumps(req),
- stripe_api_cus_id=stripe_api_cus_id,
- card_details_response=json.dumps(card_details_response),
- stripe_subscription_obj=json.dumps(
- stripe_subscription_obj) if stripe_customer_obj else '',
- stripe_onetime_charge=json.dumps(
- stripe_onetime_charge) if stripe_onetime_charge else '',
- gp_details=json.dumps(gp_details) if gp_details else '',
- specs=json.dumps(specs) if specs else '',
- vm_template_id=vm_template_id if vm_template_id else 0,
- template=json.dumps(template) if template else '',
- billing_address_data=json.dumps(
- request.session.get('billing_address_data')
- )
- )
- pi = stripe.PaymentIntent.retrieve(
- latest_invoice.payment_intent
- )
- # TODO: requires_attention is probably wrong value to compare
- if request.user.is_authenticated():
- if 'generic_payment_details' in request.session:
- redirect_url = reverse('hosting:invoices')
- else:
- redirect_url = reverse('hosting:virtual_machines')
- else:
- redirect_url = reverse('datacenterlight:index')
-
- if (pi.status == 'requires_attention' or
- pi.status == 'requires_source_action'):
- logger.debug("Display SCA authentication %s " % pi.status)
- context = {
- 'sid': stripe_subscription_obj.id,
- 'payment_intent_secret': pi.client_secret,
- 'STRIPE_PUBLISHABLE_KEY': settings.STRIPE_API_PUBLIC_KEY,
- 'showSCA': True,
- 'success': {
- 'status': True,
- 'redirect': redirect_url,
- 'msg_title': str(_('Thank you for the order.')),
- 'msg_body': str(
- _('Your product will be provisioned as soon as'
- ' we receive a payment confirmation from '
- 'Stripe. We will send you a confirmation '
- 'email. You can always contact us at '
- 'support@datacenterlight.ch')
- )
- },
- 'error': {
- 'status': False,
- 'redirect': "{url}#{section}".format(
- url=(reverse(
- 'show_product',
- kwargs={'product_slug':
- request.session[
- 'generic_payment_details']
- ['product_slug']}
- ) if 'generic_payment_details' in request.session else
- reverse('datacenterlight:payment')
- ),
- section='payment_error'
- ),
- 'msg_title': str(_('Error.')),
- 'msg_body': str(
- _('There was a payment related error.'
- ' On close of this popup, you will be redirected back to'
- ' the payment page.')
- )
- }
- }
- return JsonResponse(context)
- else:
- logger.debug(
- "Handle this case when "
- "stripe.subscription_status is incomplete but "
- "pi.status is neither requires_attention nor "
- "requires_source_action")
- msg = subscription_result.get('error')
- return show_error(msg, self.request)
- # the code below is executed for
- # a) subscription case
- # b) the subscription object is active itself, without requiring
- # SCA
- # provisioning_response = do_provisioning(
- # req, stripe_api_cus_id,
- # card_details_response, stripe_subscription_obj,
- # stripe_onetime_charge, gp_details, specs, vm_template_id,
- # template, request.session.get('billing_address_data'),
- # self.request
- # )
-
- if (provisioning_response and
- type(provisioning_response['response']) == JsonResponse):
- new_user = provisioning_response.get('user', None)
- if new_user:
- login(self.request, new_user)
- return provisioning_response['response']
+ create_vm(
+ billing_address_data, stripe_customer_id, specs,
+ stripe_subscription_obj, card_details_dict, request,
+ vm_template_id, template, user
+ )
response = {
'status': True,
- 'redirect': (
- reverse('hosting:virtual_machines')
- if request.user.is_authenticated()
- else reverse('datacenterlight:index')
- ),
+ 'redirect': reverse('hosting:virtual_machines'),
'msg_title': str(_('Thank you for the order.')),
'msg_body': str(
_('Your VM will be up and running in a few moments.'
@@ -1248,3 +1276,749 @@ class OrderConfirmationView(DetailView, FormView):
}
return JsonResponse(response)
+
+
+class OrdersHostingListView(LoginRequiredMixin, ListView):
+ template_name = "hosting/orders.html"
+ login_url = reverse_lazy('hosting:login')
+ context_object_name = "orders"
+ model = HostingOrder
+ paginate_by = 10
+ ordering = '-id'
+
+ def get_queryset(self):
+ user = self.request.user
+ self.queryset = HostingOrder.objects.filter(customer__user=user)
+ return super(OrdersHostingListView, self).get_queryset()
+
+ @method_decorator(decorators)
+ def get(self, request, *args, **kwargs):
+ return super(OrdersHostingListView, self).get(request, *args, **kwargs)
+
+
+class InvoiceListView(LoginRequiredMixin, TemplateView):
+ template_name = "hosting/invoices.html"
+ login_url = reverse_lazy('hosting:login')
+ context_object_name = "invoices"
+ paginate_by = 10
+ ordering = '-created'
+
+ def get_context_data(self, **kwargs):
+ page = self.request.GET.get('page', 1)
+ context = super(InvoiceListView, self).get_context_data(**kwargs)
+ invs_page = None
+ invs_page_charges = None
+ if ('user_email' in self.request.GET
+ and self.request.user.email == settings.ADMIN_EMAIL):
+ user_email = self.request.GET['user_email']
+ context['user_email'] = '%s' % quote(user_email)
+ logger.debug(
+ "user_email = {}".format(user_email)
+ )
+ try:
+ cu = CustomUser.objects.get(email=user_email)
+ except CustomUser.DoesNotExist as dne:
+ logger.debug("User does not exist")
+ cu = self.request.user
+ invs = stripe.Invoice.list(customer=cu.stripecustomer.stripe_id,
+ count=100,
+ status='paid')
+ paginator = Paginator(invs.data, 10)
+ try:
+ invs_page = paginator.page(page)
+ except PageNotAnInteger:
+ invs_page = paginator.page(1)
+ except EmptyPage:
+ invs_page = paginator.page(paginator.num_pages)
+ hosting_orders = HostingOrder.objects.filter(
+ customer=cu.stripecustomer).filter(
+ Q(subscription_id=None) | Q(subscription_id='')
+ ).order_by('-created_at')
+ stripe_chgs = []
+ for ho in hosting_orders:
+ stripe_chgs.append({ho.id: stripe.Charge.retrieve(ho.stripe_charge_id)})
+
+ paginator_charges = Paginator(stripe_chgs, 10)
+ try:
+ invs_page_charges = paginator_charges.page(page)
+ except PageNotAnInteger:
+ invs_page_charges = paginator_charges.page(1)
+ except EmptyPage:
+ invs_page_charges = paginator_charges.page(paginator_charges.num_pages)
+ else:
+ try:
+ invs = stripe.Invoice.list(
+ customer=self.request.user.stripecustomer.stripe_id,
+ count=100
+ )
+ paginator = Paginator(invs.data, 10)
+ try:
+ invs_page = paginator.page(page)
+ except PageNotAnInteger:
+ invs_page = paginator.page(1)
+ except EmptyPage:
+ invs_page = paginator.page(paginator.num_pages)
+ hosting_orders = HostingOrder.objects.filter(
+ customer=self.request.user.stripecustomer).filter(
+ Q(subscription_id=None) | Q(subscription_id='')
+ ).order_by('-created_at')
+ stripe_chgs = []
+ for ho in hosting_orders:
+ stripe_chgs.append(
+ {ho: stripe.Charge.retrieve(ho.stripe_charge_id)})
+ paginator_charges = Paginator(stripe_chgs, 10)
+ try:
+ invs_page_charges = paginator_charges.page(page)
+ except PageNotAnInteger:
+ invs_page_charges = paginator_charges.page(1)
+ except EmptyPage:
+ invs_page_charges = paginator_charges.page(
+ paginator_charges.num_pages)
+ except Exception as ex:
+ logger.error(str(ex))
+ invs_page = None
+ context["invs"] = invs_page
+ context["invs_charge"] = invs_page_charges
+ return context
+
+ @method_decorator(decorators)
+ def get(self, request, *args, **kwargs):
+ return super(InvoiceListView, self).get(request, *args, **kwargs)
+
+
+class InvoiceDetailView(LoginRequiredMixin, DetailView):
+ template_name = "hosting/invoice_detail.html"
+ context_object_name = "invoice"
+ login_url = reverse_lazy('hosting:login')
+ permission_required = ['view_monthlyhostingbill']
+ # model = MonthlyHostingBill
+
+ def get_object(self, queryset=None):
+ invoice_id = self.kwargs.get('invoice_id')
+ try:
+ invoice_obj = MonthlyHostingBill.objects.get(
+ invoice_number=invoice_id
+ )
+ logger.debug("Found MHB for id {invoice_id}".format(
+ invoice_id=invoice_id
+ ))
+ if self.request.user.has_perm(
+ self.permission_required[0], invoice_obj
+ ) or self.request.user.email == settings.ADMIN_EMAIL:
+ logger.debug("User has permission to invoice_obj")
+ else:
+ logger.error("User does not have permission to access")
+ invoice_obj = None
+ except MonthlyHostingBill.DoesNotExist as dne:
+ logger.debug("MHB not found for id {invoice_id}".format(
+ invoice_id=invoice_id
+ ))
+ invoice_obj = None
+ return invoice_obj
+
+ def get_context_data(self, **kwargs):
+ # Get context
+ context = super(InvoiceDetailView, self).get_context_data(**kwargs)
+ obj = self.get_object()
+
+ if obj is not None:
+ vm_id = obj.get_vm_id()
+ try:
+ # Try to get vm details from database
+ vm_detail = VMDetail.objects.get(vm_id=vm_id)
+ context['vm'] = vm_detail.__dict__
+ context['vm']['name'] = '{}-{}'.format(
+ context['vm']['configuration'], context['vm']['vm_id'])
+ user_vat_country = obj.order.billing_address.country
+ user_country_vat_rate = get_vat_rate_for_country(
+ user_vat_country)
+ price, vat, vat_percent, discount = get_vm_price_for_given_vat(
+ cpu=context['vm']['cores'],
+ ssd_size=context['vm']['disk_size'],
+ memory=context['vm']['memory'],
+ pricing_name=(obj.order.vm_pricing.name
+ if obj.order.vm_pricing else 'default'),
+ vat_rate=(
+ user_country_vat_rate * 100
+ if obj.order.vm_id >= settings.FIRST_VM_ID_AFTER_EU_VAT
+ else settings.PRE_EU_VAT_RATE
+ )
+ )
+ context['vm']["after_eu_vat_intro"] = (
+ True if obj.order.vm_id >= settings.FIRST_VM_ID_AFTER_EU_VAT
+ else False
+ )
+ context['vm']["price"] = price
+ context['vm']["vat"] = vat
+ context['vm']["vat_percent"] = vat_percent
+ context['vm']["vat_country"] = user_vat_country
+ context['vm']["discount"] = discount
+ context['vm']["total_price"] = round(
+ price + vat - discount['amount'], 2)
+ except VMDetail.DoesNotExist:
+ # fallback to get it from the infrastructure
+ try:
+ manager = OpenNebulaManager(
+ email=self.request.user.username,
+ password=self.request.user.password
+ )
+ vm = manager.get_vm(vm_id)
+ context['vm'] = VirtualMachineSerializer(vm).data
+ user_vat_country = obj.order.billing_address.country
+ user_country_vat_rate = get_vat_rate_for_country(
+ user_vat_country)
+ price, vat, vat_percent, discount = get_vm_price_for_given_vat(
+ cpu=context['vm']['cores'],
+ ssd_size=context['vm']['disk_size'],
+ memory=context['vm']['memory'],
+ pricing_name=(obj.order.vm_pricing.name
+ if obj.order.vm_pricing else 'default'),
+ vat_rate=(
+ user_country_vat_rate * 100
+ if obj.order.vm_id >= settings.FIRST_VM_ID_AFTER_EU_VAT
+ else settings.PRE_EU_VAT_RATE
+ )
+ )
+ context['vm']["after_eu_vat_intro"] = (
+ True if obj.order.vm_id >= settings.FIRST_VM_ID_AFTER_EU_VAT
+ else False
+ )
+ context['vm']["price"] = price
+ context['vm']["vat"] = vat
+ context['vm']["vat_percent"] = vat_percent
+ context['vm']["vat_country"] = user_vat_country
+ context['vm']["discount"] = discount
+ context['vm']["total_price"] = round(
+ price + vat - discount['amount'], 2)
+ except TypeError:
+ logger.error("Type error. Probably we "
+ "came from a generic product. "
+ "Invoice ID %s" % obj.invoice_id)
+ except WrongIdError:
+ logger.error("WrongIdError while accessing "
+ "invoice {}".format(obj.invoice_id))
+ messages.error(
+ self.request,
+ _('The VM you are looking for is unavailable at the '
+ 'moment. Please contact Data Center Light support.')
+ )
+ self.kwargs['error'] = 'WrongIdError'
+ context['error'] = 'WrongIdError'
+ return context
+
+ # add context params from monthly hosting bill
+ context['period_start'] = obj.get_period_start()
+ context['period_end'] = obj.get_period_end()
+ context['paid_at'] = obj.paid_at
+ context['total_in_chf'] = obj.total_in_chf()
+ context['invoice_number'] = obj.invoice_number
+ context['discount_on_stripe'] = obj.discount_in_chf()
+ if obj.lines_data_count > 1:
+ # special case, we pass the details of each of the line items
+ context['line_items'] = obj.hostingbilllineitem_set.all()
+ return context
+ else:
+ raise Http404
+
+ @method_decorator(decorators)
+ def get(self, request, *args, **kwargs):
+ self.object = self.get_object()
+ context = self.get_context_data(object=self.get_object())
+ return self.render_to_response(context)
+
+
+class OrdersHostingDeleteView(LoginRequiredMixin, DeleteView):
+ login_url = reverse_lazy('hosting:login')
+ success_url = reverse_lazy('hosting:orders')
+ model = HostingOrder
+
+
+class VirtualMachinesPlanListView(LoginRequiredMixin, ListView):
+ template_name = "hosting/virtual_machines.html"
+ login_url = reverse_lazy('hosting:login')
+ context_object_name = "vms"
+ paginate_by = 10
+ ordering = '-id'
+
+ def get_queryset(self):
+ owner = self.request.user
+ manager = OpenNebulaManager(email=owner.username,
+ password=owner.password)
+ try:
+ queryset = manager.get_vms()
+ serializer = VirtualMachineSerializer(queryset, many=True)
+ return serializer.data
+ except ConnectionRefusedError:
+ messages.error(self.request,
+ 'We could not load your VMs due to a backend connection \
+ error. Please try again in a few minutes'
+ )
+
+ self.kwargs['error'] = 'connection'
+ return []
+
+ def get_context_data(self, **kwargs):
+ error = self.kwargs.get('error')
+ if error is not None:
+ print(error)
+ context = {'error': 'connection'}
+ else:
+ context = super(ListView, self).get_context_data(**kwargs)
+ if UserHostingKey.objects.filter(user=self.request.user).exists():
+ context['show_create_ssh_key_msg'] = False
+ else:
+ context['show_create_ssh_key_msg'] = True
+ return context
+
+
+class CreateVirtualMachinesView(LoginRequiredMixin, View):
+ template_name = "hosting/create_virtual_machine.html"
+ login_url = reverse_lazy('hosting:login')
+
+ def validate_cores(self, value):
+ if (value > 48) or (value < 1):
+ raise ValidationError(_('Invalid number of cores'))
+
+ def validate_memory(self, value):
+ if 'pid' in self.request.POST:
+ try:
+ plugin = DCLCalculatorPluginModel.objects.get(
+ id=self.request.POST['pid']
+ )
+ except DCLCalculatorPluginModel.DoesNotExist as dne:
+ logger.error(
+ str(dne) + " plugin_id: " + self.request.POST['pid']
+ )
+ raise ValidationError(_('Invalid calculator properties'))
+ if plugin.enable_512mb_ram:
+ if value % 1 == 0 or value == 0.5:
+ logger.debug(
+ "Given ram {value} is either 0.5 or a"
+ " whole number".format(value=value)
+ )
+ if (value > 200) or (value < 0.5):
+ raise ValidationError(_('Invalid RAM size'))
+ else:
+ raise ValidationError(_('Invalid RAM size'))
+ elif (value > 200) or (value < 1) or (value % 1 != 0):
+ raise ValidationError(_('Invalid RAM size'))
+ else:
+ raise ValidationError(_('Invalid RAM size'))
+
+ def validate_storage(self, value):
+ if (value > 2000) or (value < 10):
+ raise ValidationError(_('Invalid storage size'))
+
+ @method_decorator(decorators)
+ def get(self, request, *args, **kwargs):
+ context = {
+ 'templates': VMTemplate.objects.all(),
+ 'cms_integration': get_cms_integration('default'),
+ }
+ return render(request, self.template_name, context)
+
+ @method_decorator(decorators)
+ def post(self, request):
+ cores = request.POST.get('cpu')
+ cores_field = forms.IntegerField(validators=[self.validate_cores])
+ memory = request.POST.get('ram')
+ memory_field = forms.FloatField(validators=[self.validate_memory])
+ storage = request.POST.get('storage')
+ storage_field = forms.IntegerField(validators=[self.validate_storage])
+ template_id = int(request.POST.get('config'))
+ pricing_name = request.POST.get('pricing_name')
+ vm_pricing = VMPricing.get_vm_pricing_by_name(pricing_name)
+ template = VMTemplate.objects.filter(
+ opennebula_vm_template_id=template_id).first()
+ template_data = VMTemplateSerializer(template).data
+
+ if vm_pricing is None:
+ vm_pricing_name_msg = _(
+ "Incorrect pricing name. Please contact support"
+ "{support_email}".format(
+ support_email=settings.DCL_SUPPORT_FROM_ADDRESS
+ )
+ )
+ messages.add_message(
+ self.request, messages.ERROR, vm_pricing_name_msg,
+ extra_tags='pricing'
+ )
+ return redirect(CreateVirtualMachinesView.as_view())
+ else:
+ vm_pricing_name = vm_pricing.name
+
+ try:
+ cores = cores_field.clean(cores)
+ except ValidationError as err:
+ msg = '{} : {}.'.format(cores, str(err))
+ messages.add_message(self.request, messages.ERROR, msg,
+ extra_tags='cores')
+ return redirect(CreateVirtualMachinesView.as_view())
+
+ try:
+ memory = memory_field.clean(memory)
+ except ValidationError as err:
+ msg = '{} : {}.'.format(memory, str(err))
+ messages.add_message(self.request, messages.ERROR, msg,
+ extra_tags='memory')
+ return redirect(CreateVirtualMachinesView.as_view())
+
+ try:
+ storage = storage_field.clean(storage)
+ except ValidationError as err:
+ msg = '{} : {}.'.format(storage, str(err))
+ messages.add_message(self.request, messages.ERROR, msg,
+ extra_tags='storage')
+ return redirect(CreateVirtualMachinesView.as_view())
+
+ price, vat, vat_percent, discount = get_vm_price_with_vat(
+ cpu=cores,
+ memory=memory,
+ ssd_size=storage,
+ pricing_name=vm_pricing_name
+ )
+
+ specs = {
+ 'cpu': cores,
+ 'memory': memory,
+ 'disk_size': storage,
+ 'discount': discount,
+ 'price': price,
+ 'vat': vat,
+ 'vat_percent': vat_percent,
+ 'total_price': round(price + vat - discount['amount'], 2),
+ 'pricing_name': vm_pricing_name
+ }
+
+ request.session['specs'] = specs
+ request.session['template'] = template_data
+ return redirect(reverse('hosting:payment'))
+
+
+class VirtualMachineView(LoginRequiredMixin, View):
+ template_name = "hosting/virtual_machine_detail.html"
+ login_url = reverse_lazy('hosting:login')
+
+ def get_object(self):
+ owner = self.request.user
+ vm = None
+ manager = OpenNebulaManager(
+ email=owner.username,
+ password=owner.password
+ )
+ vm_id = self.kwargs.get('pk')
+ try:
+ vm = manager.get_vm(vm_id)
+ return vm
+ except WrongIdError:
+ messages.error(self.request,
+ _('We could not find the requested VM. Please \
+ contact Data Center Light Support.')
+ )
+ return None
+ except ConnectionRefusedError:
+ messages.error(self.request,
+ 'We could not load your VM due to a backend connection \
+ error. Please try again in a few minutes'
+ )
+ return None
+ except Exception as error:
+ logger.error(str(error))
+ raise Http404()
+
+ def get_success_url(self):
+ final_url = reverse('hosting:virtual_machines')
+ return final_url
+
+ @method_decorator(decorators)
+ def get(self, request, *args, **kwargs):
+ vm = self.get_object()
+ if vm is None:
+ if self.request.is_ajax():
+ storage = messages.get_messages(request)
+ for m in storage:
+ pass
+ storage.used = True
+ return JsonResponse({'text': _('Terminated')})
+ else:
+ return redirect(reverse('hosting:virtual_machines'))
+ elif self.request.is_ajax():
+ return HttpResponse()
+ context = None
+ try:
+ serializer = VirtualMachineSerializer(vm)
+ hosting_order = HostingOrder.objects.get(
+ vm_id=serializer.data['vm_id']
+ )
+ inv_url = None
+ if hosting_order.subscription_id:
+ stripe_obj = stripe.Invoice.list(
+ subscription=hosting_order.subscription_id,
+ count=1
+ )
+ inv_url = stripe_obj.data[0].hosted_invoice_url
+ elif hosting_order.stripe_charge_id:
+ stripe_obj = stripe.Charge.retrieve(
+ hosting_order.stripe_charge_id
+ )
+ inv_url = stripe_obj.receipt_url
+ context = {
+ 'virtual_machine': serializer.data,
+ 'order': hosting_order,
+ 'keys': UserHostingKey.objects.filter(user=request.user),
+ 'inv_url': inv_url
+ }
+
+ except Exception as ex:
+ logger.debug("Exception generated {}".format(str(ex)))
+ messages.error(self.request,
+ _('We could not find the requested VM. Please '
+ 'contact Data Center Light Support.')
+ )
+ return redirect(reverse('hosting:virtual_machines'))
+
+ return render(request, self.template_name, context)
+
+ @method_decorator(decorators)
+ def post(self, request, *args, **kwargs):
+ response = {'status': False}
+ admin_email_body = {}
+ owner = self.request.user
+ vm = self.get_object()
+
+ manager = OpenNebulaManager(
+ email=owner.username,
+ password=owner.password
+ )
+ try:
+ vm_data = VirtualMachineSerializer(manager.get_vm(vm.id)).data
+ vm_name = vm_data.get('name')
+ except WrongIdError as wrong_id_err:
+ logger.error(str(wrong_id_err))
+ return redirect(reverse('hosting:virtual_machines'))
+
+ # Cancel Stripe subscription
+ stripe_utils = StripeUtils()
+ hosting_order = None
+ stripe_subscription_obj = None
+ try:
+ hosting_order = HostingOrder.objects.get(
+ vm_id=vm.id
+ )
+ result = stripe_utils.unsubscribe_customer(
+ subscription_id=hosting_order.subscription_id
+ )
+ stripe_subscription_obj = result.get('response_object')
+ # Check if the subscription was canceled
+ if (stripe_subscription_obj is None or
+ stripe_subscription_obj.status != 'canceled'):
+ error_msg = result.get('error')
+ logger.error(
+ 'Error canceling subscription for {user} and vm id '
+ '{vm_id}'.format(user=owner.username, vm_id=vm.id)
+ )
+ logger.error(error_msg)
+ admin_email_body['stripe_error_msg'] = error_msg
+ except HostingOrder.DoesNotExist:
+ error_msg = (
+ "HostingOrder corresponding to vm_id={vm_id} does"
+ "not exist. Hence, can not find subscription to "
+ "cancel ".format(vm_id=vm.id)
+ )
+ logger.error(error_msg)
+ admin_email_body['stripe_error_msg'] = error_msg
+
+ terminated = manager.delete_vm(vm.id)
+
+ if not terminated:
+ logger.error(
+ "manager.delete_vm returned False. Hence, error making "
+ "xml-rpc call to delete vm failed."
+ )
+ response['text'] = str(_('Error terminating VM')) + str(vm.id)
+ else:
+ for t in range(settings.MAX_TIME_TO_WAIT_FOR_VM_TERMINATE):
+ try:
+ manager.get_vm(vm.id)
+ except WrongIdError:
+ logger.error(
+ "VM {} not found. So, its terminated.".format(vm.id)
+ )
+ response['status'] = True
+ response['text'] = ugettext('Terminated')
+ vm_detail_obj = VMDetail.objects.filter(
+ vm_id=vm.id
+ ).first()
+ vm_detail_obj.terminated_at = datetime.utcnow()
+ vm_detail_obj.save()
+ except BaseException as base_exception:
+ logger.error(
+ "manager.get_vm({vm_id}) returned exception: "
+ "{details}.".format(
+ details=str(base_exception), vm_id=vm.id
+ )
+ )
+ break
+ else:
+ logger.debug(
+ 'Sleeping 2 seconds for terminate action on VM %s' %
+ vm.id
+ )
+ sleep(2)
+ if not response['status']:
+ response['text'] = str(_("VM terminate action timed out. "
+ "Please contact "
+ "support@datacenterlight.ch for "
+ "further information."))
+ context = {
+ 'vm_name': vm_name,
+ 'base_url': "{0}://{1}".format(
+ self.request.scheme, self.request.get_host()
+ ),
+ 'page_header': _('Virtual Machine %(vm_name)s Cancelled') % {
+ 'vm_name': vm_name
+ }
+ }
+ email_data = {
+ 'subject': context['page_header'],
+ 'to': self.request.user.email,
+ 'context': context,
+ 'template_name': 'vm_canceled',
+ 'template_path': 'hosting/emails/',
+ 'from_address': settings.DCL_SUPPORT_FROM_ADDRESS,
+ }
+ email = BaseEmail(**email_data)
+ email.send()
+ admin_email_body.update(response)
+ admin_email_body["customer_email"] = owner.email
+ admin_email_body["customer_username"] = owner.username
+ admin_email_body["VM_ID"] = vm.id
+ admin_email_body["VM_created_at"] = (str(hosting_order.created_at) if
+ hosting_order is not None
+ else "unknown")
+ content = ""
+ total_amount = 0
+ if stripe_subscription_obj:
+ for line_item in stripe_subscription_obj["items"]["data"]:
+ total_amount += (line_item["quantity"] *
+ line_item.plan["amount"])
+ content += " %s => %s x %s => %s\n" % (
+ line_item.plan["name"], line_item["quantity"],
+ line_item.plan["amount"]/100,
+ (line_item["quantity"] * line_item.plan["amount"])/100
+ )
+ admin_email_body["subscription_amount"] = total_amount/100
+ admin_email_body["subscription_detail"] = content
+ admin_msg_sub = "VM and Subscription for VM {} and user: {}, {}".format(
+ vm.id,
+ owner.email, owner.username
+ )
+ email_to_admin_data = {
+ 'subject': ("Deleted " if response['status']
+ else "ERROR deleting ") + admin_msg_sub,
+ 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
+ 'to': ['dcl-orders@ungleich.ch'],
+ 'body': "\n".join(
+ ["%s=%s" % (k, v) for (k, v) in admin_email_body.items()]),
+ }
+ send_plain_email_task.delay(email_to_admin_data)
+ return JsonResponse(response)
+
+
+class HostingBillListView(PermissionRequiredMixin, LoginRequiredMixin,
+ ListView):
+ template_name = "hosting/bills.html"
+ login_url = reverse_lazy('hosting:login')
+ permission_required = ['view_hostingview']
+ context_object_name = "users"
+ model = StripeCustomer
+ paginate_by = 10
+ ordering = '-id'
+
+
+class HostingBillDetailView(PermissionRequiredMixin, LoginRequiredMixin,
+ DetailView):
+ template_name = "hosting/bill_detail.html"
+ login_url = reverse_lazy('hosting:login')
+ permission_required = ['view_hostingview']
+ context_object_name = "bill"
+ model = HostingBill
+
+ def get_object(self, queryset=None):
+ # Get HostingBill for primary key (Select from customer users)
+ pk = self.kwargs['pk']
+ object = HostingBill.objects.filter(customer__id=pk).first()
+ if object is None:
+ self.template_name = 'hosting/bill_error.html'
+ return object
+
+ def get_context_data(self, **kwargs):
+ # Get context
+ context = super(DetailView, self).get_context_data(**kwargs)
+
+ owner = self.request.user
+ manager = OpenNebulaManager(email=owner.username,
+ password=owner.password)
+ # Get vms
+ queryset = manager.get_vms()
+ vms = VirtualMachineSerializer(queryset, many=True).data
+ # Set total price
+ bill = context['bill']
+ bill.total_price = 0.0
+ for vm in vms:
+ bill.total_price += vm['price']
+ context['vms'] = vms
+ return context
+
+
+def forbidden_view(request, exception=None, reason=''):
+ """
+ Handle 403 error
+ """
+ logger.error(str(exception) if exception else None)
+ logger.error('Reason = {reason}'.format(reason=reason))
+ err_msg = _('There was an error processing your request. Please try '
+ 'again.')
+ messages.add_message(request, messages.ERROR, err_msg)
+ return HttpResponseRedirect(request.get_full_path())
+
+
+# class CheckUserVM(APIView):
+# renderer_classes = (JSONRenderer, )
+#
+# def get(self, request):
+# try:
+# email = request.data['email']
+# ip = request.data['ip']
+# user = request.data['user']
+# realm = request.data['realm']
+# token = request.data['token']
+# if realm != settings.READ_VM_REALM:
+# return Response("User not allowed", 403)
+# response = check_otp(user, realm, token)
+# if response != 200:
+# return Response('Invalid token', 403)
+# manager = OpenNebulaManager(settings.OPENNEBULA_USERNAME,
+# settings.OPENNEBULA_PASSWORD)
+# # not the best way to lookup vms ip
+# # TODO: make this optimal
+# vms = manager.get_vms()
+# users_vms = [vm for vm in vms if vm.uname == email]
+# if len(users_vms) == 0:
+# return Response('No VM found with the given email address',
+# 404)
+# for vm in users_vms:
+# for nic in vm.template.nics:
+# if hasattr(nic, 'ip6_global'):
+# if nic.ip6_global == ip:
+# return Response('success', 200)
+# elif hasattr(nic, 'ip'):
+# if nic.ip == ip:
+# return Response('success', 200)
+# return Response('No VM found matching the ip address provided', 404)
+# except KeyError:
+# return Response('Not enough data provided', 400)
+
+
+class CustomLogoutView(LogoutView):
+ next_page = reverse_lazy('hosting:login')
diff --git a/membership/__init__.py b/membership/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/membership/admin.py b/membership/admin.py
new file mode 100755
index 0000000..3aefa78
--- /dev/null
+++ b/membership/admin.py
@@ -0,0 +1,104 @@
+from django import forms
+from django.contrib import admin
+from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
+from django.contrib.auth.forms import ReadOnlyPasswordHashField
+
+from .models import CustomUser, StripeCustomer
+
+
+# Refer https://docs.djangoproject.com/en/2.0/topics/auth/customizing/
+# for understanding custom auth user model
+
+
+class UserCreationForm(forms.ModelForm):
+ """A form for creating new users. Includes all the required
+ fields, plus a repeated password."""
+ password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
+ password2 = forms.CharField(label='Password confirmation',
+ widget=forms.PasswordInput)
+
+ class Meta:
+ model = CustomUser
+ fields = ('email', 'user_permissions', 'email', 'is_admin')
+
+ def clean_password2(self):
+ # Check that the two password entries match
+ password1 = self.cleaned_data.get("password1")
+ password2 = self.cleaned_data.get("password2")
+ if password1 and password2 and password1 != password2:
+ raise forms.ValidationError("Passwords don't match")
+ return password2
+
+ def save(self, commit=True):
+ # Save the provided password in hashed format
+ user = super().save(commit=False)
+ user.set_password(self.cleaned_data["password1"])
+ if commit:
+ user.save()
+ return user
+
+
+class UserChangeForm(forms.ModelForm):
+ """A form for updating users. Includes all the fields on
+ the user, but replaces the password field with admin's
+ password hash display field.
+ """
+ password = ReadOnlyPasswordHashField(
+ label="Password",
+ help_text=(
+ "Raw passwords are not stored, so there is no way to see "
+ "this user's password, but you can change the password "
+ "using
this form .")
+ )
+
+ class Meta:
+ model = CustomUser
+ fields = ('email', 'password', 'is_admin')
+
+ def clean_password(self):
+ # Regardless of what the user provides, return the initial value.
+ # This is done here, rather than on the field, because the
+ # field does not have access to the initial value
+ return self.initial["password"]
+
+
+class CustomUserAdmin(BaseUserAdmin):
+ # The forms to add and change user instances
+ form = UserChangeForm
+ add_form = UserCreationForm
+
+ # The fields to be used in displaying the User model.
+ # These override the definitions on the base UserAdmin
+ # that reference specific fields on auth.User.
+ list_display = (
+ 'email', 'is_admin', 'is_superuser'
+ )
+ list_filter = ()
+ fieldsets = (
+ (None, {'fields': ('email',)}),
+ ('Change Password',
+ {'fields': ('password',),
+ 'description': "Raw passwords are not stored, so there is no way to "
+ "see this user's password, but you can change the "
+ "password using
this "
+ "form ."
+ }
+ ),
+ ('Permissions', {'fields': ('is_admin', 'user_permissions',
+ 'groups')}),
+ )
+ # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
+ # overrides get_fieldsets to use this attribute when creating a user.
+ add_fieldsets = (
+ (None, {
+ 'classes': ('wide',),
+ 'fields': ('email', 'password1', 'password2')}
+ ),
+ )
+ search_fields = ('email',)
+ ordering = ('email',)
+ filter_horizontal = ()
+
+
+admin.site.register(CustomUser, CustomUserAdmin)
+admin.site.register(StripeCustomer)
diff --git a/membership/calendar/__init__.py b/membership/calendar/__init__.py
new file mode 100755
index 0000000..6a4085f
--- /dev/null
+++ b/membership/calendar/__init__.py
@@ -0,0 +1 @@
+__author__ = 'tomislav'
diff --git a/membership/calendar/calendar.py b/membership/calendar/calendar.py
new file mode 100755
index 0000000..ae4428f
--- /dev/null
+++ b/membership/calendar/calendar.py
@@ -0,0 +1,136 @@
+from calendar import month_name, day_abbr
+from calendar import Calendar
+from membership.models import Calendar as CalendarModel
+import datetime
+
+now = datetime.datetime.now()
+
+
+class CustomCalendar(Calendar):
+ def __init__(self):
+ super(CustomCalendar, self).__init__(firstweekday=0)
+
+ def itermonthdays(self, year, month):
+ """
+ Like itermonthdates(), but will yield day numbers. For days outside
+ the specified month the day number.
+ """
+ for date in self.itermonthdates(year, month):
+ yield date.day
+
+ def itermonthdays2(self, year, month):
+ """
+ Like itermonthdates(), but will yield (day number, weekday number)
+ tuples. For days outside the specified month the day number is 0.
+ """
+ for date in self.itermonthdates(year, month):
+ yield (date.day, date.weekday(), date.month)
+
+
+class CustomHTMLCalendar(CustomCalendar):
+ """
+ This calendar returns complete HTML pages.
+ """
+
+ # CSS classes for the day
s
+
+ def __init__(self, requested_month):
+ self.requested_month = requested_month
+ super(CustomHTMLCalendar, self).__init__()
+
+ def formatday(self, day, weekday, month=None, year=None):
+ """
+ Return a day as a table cell.
+ """
+
+ booked = CalendarModel.objects.filter(user_id=self.user.id)
+ is_booked = booked.filter(datebooked=datetime.date(day=day, month=month, year=year))
+
+ if month < int(self.requested_month):
+ return ' %d ' % ("selected" if is_booked else "", day)
+ elif month > int(self.requested_month):
+ return '
%d ' % ("selected" if is_booked else "", day)
+ else:
+ return '
%d ' % ("selected" if is_booked else "", day)
+
+ def formatweek(self, theweek, year):
+ """
+ Return a complete week as a table row.
+ """
+ s = ''.join(self.formatday(d, wd, month, year) for (d, wd, month) in theweek)
+ return '
%s ' % s
+
+ def formatmonthname(self, theyear, themonth, withyear=True):
+ """
+ Return a month name as a table row.
+ """
+ if withyear:
+ s = '%s %s' % (month_name[themonth], theyear)
+ else:
+ s = '%s' % month_name[themonth]
+ return '
%s ' % s
+
+ def add_before(self):
+ return '
'
+
+ def add_after(self):
+ return '
'
+
+ def formatmonth(self, theyear, themonth, withyear=True):
+ """
+ Return a formatted month as a table.
+ """
+ v = []
+ a = v.append
+ a('
')
+ a('\n')
+ a(self.add_before())
+ a('\n')
+ a(self.formatmonthname(theyear, themonth, withyear=withyear))
+ a('\n')
+ a(self.add_after())
+ a('\n')
+ a(self.formatweekheader())
+ a('\n')
+ for week in self.monthdays2calendar(theyear, themonth):
+ a(self.formatweek(week, theyear))
+ a('\n')
+ a('
')
+ a('\n')
+ a('
')
+ return ''.join(v)
+
+
+class BookCalendar(CustomHTMLCalendar):
+ def __init__(self, user, requested_month):
+ self.user = user
+ super(BookCalendar, self).__init__(requested_month)
+
+ def formatmonth(self, year, month):
+ self.year, self.month = year, month
+ return super(BookCalendar, self).formatmonth(year, month)
+
+ def day_cell(self, cssclass, body):
+ return '
%s ' % body
+
+ def formatmonthname(self, theyear, themonth, withyear):
+ """
+ Return a month name as a table row.
+ """
+ s = '%s' % month_name[themonth]
+ return '
%s ' % s
+
+ def formatweekday(self, day):
+ """
+ Return a weekday name as a table header.
+ """
+
+ ret = '
%s ' % day_abbr[day][0:2]
+ return ret
+
+ def formatweekheader(self):
+ """
+ Return a header for a week as a table row.
+ """
+ s = ''.join(self.formatweekday(i) for i in self.iterweekdays())
+ return '
%s ' % s
diff --git a/membership/forms.py b/membership/forms.py
new file mode 100755
index 0000000..ddeb300
--- /dev/null
+++ b/membership/forms.py
@@ -0,0 +1,66 @@
+from django import forms
+from django.utils.translation import gettext_lazy as _
+from django.contrib.auth import authenticate
+
+from .models import CreditCards
+
+from utils.forms import SignupFormMixin
+
+
+class LoginForm(forms.Form):
+ email = forms.EmailField(label="Email address", max_length=50,
+ widget=forms.TextInput(
+ attrs={'class': 'form-control', 'placeholder': 'Enter email'}))
+ password = forms.CharField(label='Password', max_length=50,
+ widget=forms.TextInput(
+ attrs={'class': 'form-control', 'placeholder': 'Password',
+ 'type': 'password'}))
+
+ def clean(self):
+ email = self.cleaned_data.get('email')
+ password = self.cleaned_data.get('password')
+ user = authenticate(email=email, password=password)
+ if not user:
+ raise forms.ValidationError("Sorry, that login was invalid. Please try again.")
+ return self.cleaned_data
+
+ def login(self, request):
+ username = self.cleaned_data.get('email')
+ password = self.cleaned_data.get('password')
+ user = authenticate(email=username, password=password)
+ return user
+
+
+class RegisterForm(SignupFormMixin):
+ password = forms.CharField(widget=forms.PasswordInput())
+ confirm_password = forms.CharField(widget=forms.PasswordInput())
+
+
+class PaymentForm(forms.ModelForm):
+ class Meta:
+ model = CreditCards
+ fields = ('name', 'card_number', 'expiry_date', 'ccv', 'user_id')
+ labels = {'name': _('Name'), 'card_number': _('Card number'), 'expiry_date': _('Expiry date'),
+ 'ccv': _('CCV')}
+ exclude = ('user_id', 'payment_type')
+ widgets = {
+ 'name': forms.TextInput(
+ attrs={'class': 'form-control', "placeholder": "Enter name on card",
+ 'placeholder': 'Enter name on card'}),
+ 'card_number': forms.TextInput(
+ attrs={'class': 'form-control', 'placeholder': 'Card Number', 'data-stripe': 'number'}),
+ 'expiry_date': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'MM/YYYY'}),
+ 'ccv': forms.TextInput(
+ attrs={'class': 'form-control', 'placeholder': 'CCV', 'data-stripe': 'cvc'})}
+
+ def clean(self):
+ data = self.cleaned_data
+
+ # if CreditCards.objects.filter(card_number=data.get("card_number")):
+ # raise forms.ValidationError({'card_number': _('Credit card is used before.')})
+ return data
+
+ def save(self, user_id):
+ self.instance.user_id = user_id
+ self.instance.user_id_id = user_id.id
+ super(PaymentForm, self).save()
diff --git a/membership/locale/de/LC_MESSAGES/django.mo b/membership/locale/de/LC_MESSAGES/django.mo
new file mode 100755
index 0000000..9e7537a
Binary files /dev/null and b/membership/locale/de/LC_MESSAGES/django.mo differ
diff --git a/membership/locale/de/LC_MESSAGES/django.po b/membership/locale/de/LC_MESSAGES/django.po
new file mode 100755
index 0000000..47c3566
--- /dev/null
+++ b/membership/locale/de/LC_MESSAGES/django.po
@@ -0,0 +1,68 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR
, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-12-03 10:44+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: LANGUAGE \n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: membership/forms.py:43
+msgid "Name"
+msgstr ""
+
+#: membership/forms.py:43
+msgid "Card number"
+msgstr ""
+
+#: membership/forms.py:43
+msgid "Expiry date"
+msgstr ""
+
+#: membership/forms.py:44
+msgid "CCV"
+msgstr ""
+
+#: membership/models.py:108
+#, python-format
+msgid ""
+"%(value)s is not a valid name. A valid name can only include letters, spaces "
+"or -"
+msgstr ""
+
+#: membership/models.py:128
+msgid "staff status"
+msgstr ""
+
+#: membership/models.py:131
+msgid "Designates whether the user can log into this admin site."
+msgstr ""
+
+#: membership/models.py:158
+msgid "Account Activation"
+msgstr ""
+
+#: membership/models.py:340
+msgid "Use this pattern(MM/YYYY)."
+msgstr ""
+
+#: membership/models.py:342
+msgid "Wrong CCV number."
+msgstr ""
+
+#~ msgid "Activate your "
+#~ msgstr "Aktiviere deinen "
+
+#~ msgid " account"
+#~ msgstr " Account"
diff --git a/membership/migrations/0001_initial.py b/membership/migrations/0001_initial.py
new file mode 100644
index 0000000..66be307
--- /dev/null
+++ b/membership/migrations/0001_initial.py
@@ -0,0 +1,80 @@
+# Generated by Django 4.2.7 on 2023-12-06 11:35
+
+from django.conf import settings
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+import membership.models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ('sites', '0002_alter_domain_unique'),
+ ('auth', '0012_alter_user_first_name_max_length'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='CustomUser',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('password', models.CharField(max_length=128, verbose_name='password')),
+ ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
+ ('name', models.CharField(max_length=50, validators=[membership.models.validate_name])),
+ ('email', models.EmailField(max_length=254, unique=True)),
+ ('username', models.CharField(max_length=60, null=True, unique=True)),
+ ('validated', models.IntegerField(choices=[(0, 'Not validated'), (1, 'Validated')], default=0)),
+ ('in_ldap', models.BooleanField(default=False)),
+ ('validation_slug', models.CharField(db_index=True, default=membership.models.get_validation_slug, max_length=50, unique=True)),
+ ('is_admin', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
+ ('import_stripe_bill_remark', models.TextField(default='', help_text='Indicates any issues while importing stripe bills')),
+ ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
+ ('site', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='sites.site')),
+ ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
+ ],
+ options={
+ 'abstract': False,
+ },
+ ),
+ migrations.CreateModel(
+ name='DeletedUser',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('user_id', models.PositiveIntegerField()),
+ ('name', models.CharField(max_length=254)),
+ ('email', models.EmailField(max_length=254, unique=True)),
+ ('deleted_at', models.DateTimeField(auto_now_add=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='StripeCustomer',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('stripe_id', models.CharField(max_length=100, unique=True)),
+ ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='CreditCards',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=50)),
+ ('card_number', models.CharField(max_length=50)),
+ ('expiry_date', models.CharField(max_length=50, validators=[django.core.validators.RegexValidator('\\d{2}\\/\\d{4}', 'Use this pattern(MM/YYYY).')])),
+ ('ccv', models.CharField(max_length=4, validators=[django.core.validators.RegexValidator('\\d{3,4}', 'Wrong CCV number.')])),
+ ('payment_type', models.CharField(default='N', max_length=5)),
+ ('user_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Calendar',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('datebooked', models.DateField()),
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ ]
diff --git a/membership/migrations/__init__.py b/membership/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/membership/models.py b/membership/models.py
new file mode 100755
index 0000000..62cabef
--- /dev/null
+++ b/membership/models.py
@@ -0,0 +1,377 @@
+import logging
+import random
+import unicodedata
+
+from datetime import datetime
+from django.conf import settings
+from django.contrib.auth.base_user import BaseUserManager
+from django.contrib.auth.hashers import make_password
+from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
+from django.contrib.sites.models import Site
+from django.urls import reverse
+from django.core.validators import RegexValidator
+from django.db import models, IntegrityError
+from django.utils.crypto import get_random_string
+from django.utils.translation import gettext_lazy as _
+from django.core.exceptions import ValidationError
+
+from utils.mailer import BaseEmail
+from utils.stripe_utils import StripeUtils
+from utils.ldap_manager import LdapManager
+
+logger = logging.getLogger(__name__)
+
+REGISTRATION_MESSAGE = {'subject': "Validation mail",
+ 'message': 'Please validate Your account under this link '
+ 'http://localhost:8000/en-us/digitalglarus/login/validate/{}',
+ 'from': 'test@test.com'}
+
+
+def get_anonymous_user_instance(CustomUser):
+ return CustomUser(name='Anonymous', email='anonymous@ungleich.ch',
+ validation_slug=make_password(None))
+
+
+class MyUserManager(BaseUserManager):
+ def create_user(self, email, name, password=None):
+ """
+ Creates and saves a User with the given email,name and password.
+ """
+ if not email:
+ raise ValueError('Users must have an email address')
+
+ user = self.model(
+ email=self.normalize_email(email),
+ name=name,
+ validation_slug=make_password(None)
+ )
+ user.is_admin = False
+ user.set_password(password)
+ user.save(using=self._db)
+ user.create_ldap_account(password)
+ return user
+
+ def create_superuser(self, email, name, password):
+ """
+ Creates and saves a superuser with the given email, name and password.
+ """
+ user = self.create_user(email,
+ password=password,
+ name=name,
+ )
+ user.is_admin = True
+ user.is_active = True
+ user.is_superuser = True
+ user.save(using=self._db)
+ return user
+
+
+def get_validation_slug():
+ return make_password(None)
+
+
+def get_first_and_last_name(full_name):
+ first_name, *last_name = full_name.split(" ")
+ last_name = " ".join(last_name)
+ return first_name, last_name
+
+
+def assign_username(user):
+ if not user.username:
+ ldap_manager = LdapManager()
+
+ # Try to come up with a username
+ first_name, last_name = get_first_and_last_name(user.name)
+ user.username = unicodedata.normalize('NFKD', first_name + last_name)
+ user.username = "".join([char for char in user.username if char.isalnum()]).lower()
+ exist = True
+ while exist:
+ # Check if it exists
+ exist, entries = ldap_manager.check_user_exists(user.username)
+ if exist:
+ # If username exists in ldap, come up with a new user name and check it again
+ user.username = user.username + str(random.randint(0, 2 ** 10))
+ else:
+ # If username does not exists in ldap, try to save it in database
+ try:
+ user.save()
+ except IntegrityError:
+ # If username exists in database then come up with a new username
+ user.username = user.username + str(random.randint(0, 2 ** 10))
+ exist = True
+
+
+def validate_name(value):
+ valid_chars = [char for char in value if (char.isalpha() or char == "-" or char == " ")]
+ if len(valid_chars) < len(value):
+ raise ValidationError(
+ _('%(value)s is not a valid name. A valid name can only include letters, spaces or -'),
+ params={'value': value},
+ )
+
+
+class CustomUser(AbstractBaseUser, PermissionsMixin):
+ VALIDATED_CHOICES = ((0, 'Not validated'), (1, 'Validated'))
+ site = models.ForeignKey(Site, default=1, on_delete=models.CASCADE)
+ name = models.CharField(max_length=50, validators=[validate_name])
+ email = models.EmailField(unique=True)
+ username = models.CharField(max_length=60, unique=True, null=True)
+ validated = models.IntegerField(choices=VALIDATED_CHOICES, default=0)
+ in_ldap = models.BooleanField(default=False)
+ # By default, we initialize the validation_slug with appropriate value
+ # This is required for User(page) admin
+ validation_slug = models.CharField(
+ db_index=True, unique=True, max_length=50,
+ default=get_validation_slug
+ )
+ is_admin = models.BooleanField(
+ _('staff status'),
+ default=False,
+ help_text=_(
+ 'Designates whether the user can log into this admin site.'),
+ )
+ import_stripe_bill_remark = models.TextField(
+ default="",
+ help_text="Indicates any issues while importing stripe bills"
+ )
+
+ objects = MyUserManager()
+
+ USERNAME_FIELD = "email"
+ REQUIRED_FIELDS = ['name', 'password']
+
+ @classmethod
+ def register(cls, name, password, email, app='digital_glarus',
+ base_url=None, send_email=True, account_details=None):
+ user = cls.objects.filter(email=email).first()
+ if not user:
+ user = cls.objects.create_user(name=name, email=email,
+ password=password)
+ if user:
+ if app == 'dcl':
+ dcl_text = settings.DCL_TEXT
+ user.is_active = False
+ if send_email is True:
+ email_data = {
+ 'subject': '{dcl_text} {account_activation}'.format(
+ dcl_text=dcl_text,
+ account_activation=_('Account Activation')
+ ),
+ 'from_address': settings.DCL_SUPPORT_FROM_ADDRESS,
+ 'to': user.email,
+ 'context': {'base_url': base_url,
+ 'activation_link': reverse(
+ 'hosting:validate',
+ kwargs={
+ 'validate_slug': user.validation_slug}),
+ 'dcl_text': dcl_text
+ },
+ 'template_name': 'user_activation',
+ 'template_path': 'datacenterlight/emails/'
+ }
+ if account_details:
+ email_data['context'][
+ 'account_details'] = account_details
+ email = BaseEmail(**email_data)
+ email.send()
+ return user
+ else:
+ return None
+ else:
+ return None
+
+ @classmethod
+ def get_all_members(cls):
+ return cls.objects.filter(
+ stripecustomer__membershiporder__isnull=False)
+
+ @classmethod
+ def validate_url(cls, validation_slug):
+ user = cls.objects.filter(validation_slug=validation_slug).first()
+ if user:
+ user.validated = 1
+ user.save()
+ return True
+ return False
+
+ @classmethod
+ def get_random_password(cls):
+ return get_random_string(24)
+
+ def is_superuser(self):
+ return False
+
+ def get_full_name(self):
+ # The user is identified by their email address
+ return self.email
+
+ def get_short_name(self):
+ # The user is identified by their email address
+ return self.email
+
+ def create_ldap_account(self, password):
+ # create ldap account for user if it does not exists already.
+ if self.in_ldap:
+ return
+
+ assign_username(self)
+ ldap_manager = LdapManager()
+ try:
+ user_exists_in_ldap, entries = ldap_manager.check_user_exists(self.username)
+ except Exception:
+ logger.exception("Exception occur while searching for user in LDAP")
+ else:
+ if not user_exists_in_ldap:
+ # IF no ldap account
+ first_name, last_name = get_first_and_last_name(self.name)
+ if not last_name:
+ last_name = first_name
+ ldap_manager.create_user(self.username, password=password,
+ firstname=first_name, lastname=last_name,
+ email=self.email)
+ else:
+ # User exists already in LDAP, but with a dummy credential
+ # We are here implies that the user has successfully
+ # authenticated against Django db, and a corresponding user
+ # exists in LDAP.
+ # We just update the LDAP credentials once again, assuming it
+ # was set to a dummy value while migrating users from Django to
+ # LDAP
+ ldap_manager.change_password(self.username, password)
+ self.in_ldap = True
+ self.save()
+
+ def __str__(self): # __unicode__ on Python 2
+ return self.email
+
+ # def has_perm(self, perm, obj=None):
+ # "Does the user have a specific permission?"
+ # # Simplest possible answer: Yes, always
+ # return self.is_admin
+
+ def has_module_perms(self, app_label):
+ "Does the user have permissions to view the app `app_label`?"
+ # Simplest possible answer: Yes, always
+ return self.is_admin
+
+ @property
+ def is_staff(self):
+ "Is the user a member of staff?"
+ # Simplest possible answer: All admins are staff
+ return self.is_admin
+
+ @is_staff.setter
+ def is_staff(self, value):
+ self._is_staff = value
+
+
+class StripeCustomer(models.Model):
+ user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
+ stripe_id = models.CharField(unique=True, max_length=100)
+
+ def __str__(self):
+ return "%s - %s" % (self.stripe_id, self.user.email)
+
+ @classmethod
+ def create_stripe_api_customer(cls, email=None, id_payment_method=None,
+ customer_name=None):
+ """
+ This method creates a Stripe API customer with the given
+ email, token and customer_name. This is different from
+ get_or_create method below in that it does not create a
+ CustomUser and associate the customer created in stripe
+ with it, while get_or_create does that before creating the
+ stripe user.
+ """
+ stripe_utils = StripeUtils()
+ stripe_data = stripe_utils.create_customer(
+ id_payment_method, email, customer_name)
+ if stripe_data.get('response_object'):
+ stripe_cus_id = stripe_data.get('response_object').get('id')
+ return stripe_cus_id
+ else:
+ return None
+
+ @classmethod
+ def get_or_create(cls, email=None, token=None, id_payment_method=None):
+ """
+ Check if there is a registered stripe customer with that email
+ or create a new one
+ """
+ try:
+ stripe_utils = StripeUtils()
+ stripe_customer = cls.objects.get(user__email=email)
+ # check if user is not in stripe but in database
+ customer = stripe_utils.check_customer(stripe_customer.stripe_id,
+ stripe_customer.user, token)
+ if "deleted" in customer and customer["deleted"]:
+ raise StripeCustomer.DoesNotExist()
+ return stripe_customer
+ except StripeCustomer.DoesNotExist:
+ user = CustomUser.objects.get(email=email)
+ stripe_utils = StripeUtils()
+ stripe_data = stripe_utils.create_customer(token, email, user.name)
+ if stripe_data.get('response_object'):
+ stripe_cus_id = stripe_data.get('response_object').get('id')
+ if hasattr(user, 'stripecustomer'):
+ # User already had a Stripe account and we are here
+ # because the account was deleted in dashboard
+ # So, we simply update the stripe_id
+ user.stripecustomer.stripe_id = stripe_cus_id
+ user.stripecustomer.save()
+ stripe_customer = user.stripecustomer
+ else:
+ # The user never had an associated Stripe account
+ # So, create one
+ stripe_customer = StripeCustomer.objects.create(
+ user=user, stripe_id=stripe_cus_id
+ )
+ return stripe_customer
+ else:
+ return None
+
+
+class CreditCards(models.Model):
+ name = models.CharField(max_length=50)
+ user_id = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
+ card_number = models.CharField(max_length=50)
+ expiry_date = models.CharField(max_length=50, validators=[
+ RegexValidator(r'\d{2}\/\d{4}', _(
+ 'Use this pattern(MM/YYYY).'))])
+ ccv = models.CharField(max_length=4, validators=[
+ RegexValidator(r'\d{3,4}', _('Wrong CCV number.'))])
+ payment_type = models.CharField(max_length=5, default='N')
+
+ def save(self, *args, **kwargs):
+ # override saving to database
+ pass
+
+
+class DeletedUser(models.Model):
+ user_id = models.PositiveIntegerField()
+
+ # why 254 ? => to be consistent with legacy code
+ name = models.CharField(max_length=254)
+ email = models.EmailField(unique=True, max_length=254)
+ deleted_at = models.DateTimeField(auto_now_add=True)
+
+
+class Calendar(models.Model):
+ datebooked = models.DateField()
+ user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
+
+ def __init__(self, *args, **kwargs):
+ if kwargs.get('datebooked'):
+ user = kwargs.get('user')
+ kwargs['datebooked'] = datetime.strptime(
+ kwargs.get('datebooked', ''), '%d,%m,%Y')
+ self.user_id = user.id
+ super(Calendar, self).__init__(*args, **kwargs)
+
+ @classmethod
+ def add_dates(cls, dates, user):
+ old_dates = Calendar.objects.filter(user_id=user.id)
+ if old_dates:
+ old_dates.delete()
+ for date in dates:
+ Calendar.objects.create(datebooked=date, user=user)
diff --git a/membership/payment.py b/membership/payment.py
new file mode 100755
index 0000000..a546699
--- /dev/null
+++ b/membership/payment.py
@@ -0,0 +1,48 @@
+__author__ = 'tomislav'
+from django.conf import settings
+from .models import CreditCards
+import stripe
+stripe.api_key = settings.STRIPE_API_PRIVATE_KEY
+
+
+class StripePayment(object):
+ @classmethod
+ def make_payment(cls, user, amount, token, time):
+ try:
+ print(amount)
+ print(amount)
+ print(amount)
+ # Use Stripe's library to make requests...
+ charge = stripe.Charge.create(
+ amount=amount,
+ currency='chf',
+ source=token,
+ description=settings.STRIPE_DESCRIPTION_ON_PAYMENT
+ )
+ if charge['status'] == 'succeeded':
+ obj = CreditCards.objects.filter(user_id=user.id).first()
+ obj.payment_type = time
+ obj.save()
+ return charge['status']
+
+ except stripe.error.CardError as e:
+ # Since it's a decline, stripe.error.CardError will be caught
+ body = e.json_body
+ err = body['error']
+ return err['message']
+ except stripe.error.RateLimitError as e:
+ return "Too many requests made to the API too quickly"
+ except stripe.error.InvalidRequestError as e:
+ return "Invalid parameters"
+ except stripe.error.AuthenticationError as e:
+ # Authentication with Stripe's API failed
+ # (maybe you changed API keys recently)
+ pass
+ except stripe.error.APIConnectionError as e:
+ return "Currently its not possible to make payments."
+ except stripe.error.StripeError as e:
+ return "Currently its not possible to make payments."
+ # maybe send email
+ except Exception as e:
+ return "Currently its not possible to make payments."
+ # maybe send email
diff --git a/membership/static/css/membership.css b/membership/static/css/membership.css
new file mode 100755
index 0000000..2b0222a
--- /dev/null
+++ b/membership/static/css/membership.css
@@ -0,0 +1,8280 @@
+@import url('https://fonts.googleapis.com/css?family=Lato|Lato');
+
+/*!
+ * Default theme for Pingendo
+ * Homepage: http://pingendo.com
+ * Copyright 2015 Pingendo
+ * Licensed under MIT
+ * Based on Bootstrap v3.3.4
+*/
+/* Add custom CSS classes here
+ *
+ * img {
+ * box-shadow : 0px 0px 10px black !important;
+ * }
+*/
+/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
+html {
+ font-family: sans-serif;
+ -ms-text-size-adjust: 100%;
+ -webkit-text-size-adjust: 100%;
+}
+
+body {
+ margin: 0;
+}
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+ display: block;
+}
+
+audio,
+canvas,
+progress,
+video {
+ display: inline-block;
+ vertical-align: baseline;
+}
+
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+
+[hidden],
+template {
+ display: none;
+}
+
+a {
+ background-color: transparent;
+}
+
+a:active,
+a:hover {
+ outline: 0;
+}
+
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+
+b,
+strong {
+ font-weight: bold;
+}
+
+dfn {
+ font-style: italic;
+}
+
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+mark {
+ background: #ff0;
+ color: #000;
+}
+
+small {
+ font-size: 80%;
+}
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sup {
+ top: -0.5em;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+img {
+ border: 0;
+}
+
+svg:not(:root) {
+ overflow: hidden;
+}
+
+figure {
+ margin: 1em 40px;
+}
+
+hr {
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ height: 0;
+}
+
+pre {
+ overflow: auto;
+}
+
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, monospace;
+ font-size: 1em;
+}
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ color: inherit;
+ font: inherit;
+ margin: 0;
+}
+
+button {
+ overflow: visible;
+}
+
+button,
+select {
+ text-transform: none;
+}
+
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button;
+ cursor: pointer;
+}
+
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+input {
+ line-height: normal;
+}
+
+input[type="checkbox"],
+input[type="radio"] {
+ box-sizing: border-box;
+ padding: 0;
+}
+
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+input[type="search"] {
+ -webkit-appearance: textfield;
+ -moz-box-sizing: content-box;
+ -webkit-box-sizing: content-box;
+ box-sizing: content-box;
+}
+
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+fieldset {
+ border: 1px solid #c0c0c0;
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
+}
+
+legend {
+ border: 0;
+ padding: 0;
+}
+
+textarea {
+ overflow: auto;
+}
+
+optgroup {
+ font-weight: bold;
+}
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+td,
+th {
+ padding: 0;
+}
+
+/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
+@media print {
+ *,
+ *:before,
+ *:after {
+ background: transparent !important;
+ color: #000 !important;
+ box-shadow: none !important;
+ text-shadow: none !important;
+ }
+
+ a,
+ a:visited {
+ text-decoration: underline;
+ }
+
+ a[href]:after {
+ content: " (" attr(href) ")";
+ }
+
+ abbr[title]:after {
+ content: " (" attr(title) ")";
+ }
+
+ a[href^="#"]:after,
+ a[href^="javascript:"]:after {
+ content: "";
+ }
+
+ pre,
+ blockquote {
+ border: 1px solid #999;
+ page-break-inside: avoid;
+ }
+
+ thead {
+ display: table-header-group;
+ }
+
+ tr,
+ img {
+ page-break-inside: avoid;
+ }
+
+ img {
+ max-width: 100% !important;
+ }
+
+ p,
+ h2,
+ h3 {
+ orphans: 3;
+ widows: 3;
+ }
+
+ h2,
+ h3 {
+ page-break-after: avoid;
+ }
+
+ select {
+ background: #fff !important;
+ }
+
+ .navbar {
+ display: none;
+ }
+
+ .btn > .caret,
+ .dropup > .btn > .caret {
+ border-top-color: #000 !important;
+ }
+
+ .label {
+ border: 1px solid #000;
+ }
+
+ .table {
+ border-collapse: collapse !important;
+ }
+
+ .table td,
+ .table th {
+ background-color: #fff !important;
+ }
+
+ .table-bordered th,
+ .table-bordered td {
+ border: 1px solid #ddd !important;
+ }
+}
+
+@font-face {
+ font-family: 'Glyphicons Halflings';
+ src: url('../fonts/glyphicons-halflings-regular.eot');
+ src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+}
+
+.glyphicon {
+ position: relative;
+ top: 1px;
+ display: inline-block;
+ font-family: 'Glyphicons Halflings';
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.glyphicon-asterisk:before {
+ content: "\2a";
+}
+
+.glyphicon-plus:before {
+ content: "\2b";
+}
+
+.glyphicon-euro:before,
+.glyphicon-eur:before {
+ content: "\20ac";
+}
+
+.glyphicon-minus:before {
+ content: "\2212";
+}
+
+.glyphicon-cloud:before {
+ content: "\2601";
+}
+
+.glyphicon-envelope:before {
+ content: "\2709";
+}
+
+.glyphicon-pencil:before {
+ content: "\270f";
+}
+
+.glyphicon-glass:before {
+ content: "\e001";
+}
+
+.glyphicon-music:before {
+ content: "\e002";
+}
+
+.glyphicon-search:before {
+ content: "\e003";
+}
+
+.glyphicon-heart:before {
+ content: "\e005";
+}
+
+.glyphicon-star:before {
+ content: "\e006";
+}
+
+.glyphicon-star-empty:before {
+ content: "\e007";
+}
+
+.glyphicon-user:before {
+ content: "\e008";
+}
+
+.glyphicon-film:before {
+ content: "\e009";
+}
+
+.glyphicon-th-large:before {
+ content: "\e010";
+}
+
+.glyphicon-th:before {
+ content: "\e011";
+}
+
+.glyphicon-th-list:before {
+ content: "\e012";
+}
+
+.glyphicon-ok:before {
+ content: "\e013";
+}
+
+.glyphicon-remove:before {
+ content: "\e014";
+}
+
+.glyphicon-zoom-in:before {
+ content: "\e015";
+}
+
+.glyphicon-zoom-out:before {
+ content: "\e016";
+}
+
+.glyphicon-off:before {
+ content: "\e017";
+}
+
+.glyphicon-signal:before {
+ content: "\e018";
+}
+
+.glyphicon-cog:before {
+ content: "\e019";
+}
+
+.glyphicon-trash:before {
+ content: "\e020";
+}
+
+.glyphicon-home:before {
+ content: "\e021";
+}
+
+.glyphicon-file:before {
+ content: "\e022";
+}
+
+.glyphicon-time:before {
+ content: "\e023";
+}
+
+.glyphicon-road:before {
+ content: "\e024";
+}
+
+.glyphicon-download-alt:before {
+ content: "\e025";
+}
+
+.glyphicon-download:before {
+ content: "\e026";
+}
+
+.glyphicon-upload:before {
+ content: "\e027";
+}
+
+.glyphicon-inbox:before {
+ content: "\e028";
+}
+
+.glyphicon-play-circle:before {
+ content: "\e029";
+}
+
+.glyphicon-repeat:before {
+ content: "\e030";
+}
+
+.glyphicon-refresh:before {
+ content: "\e031";
+}
+
+.glyphicon-list-alt:before {
+ content: "\e032";
+}
+
+.glyphicon-lock:before {
+ content: "\e033";
+}
+
+.glyphicon-flag:before {
+ content: "\e034";
+}
+
+.glyphicon-headphones:before {
+ content: "\e035";
+}
+
+.glyphicon-volume-off:before {
+ content: "\e036";
+}
+
+.glyphicon-volume-down:before {
+ content: "\e037";
+}
+
+.glyphicon-volume-up:before {
+ content: "\e038";
+}
+
+.glyphicon-qrcode:before {
+ content: "\e039";
+}
+
+.glyphicon-barcode:before {
+ content: "\e040";
+}
+
+.glyphicon-tag:before {
+ content: "\e041";
+}
+
+.glyphicon-tags:before {
+ content: "\e042";
+}
+
+.glyphicon-book:before {
+ content: "\e043";
+}
+
+.glyphicon-bookmark:before {
+ content: "\e044";
+}
+
+.glyphicon-print:before {
+ content: "\e045";
+}
+
+.glyphicon-camera:before {
+ content: "\e046";
+}
+
+.glyphicon-font:before {
+ content: "\e047";
+}
+
+.glyphicon-bold:before {
+ content: "\e048";
+}
+
+.glyphicon-italic:before {
+ content: "\e049";
+}
+
+.glyphicon-text-height:before {
+ content: "\e050";
+}
+
+.glyphicon-text-width:before {
+ content: "\e051";
+}
+
+.glyphicon-align-left:before {
+ content: "\e052";
+}
+
+.glyphicon-align-center:before {
+ content: "\e053";
+}
+
+.glyphicon-align-right:before {
+ content: "\e054";
+}
+
+.glyphicon-align-justify:before {
+ content: "\e055";
+}
+
+.glyphicon-list:before {
+ content: "\e056";
+}
+
+.glyphicon-indent-left:before {
+ content: "\e057";
+}
+
+.glyphicon-indent-right:before {
+ content: "\e058";
+}
+
+.glyphicon-facetime-video:before {
+ content: "\e059";
+}
+
+.glyphicon-picture:before {
+ content: "\e060";
+}
+
+.glyphicon-map-marker:before {
+ content: "\e062";
+}
+
+.glyphicon-adjust:before {
+ content: "\e063";
+}
+
+.glyphicon-tint:before {
+ content: "\e064";
+}
+
+.glyphicon-edit:before {
+ content: "\e065";
+}
+
+.glyphicon-share:before {
+ content: "\e066";
+}
+
+.glyphicon-check:before {
+ content: "\e067";
+}
+
+.glyphicon-move:before {
+ content: "\e068";
+}
+
+.glyphicon-step-backward:before {
+ content: "\e069";
+}
+
+.glyphicon-fast-backward:before {
+ content: "\e070";
+}
+
+.glyphicon-backward:before {
+ content: "\e071";
+}
+
+.glyphicon-play:before {
+ content: "\e072";
+}
+
+.glyphicon-pause:before {
+ content: "\e073";
+}
+
+.glyphicon-stop:before {
+ content: "\e074";
+}
+
+.glyphicon-forward:before {
+ content: "\e075";
+}
+
+.glyphicon-fast-forward:before {
+ content: "\e076";
+}
+
+.glyphicon-step-forward:before {
+ content: "\e077";
+}
+
+.glyphicon-eject:before {
+ content: "\e078";
+}
+
+.glyphicon-chevron-left:before {
+ content: "\e079";
+}
+
+.glyphicon-chevron-right:before {
+ content: "\e080";
+}
+
+.glyphicon-plus-sign:before {
+ content: "\e081";
+}
+
+.glyphicon-minus-sign:before {
+ content: "\e082";
+}
+
+.glyphicon-remove-sign:before {
+ content: "\e083";
+}
+
+.glyphicon-ok-sign:before {
+ content: "\e084";
+}
+
+.glyphicon-question-sign:before {
+ content: "\e085";
+}
+
+.glyphicon-info-sign:before {
+ content: "\e086";
+}
+
+.glyphicon-screenshot:before {
+ content: "\e087";
+}
+
+.glyphicon-remove-circle:before {
+ content: "\e088";
+}
+
+.glyphicon-ok-circle:before {
+ content: "\e089";
+}
+
+.glyphicon-ban-circle:before {
+ content: "\e090";
+}
+
+.glyphicon-arrow-left:before {
+ content: "\e091";
+}
+
+.glyphicon-arrow-right:before {
+ content: "\e092";
+}
+
+.glyphicon-arrow-up:before {
+ content: "\e093";
+}
+
+.glyphicon-arrow-down:before {
+ content: "\e094";
+}
+
+.glyphicon-share-alt:before {
+ content: "\e095";
+}
+
+.glyphicon-resize-full:before {
+ content: "\e096";
+}
+
+.glyphicon-resize-small:before {
+ content: "\e097";
+}
+
+.glyphicon-exclamation-sign:before {
+ content: "\e101";
+}
+
+.glyphicon-gift:before {
+ content: "\e102";
+}
+
+.glyphicon-leaf:before {
+ content: "\e103";
+}
+
+.glyphicon-fire:before {
+ content: "\e104";
+}
+
+.glyphicon-eye-open:before {
+ content: "\e105";
+}
+
+.glyphicon-eye-close:before {
+ content: "\e106";
+}
+
+.glyphicon-warning-sign:before {
+ content: "\e107";
+}
+
+.glyphicon-plane:before {
+ content: "\e108";
+}
+
+.glyphicon-calendar:before {
+ content: "\e109";
+}
+
+.glyphicon-random:before {
+ content: "\e110";
+}
+
+.glyphicon-comment:before {
+ content: "\e111";
+}
+
+.glyphicon-magnet:before {
+ content: "\e112";
+}
+
+.glyphicon-chevron-up:before {
+ content: "\e113";
+}
+
+.glyphicon-chevron-down:before {
+ content: "\e114";
+}
+
+.glyphicon-retweet:before {
+ content: "\e115";
+}
+
+.glyphicon-shopping-cart:before {
+ content: "\e116";
+}
+
+.glyphicon-folder-close:before {
+ content: "\e117";
+}
+
+.glyphicon-folder-open:before {
+ content: "\e118";
+}
+
+.glyphicon-resize-vertical:before {
+ content: "\e119";
+}
+
+.glyphicon-resize-horizontal:before {
+ content: "\e120";
+}
+
+.glyphicon-hdd:before {
+ content: "\e121";
+}
+
+.glyphicon-bullhorn:before {
+ content: "\e122";
+}
+
+.glyphicon-bell:before {
+ content: "\e123";
+}
+
+.glyphicon-certificate:before {
+ content: "\e124";
+}
+
+.glyphicon-thumbs-up:before {
+ content: "\e125";
+}
+
+.glyphicon-thumbs-down:before {
+ content: "\e126";
+}
+
+.glyphicon-hand-right:before {
+ content: "\e127";
+}
+
+.glyphicon-hand-left:before {
+ content: "\e128";
+}
+
+.glyphicon-hand-up:before {
+ content: "\e129";
+}
+
+.glyphicon-hand-down:before {
+ content: "\e130";
+}
+
+.glyphicon-circle-arrow-right:before {
+ content: "\e131";
+}
+
+.glyphicon-circle-arrow-left:before {
+ content: "\e132";
+}
+
+.glyphicon-circle-arrow-up:before {
+ content: "\e133";
+}
+
+.glyphicon-circle-arrow-down:before {
+ content: "\e134";
+}
+
+.glyphicon-globe:before {
+ content: "\e135";
+}
+
+.glyphicon-wrench:before {
+ content: "\e136";
+}
+
+.glyphicon-tasks:before {
+ content: "\e137";
+}
+
+.glyphicon-filter:before {
+ content: "\e138";
+}
+
+.glyphicon-briefcase:before {
+ content: "\e139";
+}
+
+.glyphicon-fullscreen:before {
+ content: "\e140";
+}
+
+.glyphicon-dashboard:before {
+ content: "\e141";
+}
+
+.glyphicon-paperclip:before {
+ content: "\e142";
+}
+
+.glyphicon-heart-empty:before {
+ content: "\e143";
+}
+
+.glyphicon-link:before {
+ content: "\e144";
+}
+
+.glyphicon-phone:before {
+ content: "\e145";
+}
+
+.glyphicon-pushpin:before {
+ content: "\e146";
+}
+
+.glyphicon-usd:before {
+ content: "\e148";
+}
+
+.glyphicon-gbp:before {
+ content: "\e149";
+}
+
+.glyphicon-sort:before {
+ content: "\e150";
+}
+
+.glyphicon-sort-by-alphabet:before {
+ content: "\e151";
+}
+
+.glyphicon-sort-by-alphabet-alt:before {
+ content: "\e152";
+}
+
+.glyphicon-sort-by-order:before {
+ content: "\e153";
+}
+
+.glyphicon-sort-by-order-alt:before {
+ content: "\e154";
+}
+
+.glyphicon-sort-by-attributes:before {
+ content: "\e155";
+}
+
+.glyphicon-sort-by-attributes-alt:before {
+ content: "\e156";
+}
+
+.glyphicon-unchecked:before {
+ content: "\e157";
+}
+
+.glyphicon-expand:before {
+ content: "\e158";
+}
+
+.glyphicon-collapse-down:before {
+ content: "\e159";
+}
+
+.glyphicon-collapse-up:before {
+ content: "\e160";
+}
+
+.glyphicon-log-in:before {
+ content: "\e161";
+}
+
+.glyphicon-flash:before {
+ content: "\e162";
+}
+
+.glyphicon-log-out:before {
+ content: "\e163";
+}
+
+.glyphicon-new-window:before {
+ content: "\e164";
+}
+
+.glyphicon-record:before {
+ content: "\e165";
+}
+
+.glyphicon-save:before {
+ content: "\e166";
+}
+
+.glyphicon-open:before {
+ content: "\e167";
+}
+
+.glyphicon-saved:before {
+ content: "\e168";
+}
+
+.glyphicon-import:before {
+ content: "\e169";
+}
+
+.glyphicon-export:before {
+ content: "\e170";
+}
+
+.glyphicon-send:before {
+ content: "\e171";
+}
+
+.glyphicon-floppy-disk:before {
+ content: "\e172";
+}
+
+.glyphicon-floppy-saved:before {
+ content: "\e173";
+}
+
+.glyphicon-floppy-remove:before {
+ content: "\e174";
+}
+
+.glyphicon-floppy-save:before {
+ content: "\e175";
+}
+
+.glyphicon-floppy-open:before {
+ content: "\e176";
+}
+
+.glyphicon-credit-card:before {
+ content: "\e177";
+}
+
+.glyphicon-transfer:before {
+ content: "\e178";
+}
+
+.glyphicon-cutlery:before {
+ content: "\e179";
+}
+
+.glyphicon-header:before {
+ content: "\e180";
+}
+
+.glyphicon-compressed:before {
+ content: "\e181";
+}
+
+.glyphicon-earphone:before {
+ content: "\e182";
+}
+
+.glyphicon-phone-alt:before {
+ content: "\e183";
+}
+
+.glyphicon-tower:before {
+ content: "\e184";
+}
+
+.glyphicon-stats:before {
+ content: "\e185";
+}
+
+.glyphicon-sd-video:before {
+ content: "\e186";
+}
+
+.glyphicon-hd-video:before {
+ content: "\e187";
+}
+
+.glyphicon-subtitles:before {
+ content: "\e188";
+}
+
+.glyphicon-sound-stereo:before {
+ content: "\e189";
+}
+
+.glyphicon-sound-dolby:before {
+ content: "\e190";
+}
+
+.glyphicon-sound-5-1:before {
+ content: "\e191";
+}
+
+.glyphicon-sound-6-1:before {
+ content: "\e192";
+}
+
+.glyphicon-sound-7-1:before {
+ content: "\e193";
+}
+
+.glyphicon-copyright-mark:before {
+ content: "\e194";
+}
+
+.glyphicon-registration-mark:before {
+ content: "\e195";
+}
+
+.glyphicon-cloud-download:before {
+ content: "\e197";
+}
+
+.glyphicon-cloud-upload:before {
+ content: "\e198";
+}
+
+.glyphicon-tree-conifer:before {
+ content: "\e199";
+}
+
+.glyphicon-tree-deciduous:before {
+ content: "\e200";
+}
+
+.glyphicon-cd:before {
+ content: "\e201";
+}
+
+.glyphicon-save-file:before {
+ content: "\e202";
+}
+
+.glyphicon-open-file:before {
+ content: "\e203";
+}
+
+.glyphicon-level-up:before {
+ content: "\e204";
+}
+
+.glyphicon-copy:before {
+ content: "\e205";
+}
+
+.glyphicon-paste:before {
+ content: "\e206";
+}
+
+.glyphicon-alert:before {
+ content: "\e209";
+}
+
+.glyphicon-equalizer:before {
+ content: "\e210";
+}
+
+.glyphicon-king:before {
+ content: "\e211";
+}
+
+.glyphicon-queen:before {
+ content: "\e212";
+}
+
+.glyphicon-pawn:before {
+ content: "\e213";
+}
+
+.glyphicon-bishop:before {
+ content: "\e214";
+}
+
+.glyphicon-knight:before {
+ content: "\e215";
+}
+
+.glyphicon-baby-formula:before {
+ content: "\e216";
+}
+
+.glyphicon-tent:before {
+ content: "\26fa";
+}
+
+.glyphicon-blackboard:before {
+ content: "\e218";
+}
+
+.glyphicon-bed:before {
+ content: "\e219";
+}
+
+.glyphicon-apple:before {
+ content: "\f8ff";
+}
+
+.glyphicon-erase:before {
+ content: "\e221";
+}
+
+.glyphicon-hourglass:before {
+ content: "\231b";
+}
+
+.glyphicon-lamp:before {
+ content: "\e223";
+}
+
+.glyphicon-duplicate:before {
+ content: "\e224";
+}
+
+.glyphicon-piggy-bank:before {
+ content: "\e225";
+}
+
+.glyphicon-scissors:before {
+ content: "\e226";
+}
+
+.glyphicon-bitcoin:before {
+ content: "\e227";
+}
+
+.glyphicon-btc:before {
+ content: "\e227";
+}
+
+.glyphicon-xbt:before {
+ content: "\e227";
+}
+
+.glyphicon-yen:before {
+ content: "\00a5";
+}
+
+.glyphicon-jpy:before {
+ content: "\00a5";
+}
+
+.glyphicon-ruble:before {
+ content: "\20bd";
+}
+
+.glyphicon-rub:before {
+ content: "\20bd";
+}
+
+.glyphicon-scale:before {
+ content: "\e230";
+}
+
+.glyphicon-ice-lolly:before {
+ content: "\e231";
+}
+
+.glyphicon-ice-lolly-tasted:before {
+ content: "\e232";
+}
+
+.glyphicon-education:before {
+ content: "\e233";
+}
+
+.glyphicon-option-horizontal:before {
+ content: "\e234";
+}
+
+.glyphicon-option-vertical:before {
+ content: "\e235";
+}
+
+.glyphicon-menu-hamburger:before {
+ content: "\e236";
+}
+
+.glyphicon-modal-window:before {
+ content: "\e237";
+}
+
+.glyphicon-oil:before {
+ content: "\e238";
+}
+
+.glyphicon-grain:before {
+ content: "\e239";
+}
+
+.glyphicon-sunglasses:before {
+ content: "\e240";
+}
+
+.glyphicon-text-size:before {
+ content: "\e241";
+}
+
+.glyphicon-text-color:before {
+ content: "\e242";
+}
+
+.glyphicon-text-background:before {
+ content: "\e243";
+}
+
+.glyphicon-object-align-top:before {
+ content: "\e244";
+}
+
+.glyphicon-object-align-bottom:before {
+ content: "\e245";
+}
+
+.glyphicon-object-align-horizontal:before {
+ content: "\e246";
+}
+
+.glyphicon-object-align-left:before {
+ content: "\e247";
+}
+
+.glyphicon-object-align-vertical:before {
+ content: "\e248";
+}
+
+.glyphicon-object-align-right:before {
+ content: "\e249";
+}
+
+.glyphicon-triangle-right:before {
+ content: "\e250";
+}
+
+.glyphicon-triangle-left:before {
+ content: "\e251";
+}
+
+.glyphicon-triangle-bottom:before {
+ content: "\e252";
+}
+
+.glyphicon-triangle-top:before {
+ content: "\e253";
+}
+
+.glyphicon-console:before {
+ content: "\e254";
+}
+
+.glyphicon-superscript:before {
+ content: "\e255";
+}
+
+.glyphicon-subscript:before {
+ content: "\e256";
+}
+
+.glyphicon-menu-left:before {
+ content: "\e257";
+}
+
+.glyphicon-menu-right:before {
+ content: "\e258";
+}
+
+.glyphicon-menu-down:before {
+ content: "\e259";
+}
+
+.glyphicon-menu-up:before {
+ content: "\e260";
+}
+
+* {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+*:before,
+*:after {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+html {
+ font-size: 10px;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+body {
+ font-family: Lato;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #000000;
+ background-color: #ffffff;
+}
+
+input,
+button,
+select,
+textarea {
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+
+a {
+ color: #8bc4c9;
+ text-decoration: none;
+}
+
+a:hover,
+a:focus {
+ color: #23547f;
+ text-decoration: underline;
+}
+
+a:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+figure {
+ margin: 0;
+}
+
+img {
+ vertical-align: middle;
+}
+
+.img-responsive,
+.thumbnail > img,
+.thumbnail a > img,
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+}
+
+.img-rounded {
+ border-radius: 5px;
+}
+
+.img-thumbnail {
+ padding: 4px;
+ line-height: 1.42857143;
+ background-color: #ffffff;
+ border: 1px solid #dddddd;
+ border-radius: 4px;
+ -webkit-transition: all 0.2s ease-in-out;
+ -o-transition: all 0.2s ease-in-out;
+ transition: all 0.2s ease-in-out;
+ display: inline-block;
+ max-width: 100%;
+ height: auto;
+}
+
+.img-circle {
+ border-radius: 50%;
+}
+
+hr {
+ margin-top: 20px;
+ margin-bottom: 20px;
+ border: 0;
+ border-top: 1px solid #eeeeee;
+}
+
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ margin: -1px;
+ padding: 0;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0;
+}
+
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+}
+
+[role="button"] {
+ cursor: pointer;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6 {
+ font-family: Lato;
+ font-weight: 500;
+ line-height: 1.1;
+ color: inherit;
+}
+
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small,
+.h1 small,
+.h2 small,
+.h3 small,
+.h4 small,
+.h5 small,
+.h6 small,
+h1 .small,
+h2 .small,
+h3 .small,
+h4 .small,
+h5 .small,
+h6 .small,
+.h1 .small,
+.h2 .small,
+.h3 .small,
+.h4 .small,
+.h5 .small,
+.h6 .small {
+ font-weight: normal;
+ line-height: 1;
+ color: #777777;
+}
+
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3 {
+ margin-top: 20px;
+ margin-bottom: 10px;
+}
+
+h1 small,
+.h1 small,
+h2 small,
+.h2 small,
+h3 small,
+.h3 small,
+h1 .small,
+.h1 .small,
+h2 .small,
+.h2 .small,
+h3 .small,
+.h3 .small {
+ font-size: 65%;
+}
+
+h4,
+.h4,
+h5,
+.h5,
+h6,
+.h6 {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+h4 small,
+.h4 small,
+h5 small,
+.h5 small,
+h6 small,
+.h6 small,
+h4 .small,
+.h4 .small,
+h5 .small,
+.h5 .small,
+h6 .small,
+.h6 .small {
+ font-size: 75%;
+}
+
+h1,
+.h1 {
+ font-size: 36px;
+}
+
+h2,
+.h2 {
+ font-size: 30px;
+}
+
+h3,
+.h3 {
+ font-size: 24px;
+}
+
+h4,
+.h4 {
+ font-size: 18px;
+}
+
+h5,
+.h5 {
+ font-size: 14px;
+}
+
+h6,
+.h6 {
+ font-size: 12px;
+}
+
+p {
+ margin: 0 0 10px;
+}
+
+.lead {
+ margin-bottom: 20px;
+ font-size: 16px;
+ font-weight: 300;
+ line-height: 1.4;
+}
+
+@media (min-width: 768px) {
+ .lead {
+ font-size: 21px;
+ }
+}
+
+small,
+.small {
+ font-size: 85%;
+}
+
+mark,
+.mark {
+ background-color: #f8d9ac;
+ padding: .2em;
+}
+
+.text-left {
+ text-align: left;
+}
+
+.text-right {
+ text-align: right;
+}
+
+.text-center {
+ text-align: center;
+}
+
+.text-justify {
+ text-align: justify;
+}
+
+.text-nowrap {
+ white-space: nowrap;
+}
+
+.text-lowercase {
+ text-transform: lowercase;
+}
+
+.text-uppercase {
+ text-transform: uppercase;
+}
+
+.text-capitalize {
+ text-transform: capitalize;
+}
+
+.text-muted {
+ color: #777777;
+}
+
+.text-primary {
+ color: #165A72;
+}
+
+a.text-primary:hover {
+ color: #286193;
+}
+
+.text-success {
+ color: #5cb85c;
+}
+
+a.text-success:hover {
+ color: #449d44;
+}
+
+.text-info {
+ color: #5bc0de;
+}
+
+a.text-info:hover {
+ color: #31b0d5;
+}
+
+.text-warning {
+ color: #f0ad4e;
+}
+
+a.text-warning:hover {
+ color: #ec971f;
+}
+
+.text-danger {
+ color: #d9534f;
+}
+
+a.text-danger:hover {
+ color: #c9302c;
+}
+
+.bg-primary {
+ color: #fff;
+ background-color: #337cbb;
+}
+
+a.bg-primary:hover {
+ background-color: #286193;
+}
+
+.bg-success {
+ background-color: #a3d7a3;
+}
+
+a.bg-success:hover {
+ background-color: #80c780;
+}
+
+.bg-info {
+ background-color: #b0e1ef;
+}
+
+a.bg-info:hover {
+ background-color: #85d0e7;
+}
+
+.bg-warning {
+ background-color: #f8d9ac;
+}
+
+a.bg-warning:hover {
+ background-color: #f4c37d;
+}
+
+.bg-danger {
+ background-color: #eba5a3;
+}
+
+a.bg-danger:hover {
+ background-color: #e27c79;
+}
+
+.page-header {
+ padding-bottom: 9px;
+ margin: 40px 0 20px;
+ border-bottom: 1px solid #eeeeee;
+}
+
+ul,
+ol {
+ margin-top: 0;
+ margin-bottom: 10px;
+}
+
+ul ul,
+ol ul,
+ul ol,
+ol ol {
+ margin-bottom: 0;
+}
+
+.list-unstyled {
+ padding-left: 0;
+ list-style: none;
+}
+
+.list-inline {
+ padding-left: 0;
+ list-style: none;
+ margin-left: -5px;
+}
+
+.list-inline > li {
+ display: inline-block;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+dl {
+ margin-top: 0;
+ margin-bottom: 20px;
+}
+
+dt,
+dd {
+ line-height: 1.42857143;
+}
+
+dt {
+ font-weight: bold;
+}
+
+dd {
+ margin-left: 0;
+}
+
+@media (min-width: 768px) {
+ .dl-horizontal dt {
+ float: left;
+ width: 160px;
+ clear: left;
+ text-align: right;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .dl-horizontal dd {
+ margin-left: 180px;
+ }
+}
+
+abbr[title],
+abbr[data-original-title] {
+ cursor: help;
+ border-bottom: 1px dotted #777777;
+}
+
+.initialism {
+ font-size: 90%;
+ text-transform: uppercase;
+}
+
+blockquote {
+ padding: 10px 20px;
+ margin: 0 0 20px;
+ font-size: 17.5px;
+ border-left: 5px solid #eeeeee;
+}
+
+blockquote p:last-child,
+blockquote ul:last-child,
+blockquote ol:last-child {
+ margin-bottom: 0;
+}
+
+blockquote footer,
+blockquote small,
+blockquote .small {
+ display: block;
+ font-size: 80%;
+ line-height: 1.42857143;
+ color: #777777;
+}
+
+blockquote footer:before,
+blockquote small:before,
+blockquote .small:before {
+ content: '\2014 \00A0';
+}
+
+.blockquote-reverse,
+blockquote.pull-right {
+ padding-right: 15px;
+ padding-left: 0;
+ border-right: 5px solid #eeeeee;
+ border-left: 0;
+ text-align: right;
+}
+
+.blockquote-reverse footer:before,
+blockquote.pull-right footer:before,
+.blockquote-reverse small:before,
+blockquote.pull-right small:before,
+.blockquote-reverse .small:before,
+blockquote.pull-right .small:before {
+ content: '';
+}
+
+.blockquote-reverse footer:after,
+blockquote.pull-right footer:after,
+.blockquote-reverse small:after,
+blockquote.pull-right small:after,
+.blockquote-reverse .small:after,
+blockquote.pull-right .small:after {
+ content: '\00A0 \2014';
+}
+
+address {
+ margin-bottom: 20px;
+ font-style: normal;
+ line-height: 1.42857143;
+}
+
+code,
+kbd,
+pre,
+samp {
+ font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+}
+
+code {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #c7254e;
+ background-color: #f9f2f4;
+ border-radius: 4px;
+}
+
+kbd {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #ffffff;
+ background-color: #333333;
+ border-radius: 2px;
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
+}
+
+kbd kbd {
+ padding: 0;
+ font-size: 100%;
+ font-weight: bold;
+ box-shadow: none;
+}
+
+pre {
+ display: block;
+ padding: 9.5px;
+ margin: 0 0 10px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ word-break: break-all;
+ word-wrap: break-word;
+ color: #333333;
+ background-color: #f5f5f5;
+ border: 1px solid #cccccc;
+ border-radius: 4px;
+}
+
+pre code {
+ padding: 0;
+ font-size: inherit;
+ color: inherit;
+ white-space: pre-wrap;
+ background-color: transparent;
+ border-radius: 0;
+}
+
+.pre-scrollable {
+ max-height: 340px;
+ overflow-y: scroll;
+}
+
+.container {
+ margin-right: auto;
+ margin-left: auto;
+ padding-left: 15px;
+ padding-right: 15px;
+}
+
+@media (min-width: 768px) {
+ .container {
+ width: 750px;
+ }
+}
+
+@media (min-width: 992px) {
+ .container {
+ width: 970px;
+ }
+}
+
+@media (min-width: 1200px) {
+ .container {
+ width: 1170px;
+ }
+}
+
+.container-fluid {
+ margin-right: auto;
+ margin-left: auto;
+ padding-left: 15px;
+ padding-right: 15px;
+}
+
+.row {
+ margin-left: -15px;
+ margin-right: -15px;
+}
+
+.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
+ position: relative;
+ min-height: 1px;
+ padding-left: 15px;
+ padding-right: 15px;
+}
+
+.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
+ float: left;
+}
+
+.col-xs-12 {
+ width: 100%;
+}
+
+.col-xs-11 {
+ width: 91.66666667%;
+}
+
+.col-xs-10 {
+ width: 83.33333333%;
+}
+
+.col-xs-9 {
+ width: 75%;
+}
+
+.col-xs-8 {
+ width: 66.66666667%;
+}
+
+.col-xs-7 {
+ width: 58.33333333%;
+}
+
+.col-xs-6 {
+ width: 50%;
+}
+
+.col-xs-5 {
+ width: 41.66666667%;
+}
+
+.col-xs-4 {
+ width: 33.33333333%;
+}
+
+.col-xs-3 {
+ width: 25%;
+}
+
+.col-xs-2 {
+ width: 16.66666667%;
+}
+
+.col-xs-1 {
+ width: 8.33333333%;
+}
+
+.col-xs-pull-12 {
+ right: 100%;
+}
+
+.col-xs-pull-11 {
+ right: 91.66666667%;
+}
+
+.col-xs-pull-10 {
+ right: 83.33333333%;
+}
+
+.col-xs-pull-9 {
+ right: 75%;
+}
+
+.col-xs-pull-8 {
+ right: 66.66666667%;
+}
+
+.col-xs-pull-7 {
+ right: 58.33333333%;
+}
+
+.col-xs-pull-6 {
+ right: 50%;
+}
+
+.col-xs-pull-5 {
+ right: 41.66666667%;
+}
+
+.col-xs-pull-4 {
+ right: 33.33333333%;
+}
+
+.col-xs-pull-3 {
+ right: 25%;
+}
+
+.col-xs-pull-2 {
+ right: 16.66666667%;
+}
+
+.col-xs-pull-1 {
+ right: 8.33333333%;
+}
+
+.col-xs-pull-0 {
+ right: auto;
+}
+
+.col-xs-push-12 {
+ left: 100%;
+}
+
+.col-xs-push-11 {
+ left: 91.66666667%;
+}
+
+.col-xs-push-10 {
+ left: 83.33333333%;
+}
+
+.col-xs-push-9 {
+ left: 75%;
+}
+
+.col-xs-push-8 {
+ left: 66.66666667%;
+}
+
+.col-xs-push-7 {
+ left: 58.33333333%;
+}
+
+.col-xs-push-6 {
+ left: 50%;
+}
+
+.col-xs-push-5 {
+ left: 41.66666667%;
+}
+
+.col-xs-push-4 {
+ left: 33.33333333%;
+}
+
+.col-xs-push-3 {
+ left: 25%;
+}
+
+.col-xs-push-2 {
+ left: 16.66666667%;
+}
+
+.col-xs-push-1 {
+ left: 8.33333333%;
+}
+
+.col-xs-push-0 {
+ left: auto;
+}
+
+.col-xs-offset-12 {
+ margin-left: 100%;
+}
+
+.col-xs-offset-11 {
+ margin-left: 91.66666667%;
+}
+
+.col-xs-offset-10 {
+ margin-left: 83.33333333%;
+}
+
+.col-xs-offset-9 {
+ margin-left: 75%;
+}
+
+.col-xs-offset-8 {
+ margin-left: 66.66666667%;
+}
+
+.col-xs-offset-7 {
+ margin-left: 58.33333333%;
+}
+
+.col-xs-offset-6 {
+ margin-left: 50%;
+}
+
+.col-xs-offset-5 {
+ margin-left: 41.66666667%;
+}
+
+.col-xs-offset-4 {
+ margin-left: 33.33333333%;
+}
+
+.col-xs-offset-3 {
+ margin-left: 25%;
+}
+
+.col-xs-offset-2 {
+ margin-left: 16.66666667%;
+}
+
+.col-xs-offset-1 {
+ margin-left: 8.33333333%;
+}
+
+.col-xs-offset-0 {
+ margin-left: 0%;
+}
+
+@media (min-width: 768px) {
+ .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
+ float: left;
+ }
+
+ .col-sm-12 {
+ width: 100%;
+ }
+
+ .col-sm-11 {
+ width: 91.66666667%;
+ }
+
+ .col-sm-10 {
+ width: 83.33333333%;
+ }
+
+ .col-sm-9 {
+ width: 75%;
+ }
+
+ .col-sm-8 {
+ width: 66.66666667%;
+ }
+
+ .col-sm-7 {
+ width: 58.33333333%;
+ }
+
+ .col-sm-6 {
+ width: 50%;
+ }
+
+ .col-sm-5 {
+ width: 41.66666667%;
+ }
+
+ .col-sm-4 {
+ width: 33.33333333%;
+ }
+
+ .col-sm-3 {
+ width: 25%;
+ }
+
+ .col-sm-2 {
+ width: 16.66666667%;
+ }
+
+ .col-sm-1 {
+ width: 8.33333333%;
+ }
+
+ .col-sm-pull-12 {
+ right: 100%;
+ }
+
+ .col-sm-pull-11 {
+ right: 91.66666667%;
+ }
+
+ .col-sm-pull-10 {
+ right: 83.33333333%;
+ }
+
+ .col-sm-pull-9 {
+ right: 75%;
+ }
+
+ .col-sm-pull-8 {
+ right: 66.66666667%;
+ }
+
+ .col-sm-pull-7 {
+ right: 58.33333333%;
+ }
+
+ .col-sm-pull-6 {
+ right: 50%;
+ }
+
+ .col-sm-pull-5 {
+ right: 41.66666667%;
+ }
+
+ .col-sm-pull-4 {
+ right: 33.33333333%;
+ }
+
+ .col-sm-pull-3 {
+ right: 25%;
+ }
+
+ .col-sm-pull-2 {
+ right: 16.66666667%;
+ }
+
+ .col-sm-pull-1 {
+ right: 8.33333333%;
+ }
+
+ .col-sm-pull-0 {
+ right: auto;
+ }
+
+ .col-sm-push-12 {
+ left: 100%;
+ }
+
+ .col-sm-push-11 {
+ left: 91.66666667%;
+ }
+
+ .col-sm-push-10 {
+ left: 83.33333333%;
+ }
+
+ .col-sm-push-9 {
+ left: 75%;
+ }
+
+ .col-sm-push-8 {
+ left: 66.66666667%;
+ }
+
+ .col-sm-push-7 {
+ left: 58.33333333%;
+ }
+
+ .col-sm-push-6 {
+ left: 50%;
+ }
+
+ .col-sm-push-5 {
+ left: 41.66666667%;
+ }
+
+ .col-sm-push-4 {
+ left: 33.33333333%;
+ }
+
+ .col-sm-push-3 {
+ left: 25%;
+ }
+
+ .col-sm-push-2 {
+ left: 16.66666667%;
+ }
+
+ .col-sm-push-1 {
+ left: 8.33333333%;
+ }
+
+ .col-sm-push-0 {
+ left: auto;
+ }
+
+ .col-sm-offset-12 {
+ margin-left: 100%;
+ }
+
+ .col-sm-offset-11 {
+ margin-left: 91.66666667%;
+ }
+
+ .col-sm-offset-10 {
+ margin-left: 83.33333333%;
+ }
+
+ .col-sm-offset-9 {
+ margin-left: 75%;
+ }
+
+ .col-sm-offset-8 {
+ margin-left: 66.66666667%;
+ }
+
+ .col-sm-offset-7 {
+ margin-left: 58.33333333%;
+ }
+
+ .col-sm-offset-6 {
+ margin-left: 50%;
+ }
+
+ .col-sm-offset-5 {
+ margin-left: 41.66666667%;
+ }
+
+ .col-sm-offset-4 {
+ margin-left: 33.33333333%;
+ }
+
+ .col-sm-offset-3 {
+ margin-left: 25%;
+ }
+
+ .col-sm-offset-2 {
+ margin-left: 16.66666667%;
+ }
+
+ .col-sm-offset-1 {
+ margin-left: 8.33333333%;
+ }
+
+ .col-sm-offset-0 {
+ margin-left: 0%;
+ }
+}
+
+@media (min-width: 992px) {
+ .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
+ float: left;
+ }
+
+ .col-md-12 {
+ width: 100%;
+ }
+
+ .col-md-11 {
+ width: 91.66666667%;
+ }
+
+ .col-md-10 {
+ width: 83.33333333%;
+ }
+
+ .col-md-9 {
+ width: 75%;
+ }
+
+ .col-md-8 {
+ width: 66.66666667%;
+ }
+
+ .col-md-7 {
+ width: 58.33333333%;
+ }
+
+ .col-md-6 {
+ width: 50%;
+ }
+
+ .col-md-5 {
+ width: 41.66666667%;
+ }
+
+ .col-md-4 {
+ width: 33.33333333%;
+ }
+
+ .col-md-3 {
+ width: 25%;
+ }
+
+ .col-md-2 {
+ width: 16.66666667%;
+ }
+
+ .col-md-1 {
+ width: 8.33333333%;
+ }
+
+ .col-md-pull-12 {
+ right: 100%;
+ }
+
+ .col-md-pull-11 {
+ right: 91.66666667%;
+ }
+
+ .col-md-pull-10 {
+ right: 83.33333333%;
+ }
+
+ .col-md-pull-9 {
+ right: 75%;
+ }
+
+ .col-md-pull-8 {
+ right: 66.66666667%;
+ }
+
+ .col-md-pull-7 {
+ right: 58.33333333%;
+ }
+
+ .col-md-pull-6 {
+ right: 50%;
+ }
+
+ .col-md-pull-5 {
+ right: 41.66666667%;
+ }
+
+ .col-md-pull-4 {
+ right: 33.33333333%;
+ }
+
+ .col-md-pull-3 {
+ right: 25%;
+ }
+
+ .col-md-pull-2 {
+ right: 16.66666667%;
+ }
+
+ .col-md-pull-1 {
+ right: 8.33333333%;
+ }
+
+ .col-md-pull-0 {
+ right: auto;
+ }
+
+ .col-md-push-12 {
+ left: 100%;
+ }
+
+ .col-md-push-11 {
+ left: 91.66666667%;
+ }
+
+ .col-md-push-10 {
+ left: 83.33333333%;
+ }
+
+ .col-md-push-9 {
+ left: 75%;
+ }
+
+ .col-md-push-8 {
+ left: 66.66666667%;
+ }
+
+ .col-md-push-7 {
+ left: 58.33333333%;
+ }
+
+ .col-md-push-6 {
+ left: 50%;
+ }
+
+ .col-md-push-5 {
+ left: 41.66666667%;
+ }
+
+ .col-md-push-4 {
+ left: 33.33333333%;
+ }
+
+ .col-md-push-3 {
+ left: 25%;
+ }
+
+ .col-md-push-2 {
+ left: 16.66666667%;
+ }
+
+ .col-md-push-1 {
+ left: 8.33333333%;
+ }
+
+ .col-md-push-0 {
+ left: auto;
+ }
+
+ .col-md-offset-12 {
+ margin-left: 100%;
+ }
+
+ .col-md-offset-11 {
+ margin-left: 91.66666667%;
+ }
+
+ .col-md-offset-10 {
+ margin-left: 83.33333333%;
+ }
+
+ .col-md-offset-9 {
+ margin-left: 75%;
+ }
+
+ .col-md-offset-8 {
+ margin-left: 66.66666667%;
+ }
+
+ .col-md-offset-7 {
+ margin-left: 58.33333333%;
+ }
+
+ .col-md-offset-6 {
+ margin-left: 50%;
+ }
+
+ .col-md-offset-5 {
+ margin-left: 41.66666667%;
+ }
+
+ .col-md-offset-4 {
+ margin-left: 33.33333333%;
+ }
+
+ .col-md-offset-3 {
+ margin-left: 25%;
+ }
+
+ .col-md-offset-2 {
+ margin-left: 16.66666667%;
+ }
+
+ .col-md-offset-1 {
+ margin-left: 8.33333333%;
+ }
+
+ .col-md-offset-0 {
+ margin-left: 0%;
+ }
+}
+
+@media (min-width: 1200px) {
+ .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
+ float: left;
+ }
+
+ .col-lg-12 {
+ width: 100%;
+ }
+
+ .col-lg-11 {
+ width: 91.66666667%;
+ }
+
+ .col-lg-10 {
+ width: 83.33333333%;
+ }
+
+ .col-lg-9 {
+ width: 75%;
+ }
+
+ .col-lg-8 {
+ width: 66.66666667%;
+ }
+
+ .col-lg-7 {
+ width: 58.33333333%;
+ }
+
+ .col-lg-6 {
+ width: 50%;
+ }
+
+ .col-lg-5 {
+ width: 41.66666667%;
+ }
+
+ .col-lg-4 {
+ width: 33.33333333%;
+ }
+
+ .col-lg-3 {
+ width: 25%;
+ }
+
+ .col-lg-2 {
+ width: 16.66666667%;
+ }
+
+ .col-lg-1 {
+ width: 8.33333333%;
+ }
+
+ .col-lg-pull-12 {
+ right: 100%;
+ }
+
+ .col-lg-pull-11 {
+ right: 91.66666667%;
+ }
+
+ .col-lg-pull-10 {
+ right: 83.33333333%;
+ }
+
+ .col-lg-pull-9 {
+ right: 75%;
+ }
+
+ .col-lg-pull-8 {
+ right: 66.66666667%;
+ }
+
+ .col-lg-pull-7 {
+ right: 58.33333333%;
+ }
+
+ .col-lg-pull-6 {
+ right: 50%;
+ }
+
+ .col-lg-pull-5 {
+ right: 41.66666667%;
+ }
+
+ .col-lg-pull-4 {
+ right: 33.33333333%;
+ }
+
+ .col-lg-pull-3 {
+ right: 25%;
+ }
+
+ .col-lg-pull-2 {
+ right: 16.66666667%;
+ }
+
+ .col-lg-pull-1 {
+ right: 8.33333333%;
+ }
+
+ .col-lg-pull-0 {
+ right: auto;
+ }
+
+ .col-lg-push-12 {
+ left: 100%;
+ }
+
+ .col-lg-push-11 {
+ left: 91.66666667%;
+ }
+
+ .col-lg-push-10 {
+ left: 83.33333333%;
+ }
+
+ .col-lg-push-9 {
+ left: 75%;
+ }
+
+ .col-lg-push-8 {
+ left: 66.66666667%;
+ }
+
+ .col-lg-push-7 {
+ left: 58.33333333%;
+ }
+
+ .col-lg-push-6 {
+ left: 50%;
+ }
+
+ .col-lg-push-5 {
+ left: 41.66666667%;
+ }
+
+ .col-lg-push-4 {
+ left: 33.33333333%;
+ }
+
+ .col-lg-push-3 {
+ left: 25%;
+ }
+
+ .col-lg-push-2 {
+ left: 16.66666667%;
+ }
+
+ .col-lg-push-1 {
+ left: 8.33333333%;
+ }
+
+ .col-lg-push-0 {
+ left: auto;
+ }
+
+ .col-lg-offset-12 {
+ margin-left: 100%;
+ }
+
+ .col-lg-offset-11 {
+ margin-left: 91.66666667%;
+ }
+
+ .col-lg-offset-10 {
+ margin-left: 83.33333333%;
+ }
+
+ .col-lg-offset-9 {
+ margin-left: 75%;
+ }
+
+ .col-lg-offset-8 {
+ margin-left: 66.66666667%;
+ }
+
+ .col-lg-offset-7 {
+ margin-left: 58.33333333%;
+ }
+
+ .col-lg-offset-6 {
+ margin-left: 50%;
+ }
+
+ .col-lg-offset-5 {
+ margin-left: 41.66666667%;
+ }
+
+ .col-lg-offset-4 {
+ margin-left: 33.33333333%;
+ }
+
+ .col-lg-offset-3 {
+ margin-left: 25%;
+ }
+
+ .col-lg-offset-2 {
+ margin-left: 16.66666667%;
+ }
+
+ .col-lg-offset-1 {
+ margin-left: 8.33333333%;
+ }
+
+ .col-lg-offset-0 {
+ margin-left: 0%;
+ }
+}
+
+table {
+ background-color: transparent;
+}
+
+caption {
+ padding-top: 8px;
+ padding-bottom: 8px;
+ color: #777777;
+ text-align: left;
+}
+
+th {
+ text-align: left;
+}
+
+.table {
+ width: 100%;
+ max-width: 100%;
+ margin-bottom: 20px;
+}
+
+.table > thead > tr > th,
+.table > tbody > tr > th,
+.table > tfoot > tr > th,
+.table > thead > tr > td,
+.table > tbody > tr > td,
+.table > tfoot > tr > td {
+ padding: 8px;
+ line-height: 1.42857143;
+ vertical-align: top;
+ border-top: 1px solid #dddddd;
+}
+
+.table > thead > tr > th {
+ vertical-align: bottom;
+ border-bottom: 2px solid #dddddd;
+}
+
+.table > caption + thead > tr:first-child > th,
+.table > colgroup + thead > tr:first-child > th,
+.table > thead:first-child > tr:first-child > th,
+.table > caption + thead > tr:first-child > td,
+.table > colgroup + thead > tr:first-child > td,
+.table > thead:first-child > tr:first-child > td {
+ border-top: 0;
+}
+
+.table > tbody + tbody {
+ border-top: 2px solid #dddddd;
+}
+
+.table .table {
+ background-color: #ffffff;
+}
+
+.table-condensed > thead > tr > th,
+.table-condensed > tbody > tr > th,
+.table-condensed > tfoot > tr > th,
+.table-condensed > thead > tr > td,
+.table-condensed > tbody > tr > td,
+.table-condensed > tfoot > tr > td {
+ padding: 5px;
+}
+
+.table-bordered {
+ border: 1px solid #dddddd;
+}
+
+.table-bordered > thead > tr > th,
+.table-bordered > tbody > tr > th,
+.table-bordered > tfoot > tr > th,
+.table-bordered > thead > tr > td,
+.table-bordered > tbody > tr > td,
+.table-bordered > tfoot > tr > td {
+ border: 1px solid #dddddd;
+}
+
+.table-bordered > thead > tr > th,
+.table-bordered > thead > tr > td {
+ border-bottom-width: 2px;
+}
+
+.table-striped > tbody > tr:nth-of-type(odd) {
+ background-color: #f9f9f9;
+}
+
+.table-hover > tbody > tr:hover {
+ background-color: #f5f5f5;
+}
+
+table col[class*="col-"] {
+ position: static;
+ float: none;
+ display: table-column;
+}
+
+table td[class*="col-"],
+table th[class*="col-"] {
+ position: static;
+ float: none;
+ display: table-cell;
+}
+
+.table > thead > tr > td.active,
+.table > tbody > tr > td.active,
+.table > tfoot > tr > td.active,
+.table > thead > tr > th.active,
+.table > tbody > tr > th.active,
+.table > tfoot > tr > th.active,
+.table > thead > tr.active > td,
+.table > tbody > tr.active > td,
+.table > tfoot > tr.active > td,
+.table > thead > tr.active > th,
+.table > tbody > tr.active > th,
+.table > tfoot > tr.active > th {
+ background-color: #f5f5f5;
+}
+
+.table-hover > tbody > tr > td.active:hover,
+.table-hover > tbody > tr > th.active:hover,
+.table-hover > tbody > tr.active:hover > td,
+.table-hover > tbody > tr:hover > .active,
+.table-hover > tbody > tr.active:hover > th {
+ background-color: #e8e8e8;
+}
+
+.table > thead > tr > td.success,
+.table > tbody > tr > td.success,
+.table > tfoot > tr > td.success,
+.table > thead > tr > th.success,
+.table > tbody > tr > th.success,
+.table > tfoot > tr > th.success,
+.table > thead > tr.success > td,
+.table > tbody > tr.success > td,
+.table > tfoot > tr.success > td,
+.table > thead > tr.success > th,
+.table > tbody > tr.success > th,
+.table > tfoot > tr.success > th {
+ background-color: #a3d7a3;
+}
+
+.table-hover > tbody > tr > td.success:hover,
+.table-hover > tbody > tr > th.success:hover,
+.table-hover > tbody > tr.success:hover > td,
+.table-hover > tbody > tr:hover > .success,
+.table-hover > tbody > tr.success:hover > th {
+ background-color: #91cf91;
+}
+
+.table > thead > tr > td.info,
+.table > tbody > tr > td.info,
+.table > tfoot > tr > td.info,
+.table > thead > tr > th.info,
+.table > tbody > tr > th.info,
+.table > tfoot > tr > th.info,
+.table > thead > tr.info > td,
+.table > tbody > tr.info > td,
+.table > tfoot > tr.info > td,
+.table > thead > tr.info > th,
+.table > tbody > tr.info > th,
+.table > tfoot > tr.info > th {
+ background-color: #b0e1ef;
+}
+
+.table-hover > tbody > tr > td.info:hover,
+.table-hover > tbody > tr > th.info:hover,
+.table-hover > tbody > tr.info:hover > td,
+.table-hover > tbody > tr:hover > .info,
+.table-hover > tbody > tr.info:hover > th {
+ background-color: #9bd8eb;
+}
+
+.table > thead > tr > td.warning,
+.table > tbody > tr > td.warning,
+.table > tfoot > tr > td.warning,
+.table > thead > tr > th.warning,
+.table > tbody > tr > th.warning,
+.table > tfoot > tr > th.warning,
+.table > thead > tr.warning > td,
+.table > tbody > tr.warning > td,
+.table > tfoot > tr.warning > td,
+.table > thead > tr.warning > th,
+.table > tbody > tr.warning > th,
+.table > tfoot > tr.warning > th {
+ background-color: #f8d9ac;
+}
+
+.table-hover > tbody > tr > td.warning:hover,
+.table-hover > tbody > tr > th.warning:hover,
+.table-hover > tbody > tr.warning:hover > td,
+.table-hover > tbody > tr:hover > .warning,
+.table-hover > tbody > tr.warning:hover > th {
+ background-color: #f6ce95;
+}
+
+.table > thead > tr > td.danger,
+.table > tbody > tr > td.danger,
+.table > tfoot > tr > td.danger,
+.table > thead > tr > th.danger,
+.table > tbody > tr > th.danger,
+.table > tfoot > tr > th.danger,
+.table > thead > tr.danger > td,
+.table > tbody > tr.danger > td,
+.table > tfoot > tr.danger > td,
+.table > thead > tr.danger > th,
+.table > tbody > tr.danger > th,
+.table > tfoot > tr.danger > th {
+ background-color: #eba5a3;
+}
+
+.table-hover > tbody > tr > td.danger:hover,
+.table-hover > tbody > tr > th.danger:hover,
+.table-hover > tbody > tr.danger:hover > td,
+.table-hover > tbody > tr:hover > .danger,
+.table-hover > tbody > tr.danger:hover > th {
+ background-color: #e7908e;
+}
+
+.table-responsive {
+ overflow-x: auto;
+ min-height: 0.01%;
+}
+
+@media screen and (max-width: 767px) {
+ .table-responsive {
+ width: 100%;
+ margin-bottom: 15px;
+ overflow-y: hidden;
+ -ms-overflow-style: -ms-autohiding-scrollbar;
+ border: 1px solid #dddddd;
+ }
+
+ .table-responsive > .table {
+ margin-bottom: 0;
+ }
+
+ .table-responsive > .table > thead > tr > th,
+ .table-responsive > .table > tbody > tr > th,
+ .table-responsive > .table > tfoot > tr > th,
+ .table-responsive > .table > thead > tr > td,
+ .table-responsive > .table > tbody > tr > td,
+ .table-responsive > .table > tfoot > tr > td {
+ white-space: nowrap;
+ }
+
+ .table-responsive > .table-bordered {
+ border: 0;
+ }
+
+ .table-responsive > .table-bordered > thead > tr > th:first-child,
+ .table-responsive > .table-bordered > tbody > tr > th:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+ .table-responsive > .table-bordered > thead > tr > td:first-child,
+ .table-responsive > .table-bordered > tbody > tr > td:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+ }
+
+ .table-responsive > .table-bordered > thead > tr > th:last-child,
+ .table-responsive > .table-bordered > tbody > tr > th:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+ .table-responsive > .table-bordered > thead > tr > td:last-child,
+ .table-responsive > .table-bordered > tbody > tr > td:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+ }
+
+ .table-responsive > .table-bordered > tbody > tr:last-child > th,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > th,
+ .table-responsive > .table-bordered > tbody > tr:last-child > td,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+ border-bottom: 0;
+ }
+}
+
+fieldset {
+ padding: 0;
+ margin: 0;
+ border: 0;
+ min-width: 0;
+}
+
+legend {
+ display: block;
+ width: 100%;
+ padding: 0;
+ margin-bottom: 20px;
+ font-size: 21px;
+ line-height: inherit;
+ color: #333333;
+ border: 0;
+ border-bottom: 1px solid #e5e5e5;
+}
+
+label {
+ display: inline-block;
+ max-width: 100%;
+ margin-bottom: 5px;
+ font-weight: bold;
+}
+
+input[type="search"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+input[type="radio"],
+input[type="checkbox"] {
+ margin: 4px 0 0;
+ margin-top: 1px \9;
+ line-height: normal;
+}
+
+input[type="file"] {
+ display: block;
+}
+
+input[type="range"] {
+ display: block;
+ width: 100%;
+}
+
+select[multiple],
+select[size] {
+ height: auto;
+}
+
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+output {
+ display: block;
+ padding-top: 7px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555555;
+}
+
+.form-control {
+ display: block;
+ width: 100%;
+ height: 34px;
+ padding: 6px 12px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555555;
+ background-color: #ffffff;
+ background-image: none;
+ border: 1px solid #cccccc;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+
+.form-control:focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);
+}
+
+.form-control::-moz-placeholder {
+ color: #999999;
+ opacity: 1;
+}
+
+.form-control:-ms-input-placeholder {
+ color: #999999;
+}
+
+.form-control::-webkit-input-placeholder {
+ color: #999999;
+}
+
+.form-control[disabled],
+.form-control[readonly],
+fieldset[disabled] .form-control {
+ background-color: #eeeeee;
+ opacity: 1;
+}
+
+.form-control[disabled],
+fieldset[disabled] .form-control {
+ cursor: not-allowed;
+}
+
+textarea.form-control {
+ height: auto;
+}
+
+input[type="search"] {
+ -webkit-appearance: none;
+}
+
+@media screen and (-webkit-min-device-pixel-ratio: 0) {
+ input[type="date"],
+ input[type="time"],
+ input[type="datetime-local"],
+ input[type="month"] {
+ line-height: 34px;
+ }
+
+ input[type="date"].input-sm,
+ input[type="time"].input-sm,
+ input[type="datetime-local"].input-sm,
+ input[type="month"].input-sm,
+ .input-group-sm input[type="date"],
+ .input-group-sm input[type="time"],
+ .input-group-sm input[type="datetime-local"],
+ .input-group-sm input[type="month"] {
+ line-height: 30px;
+ }
+
+ input[type="date"].input-lg,
+ input[type="time"].input-lg,
+ input[type="datetime-local"].input-lg,
+ input[type="month"].input-lg,
+ .input-group-lg input[type="date"],
+ .input-group-lg input[type="time"],
+ .input-group-lg input[type="datetime-local"],
+ .input-group-lg input[type="month"] {
+ line-height: 46px;
+ }
+}
+
+.form-group {
+ margin-bottom: 15px;
+}
+
+.radio,
+.checkbox {
+ position: relative;
+ display: block;
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+.radio label,
+.checkbox label {
+ min-height: 20px;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ cursor: pointer;
+}
+
+.radio input[type="radio"],
+.radio-inline input[type="radio"],
+.checkbox input[type="checkbox"],
+.checkbox-inline input[type="checkbox"] {
+ position: absolute;
+ margin-left: -20px;
+ margin-top: 4px \9;
+}
+
+.radio + .radio,
+.checkbox + .checkbox {
+ margin-top: -5px;
+}
+
+.radio-inline,
+.checkbox-inline {
+ position: relative;
+ display: inline-block;
+ padding-left: 20px;
+ margin-bottom: 0;
+ vertical-align: middle;
+ font-weight: normal;
+ cursor: pointer;
+}
+
+.radio-inline + .radio-inline,
+.checkbox-inline + .checkbox-inline {
+ margin-top: 0;
+ margin-left: 10px;
+}
+
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+input[type="radio"].disabled,
+input[type="checkbox"].disabled,
+fieldset[disabled] input[type="radio"],
+fieldset[disabled] input[type="checkbox"] {
+ cursor: not-allowed;
+}
+
+.radio-inline.disabled,
+.checkbox-inline.disabled,
+fieldset[disabled] .radio-inline,
+fieldset[disabled] .checkbox-inline {
+ cursor: not-allowed;
+}
+
+.radio.disabled label,
+.checkbox.disabled label,
+fieldset[disabled] .radio label,
+fieldset[disabled] .checkbox label {
+ cursor: not-allowed;
+}
+
+.form-control-static {
+ padding-top: 7px;
+ padding-bottom: 7px;
+ margin-bottom: 0;
+ min-height: 34px;
+}
+
+.form-control-static.input-lg,
+.form-control-static.input-sm {
+ padding-left: 0;
+ padding-right: 0;
+}
+
+.input-sm {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 2px;
+}
+
+select.input-sm {
+ height: 30px;
+ line-height: 30px;
+}
+
+textarea.input-sm,
+select[multiple].input-sm {
+ height: auto;
+}
+
+.form-group-sm .form-control {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 2px;
+}
+
+select.form-group-sm .form-control {
+ height: 30px;
+ line-height: 30px;
+}
+
+textarea.form-group-sm .form-control,
+select[multiple].form-group-sm .form-control {
+ height: auto;
+}
+
+.form-group-sm .form-control-static {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ min-height: 32px;
+}
+
+.input-lg {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 5px;
+}
+
+select.input-lg {
+ height: 46px;
+ line-height: 46px;
+}
+
+textarea.input-lg,
+select[multiple].input-lg {
+ height: auto;
+}
+
+.form-group-lg .form-control {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 5px;
+}
+
+select.form-group-lg .form-control {
+ height: 46px;
+ line-height: 46px;
+}
+
+textarea.form-group-lg .form-control,
+select[multiple].form-group-lg .form-control {
+ height: auto;
+}
+
+.form-group-lg .form-control-static {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ min-height: 38px;
+}
+
+.has-feedback {
+ position: relative;
+}
+
+.has-feedback .form-control {
+ padding-right: 42.5px;
+}
+
+.form-control-feedback {
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: 2;
+ display: block;
+ width: 34px;
+ height: 34px;
+ line-height: 34px;
+ text-align: center;
+ pointer-events: none;
+}
+
+.input-lg + .form-control-feedback {
+ width: 46px;
+ height: 46px;
+ line-height: 46px;
+}
+
+.input-sm + .form-control-feedback {
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+}
+
+.has-success .help-block,
+.has-success .control-label,
+.has-success .radio,
+.has-success .checkbox,
+.has-success .radio-inline,
+.has-success .checkbox-inline,
+.has-success.radio label,
+.has-success.checkbox label,
+.has-success.radio-inline label,
+.has-success.checkbox-inline label {
+ color: #5cb85c;
+}
+
+.has-success .form-control {
+ border-color: #5cb85c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+
+.has-success .form-control:focus {
+ border-color: #449d44;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #a3d7a3;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #a3d7a3;
+}
+
+.has-success .input-group-addon {
+ color: #5cb85c;
+ border-color: #5cb85c;
+ background-color: #a3d7a3;
+}
+
+.has-success .form-control-feedback {
+ color: #5cb85c;
+}
+
+.has-warning .help-block,
+.has-warning .control-label,
+.has-warning .radio,
+.has-warning .checkbox,
+.has-warning .radio-inline,
+.has-warning .checkbox-inline,
+.has-warning.radio label,
+.has-warning.checkbox label,
+.has-warning.radio-inline label,
+.has-warning.checkbox-inline label {
+ color: #f0ad4e;
+}
+
+.has-warning .form-control {
+ border-color: #f0ad4e;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+
+.has-warning .form-control:focus {
+ border-color: #ec971f;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f8d9ac;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f8d9ac;
+}
+
+.has-warning .input-group-addon {
+ color: #f0ad4e;
+ border-color: #f0ad4e;
+ background-color: #f8d9ac;
+}
+
+.has-warning .form-control-feedback {
+ color: #f0ad4e;
+}
+
+.has-error .help-block,
+.has-error .control-label,
+.has-error .radio,
+.has-error .checkbox,
+.has-error .radio-inline,
+.has-error .checkbox-inline,
+.has-error.radio label,
+.has-error.checkbox label,
+.has-error.radio-inline label,
+.has-error.checkbox-inline label {
+ color: #d9534f;
+}
+
+.has-error .form-control {
+ border-color: #d9534f;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+
+.has-error .form-control:focus {
+ border-color: #c9302c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #eba5a3;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #eba5a3;
+}
+
+.has-error .input-group-addon {
+ color: #d9534f;
+ border-color: #d9534f;
+ background-color: #eba5a3;
+}
+
+.has-error .form-control-feedback {
+ color: #d9534f;
+}
+
+.has-feedback label ~ .form-control-feedback {
+ top: 25px;
+}
+
+.has-feedback label.sr-only ~ .form-control-feedback {
+ top: 0;
+}
+
+.help-block {
+ display: block;
+ margin-top: 5px;
+ margin-bottom: 10px;
+ color: #404040;
+}
+
+@media (min-width: 768px) {
+ .form-inline .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .form-inline .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+
+ .form-inline .form-control-static {
+ display: inline-block;
+ }
+
+ .form-inline .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+
+ .form-inline .input-group .input-group-addon,
+ .form-inline .input-group .input-group-btn,
+ .form-inline .input-group .form-control {
+ width: auto;
+ }
+
+ .form-inline .input-group > .form-control {
+ width: 100%;
+ }
+
+ .form-inline .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .form-inline .radio,
+ .form-inline .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .form-inline .radio label,
+ .form-inline .checkbox label {
+ padding-left: 0;
+ }
+
+ .form-inline .radio input[type="radio"],
+ .form-inline .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+
+ .form-inline .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+
+.form-horizontal .radio,
+.form-horizontal .checkbox,
+.form-horizontal .radio-inline,
+.form-horizontal .checkbox-inline {
+ margin-top: 0;
+ margin-bottom: 0;
+ padding-top: 7px;
+}
+
+.form-horizontal .radio,
+.form-horizontal .checkbox {
+ min-height: 27px;
+}
+
+.form-horizontal .form-group {
+ margin-left: -15px;
+ margin-right: -15px;
+}
+
+@media (min-width: 768px) {
+ .form-horizontal .control-label {
+ text-align: right;
+ margin-bottom: 0;
+ padding-top: 7px;
+ }
+}
+
+.form-horizontal .has-feedback .form-control-feedback {
+ right: 15px;
+}
+
+@media (min-width: 768px) {
+ .form-horizontal .form-group-lg .control-label {
+ padding-top: 14.333333px;
+ }
+}
+
+@media (min-width: 768px) {
+ .form-horizontal .form-group-sm .control-label {
+ padding-top: 6px;
+ }
+}
+
+.btn {
+ display: inline-block;
+ margin-bottom: 0;
+ font-weight: normal;
+ text-align: center;
+ vertical-align: middle;
+ touch-action: manipulation;
+ cursor: pointer;
+ background-image: none;
+ border: 1px solid transparent;
+ white-space: nowrap;
+ padding: 6px 12px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ border-radius: 4px;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.btn:focus,
+.btn:active:focus,
+.btn.active:focus,
+.btn.focus,
+.btn:active.focus,
+.btn.active.focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+.btn:hover,
+.btn:focus,
+.btn.focus {
+ color: #000000;
+ text-decoration: none;
+}
+
+.btn:active,
+.btn.active {
+ outline: 0;
+ background-image: none;
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+}
+
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+ cursor: not-allowed;
+ pointer-events: none;
+ opacity: 0.65;
+ filter: alpha(opacity=65);
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.btn-default {
+ color: #ffffff;
+ background-color: #a0ced7;
+ border-color: #9dc8ce;
+}
+
+.btn-default:hover,
+.btn-default:focus,
+.btn-default.focus,
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ color: #ffffff;
+ background-color: #1a6687;
+ border-color: #1a6687;
+}
+
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ background-image: none;
+}
+
+.btn-default.disabled,
+.btn-default[disabled],
+fieldset[disabled] .btn-default,
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled.focus,
+.btn-default[disabled].focus,
+fieldset[disabled] .btn-default.focus,
+.btn-default.disabled:active,
+.btn-default[disabled]:active,
+fieldset[disabled] .btn-default:active,
+.btn-default.disabled.active,
+.btn-default[disabled].active,
+fieldset[disabled] .btn-default.active {
+ background-color: #ffffff;
+ border-color: #a0ced7;
+}
+
+.btn-default .badge {
+ color: #ffffff;
+ background-color: #000000;
+}
+
+.btn-primary {
+ color: #ffffff;
+ background-color: #8bc4c9;
+ border-color: #9dc8ce;
+}
+
+.btn-primary:hover,
+.btn-primary:focus,
+.btn-primary.focus,
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ color: #ffffff;
+ background-color: #1a6687;
+ border-color: #165a72;
+}
+
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ background-image: none;
+}
+
+.btn-primary.disabled,
+.btn-primary[disabled],
+fieldset[disabled] .btn-primary,
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled.focus,
+.btn-primary[disabled].focus,
+fieldset[disabled] .btn-primary.focus,
+.btn-primary.disabled:active,
+.btn-primary[disabled]:active,
+fieldset[disabled] .btn-primary:active,
+.btn-primary.disabled.active,
+.btn-primary[disabled].active,
+fieldset[disabled] .btn-primary.active {
+ background-color: #337cbb;
+ border-color: #2e6fa7;
+}
+
+.btn-primary .badge {
+ color: #337cbb;
+ background-color: #ffffff;
+}
+
+.btn-success {
+ color: #ffffff;
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+
+.btn-success:hover,
+.btn-success:focus,
+.btn-success.focus,
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ color: #ffffff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ background-image: none;
+}
+
+.btn-success.disabled,
+.btn-success[disabled],
+fieldset[disabled] .btn-success,
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled.focus,
+.btn-success[disabled].focus,
+fieldset[disabled] .btn-success.focus,
+.btn-success.disabled:active,
+.btn-success[disabled]:active,
+fieldset[disabled] .btn-success:active,
+.btn-success.disabled.active,
+.btn-success[disabled].active,
+fieldset[disabled] .btn-success.active {
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+
+.btn-success .badge {
+ color: #5cb85c;
+ background-color: #ffffff;
+}
+
+.btn-info {
+ color: #ffffff;
+ background-color: #E4762B;
+ border-color: #E28809;
+}
+
+.btn-info:hover,
+.btn-info:focus,
+.btn-info.focus,
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ color: #ffffff;
+ background-color: #E63F0A;
+ border-color: #E63F0A;
+}
+
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ background-image: none;
+}
+
+.btn-info.disabled,
+.btn-info[disabled],
+fieldset[disabled] .btn-info,
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled.focus,
+.btn-info[disabled].focus,
+fieldset[disabled] .btn-info.focus,
+.btn-info.disabled:active,
+.btn-info[disabled]:active,
+fieldset[disabled] .btn-info:active,
+.btn-info.disabled.active,
+.btn-info[disabled].active,
+fieldset[disabled] .btn-info.active {
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+
+.btn-info .badge {
+ color: #5bc0de;
+ background-color: #ffffff;
+}
+
+.btn-warning {
+ color: #ffffff;
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+
+.btn-warning:hover,
+.btn-warning:focus,
+.btn-warning.focus,
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ color: #ffffff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ background-image: none;
+}
+
+.btn-warning.disabled,
+.btn-warning[disabled],
+fieldset[disabled] .btn-warning,
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled.focus,
+.btn-warning[disabled].focus,
+fieldset[disabled] .btn-warning.focus,
+.btn-warning.disabled:active,
+.btn-warning[disabled]:active,
+fieldset[disabled] .btn-warning:active,
+.btn-warning.disabled.active,
+.btn-warning[disabled].active,
+fieldset[disabled] .btn-warning.active {
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+
+.btn-warning .badge {
+ color: #f0ad4e;
+ background-color: #ffffff;
+}
+
+.btn-danger {
+ color: #ffffff;
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+
+.btn-danger:hover,
+.btn-danger:focus,
+.btn-danger.focus,
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ color: #ffffff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ background-image: none;
+}
+
+.btn-danger.disabled,
+.btn-danger[disabled],
+fieldset[disabled] .btn-danger,
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled.focus,
+.btn-danger[disabled].focus,
+fieldset[disabled] .btn-danger.focus,
+.btn-danger.disabled:active,
+.btn-danger[disabled]:active,
+fieldset[disabled] .btn-danger:active,
+.btn-danger.disabled.active,
+.btn-danger[disabled].active,
+fieldset[disabled] .btn-danger.active {
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+
+.btn-danger .badge {
+ color: #d9534f;
+ background-color: #ffffff;
+}
+
+.btn-link {
+ color: #337cbb;
+ font-weight: normal;
+ border-radius: 0;
+}
+
+.btn-link,
+.btn-link:active,
+.btn-link.active,
+.btn-link[disabled],
+fieldset[disabled] .btn-link {
+ background-color: transparent;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.btn-link,
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+ border-color: transparent;
+}
+
+.btn-link:hover,
+.btn-link:focus {
+ color: #23547f;
+ text-decoration: underline;
+ background-color: transparent;
+}
+
+.btn-link[disabled]:hover,
+fieldset[disabled] .btn-link:hover,
+.btn-link[disabled]:focus,
+fieldset[disabled] .btn-link:focus {
+ color: #777777;
+ text-decoration: none;
+}
+
+.btn-lg,
+.btn-group-lg > .btn {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 5px;
+}
+
+.btn-sm,
+.btn-group-sm > .btn {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 2px;
+}
+
+.btn-xs,
+.btn-group-xs > .btn {
+ padding: 1px 5px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 2px;
+}
+
+.btn-block {
+ display: block;
+ width: 100%;
+}
+
+.btn-block + .btn-block {
+ margin-top: 5px;
+}
+
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+ width: 100%;
+}
+
+.fade {
+ opacity: 0;
+ -webkit-transition: opacity 0.15s linear;
+ -o-transition: opacity 0.15s linear;
+ transition: opacity 0.15s linear;
+}
+
+.fade.in {
+ opacity: 1;
+}
+
+.collapse {
+ display: none;
+}
+
+.collapse.in {
+ display: block;
+}
+
+tr.collapse.in {
+ display: table-row;
+}
+
+tbody.collapse.in {
+ display: table-row-group;
+}
+
+.collapsing {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ -webkit-transition-property: height, visibility;
+ transition-property: height, visibility;
+ -webkit-transition-duration: 0.35s;
+ transition-duration: 0.35s;
+ -webkit-transition-timing-function: ease;
+ transition-timing-function: ease;
+}
+
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-left: 2px;
+ vertical-align: middle;
+ border-top: 4px dashed;
+ border-right: 4px solid transparent;
+ border-left: 4px solid transparent;
+}
+
+.dropup,
+.dropdown {
+ position: relative;
+}
+
+.dropdown-toggle:focus {
+ outline: 0;
+}
+
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 1000;
+ display: none;
+ float: left;
+ min-width: 160px;
+ padding: 5px 0;
+ margin: 2px 0 0;
+ list-style: none;
+ font-size: 14px;
+ text-align: left;
+ background-color: #ffffff;
+ border: 1px solid #cccccc;
+ border: 1px solid rgba(0, 0, 0, 0.15);
+ border-radius: 4px;
+ -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
+ background-clip: padding-box;
+}
+
+.dropdown-menu.pull-right {
+ right: 0;
+ left: auto;
+}
+
+.dropdown-menu .divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+
+.dropdown-menu > li > a {
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: normal;
+ line-height: 1.42857143;
+ color: #333333;
+ white-space: nowrap;
+}
+
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+ text-decoration: none;
+ color: #262626;
+ background-color: #f5f5f5;
+}
+
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+ color: #ffffff;
+ text-decoration: none;
+ outline: 0;
+ background-color: #337cbb;
+}
+
+.dropdown-menu > .disabled > a,
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ color: #777777;
+}
+
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ text-decoration: none;
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ cursor: not-allowed;
+}
+
+.open > .dropdown-menu {
+ display: block;
+}
+
+.open > a {
+ outline: 0;
+}
+
+.dropdown-menu-right {
+ left: auto;
+ right: 0;
+}
+
+.dropdown-menu-left {
+ left: 0;
+ right: auto;
+}
+
+.dropdown-header {
+ display: block;
+ padding: 3px 20px;
+ font-size: 12px;
+ line-height: 1.42857143;
+ color: #777777;
+ white-space: nowrap;
+}
+
+.dropdown-backdrop {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ top: 0;
+ z-index: 990;
+}
+
+.pull-right > .dropdown-menu {
+ right: 0;
+ left: auto;
+}
+
+.dropup .caret,
+.navbar-fixed-bottom .dropdown .caret {
+ border-top: 0;
+ border-bottom: 4px solid;
+ content: "";
+}
+
+.dropup .dropdown-menu,
+.navbar-fixed-bottom .dropdown .dropdown-menu {
+ top: auto;
+ bottom: 100%;
+ margin-bottom: 2px;
+}
+
+@media (min-width: 768px) {
+ .navbar-right .dropdown-menu {
+ left: auto;
+ right: 0;
+ }
+
+ .navbar-right .dropdown-menu-left {
+ left: 0;
+ right: auto;
+ }
+}
+
+.btn-group,
+.btn-group-vertical {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.btn-group > .btn,
+.btn-group-vertical > .btn {
+ position: relative;
+ float: left;
+}
+
+.btn-group > .btn:hover,
+.btn-group-vertical > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group-vertical > .btn:focus,
+.btn-group > .btn:active,
+.btn-group-vertical > .btn:active,
+.btn-group > .btn.active,
+.btn-group-vertical > .btn.active {
+ z-index: 2;
+}
+
+.btn-group .btn + .btn,
+.btn-group .btn + .btn-group,
+.btn-group .btn-group + .btn,
+.btn-group .btn-group + .btn-group {
+ margin-left: -1px;
+}
+
+.btn-toolbar {
+ margin-left: -5px;
+}
+
+.btn-toolbar .btn-group,
+.btn-toolbar .input-group {
+ float: left;
+}
+
+.btn-toolbar > .btn,
+.btn-toolbar > .btn-group,
+.btn-toolbar > .input-group {
+ margin-left: 5px;
+}
+
+.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
+ border-radius: 0;
+}
+
+.btn-group > .btn:first-child {
+ margin-left: 0;
+}
+
+.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
+ border-bottom-right-radius: 0;
+ border-top-right-radius: 0;
+}
+
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
+ border-bottom-left-radius: 0;
+ border-top-left-radius: 0;
+}
+
+.btn-group > .btn-group {
+ float: left;
+}
+
+.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+
+.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-bottom-right-radius: 0;
+ border-top-right-radius: 0;
+}
+
+.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-bottom-left-radius: 0;
+ border-top-left-radius: 0;
+}
+
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+ outline: 0;
+}
+
+.btn-group > .btn + .dropdown-toggle {
+ padding-left: 8px;
+ padding-right: 8px;
+}
+
+.btn-group > .btn-lg + .dropdown-toggle {
+ padding-left: 12px;
+ padding-right: 12px;
+}
+
+.btn-group.open .dropdown-toggle {
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+}
+
+.btn-group.open .dropdown-toggle.btn-link {
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.btn .caret {
+ margin-left: 0;
+}
+
+.btn-lg .caret {
+ border-width: 5px 5px 0;
+ border-bottom-width: 0;
+}
+
+.dropup .btn-lg .caret {
+ border-width: 0 5px 5px;
+}
+
+.btn-group-vertical > .btn,
+.btn-group-vertical > .btn-group,
+.btn-group-vertical > .btn-group > .btn {
+ display: block;
+ float: none;
+ width: 100%;
+ max-width: 100%;
+}
+
+.btn-group-vertical > .btn-group > .btn {
+ float: none;
+}
+
+.btn-group-vertical > .btn + .btn,
+.btn-group-vertical > .btn + .btn-group,
+.btn-group-vertical > .btn-group + .btn,
+.btn-group-vertical > .btn-group + .btn-group {
+ margin-top: -1px;
+ margin-left: 0;
+}
+
+.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+
+.btn-group-vertical > .btn:first-child:not(:last-child) {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.btn-group-vertical > .btn:last-child:not(:first-child) {
+ border-bottom-left-radius: 4px;
+ border-top-right-radius: 0;
+ border-top-left-radius: 0;
+}
+
+.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-top-right-radius: 0;
+ border-top-left-radius: 0;
+}
+
+.btn-group-justified {
+ display: table;
+ width: 100%;
+ table-layout: fixed;
+ border-collapse: separate;
+}
+
+.btn-group-justified > .btn,
+.btn-group-justified > .btn-group {
+ float: none;
+ display: table-cell;
+ width: 1%;
+}
+
+.btn-group-justified > .btn-group .btn {
+ width: 100%;
+}
+
+.btn-group-justified > .btn-group .dropdown-menu {
+ left: auto;
+}
+
+[data-toggle="buttons"] > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn input[type="checkbox"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none;
+}
+
+.input-group {
+ position: relative;
+ display: table;
+ border-collapse: separate;
+}
+
+.input-group[class*="col-"] {
+ float: none;
+ padding-left: 0;
+ padding-right: 0;
+}
+
+.input-group .form-control {
+ position: relative;
+ z-index: 2;
+ float: left;
+ width: 100%;
+ margin-bottom: 0;
+}
+
+.input-group-lg > .form-control,
+.input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 5px;
+}
+
+select.input-group-lg > .form-control,
+select.input-group-lg > .input-group-addon,
+select.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ line-height: 46px;
+}
+
+textarea.input-group-lg > .form-control,
+textarea.input-group-lg > .input-group-addon,
+textarea.input-group-lg > .input-group-btn > .btn,
+select[multiple].input-group-lg > .form-control,
+select[multiple].input-group-lg > .input-group-addon,
+select[multiple].input-group-lg > .input-group-btn > .btn {
+ height: auto;
+}
+
+.input-group-sm > .form-control,
+.input-group-sm > .input-group-addon,
+.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 2px;
+}
+
+select.input-group-sm > .form-control,
+select.input-group-sm > .input-group-addon,
+select.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ line-height: 30px;
+}
+
+textarea.input-group-sm > .form-control,
+textarea.input-group-sm > .input-group-addon,
+textarea.input-group-sm > .input-group-btn > .btn,
+select[multiple].input-group-sm > .form-control,
+select[multiple].input-group-sm > .input-group-addon,
+select[multiple].input-group-sm > .input-group-btn > .btn {
+ height: auto;
+}
+
+.input-group-addon,
+.input-group-btn,
+.input-group .form-control {
+ display: table-cell;
+}
+
+.input-group-addon:not(:first-child):not(:last-child),
+.input-group-btn:not(:first-child):not(:last-child),
+.input-group .form-control:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+
+.input-group-addon,
+.input-group-btn {
+ width: 1%;
+ white-space: nowrap;
+ vertical-align: middle;
+}
+
+.input-group-addon {
+ padding: 6px 12px;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1;
+ color: #555555;
+ text-align: center;
+ background-color: #eeeeee;
+ border: 1px solid #cccccc;
+ border-radius: 4px;
+}
+
+.input-group-addon.input-sm {
+ padding: 5px 10px;
+ font-size: 12px;
+ border-radius: 2px;
+}
+
+.input-group-addon.input-lg {
+ padding: 10px 16px;
+ font-size: 18px;
+ border-radius: 5px;
+}
+
+.input-group-addon input[type="radio"],
+.input-group-addon input[type="checkbox"] {
+ margin-top: 0;
+}
+
+.input-group .form-control:first-child,
+.input-group-addon:first-child,
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group > .btn,
+.input-group-btn:first-child > .dropdown-toggle,
+.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
+.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
+ border-bottom-right-radius: 0;
+ border-top-right-radius: 0;
+}
+
+.input-group-addon:first-child {
+ border-right: 0;
+}
+
+.input-group .form-control:last-child,
+.input-group-addon:last-child,
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group > .btn,
+.input-group-btn:last-child > .dropdown-toggle,
+.input-group-btn:first-child > .btn:not(:first-child),
+.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
+ border-bottom-left-radius: 0;
+ border-top-left-radius: 0;
+}
+
+.input-group-addon:last-child {
+ border-left: 0;
+}
+
+.input-group-btn {
+ position: relative;
+ font-size: 0;
+ white-space: nowrap;
+}
+
+.input-group-btn > .btn {
+ position: relative;
+}
+
+.input-group-btn > .btn + .btn {
+ margin-left: -1px;
+}
+
+.input-group-btn > .btn:hover,
+.input-group-btn > .btn:focus,
+.input-group-btn > .btn:active {
+ z-index: 2;
+}
+
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group {
+ margin-right: -1px;
+}
+
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group {
+ margin-left: -1px;
+}
+
+.nav {
+ margin-bottom: 0;
+ padding-left: 0;
+ list-style: none;
+}
+
+.nav > li {
+ position: relative;
+ display: block;
+}
+
+.nav > li > a {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+}
+
+.nav > li > a:hover,
+.nav > li > a:focus {
+ text-decoration: none;
+ background-color: #eeeeee;
+}
+
+.nav > li.disabled > a {
+ color: #777777;
+}
+
+.nav > li.disabled > a:hover,
+.nav > li.disabled > a:focus {
+ color: #777777;
+ text-decoration: none;
+ background-color: transparent;
+ cursor: not-allowed;
+}
+
+.nav .open > a,
+.nav .open > a:hover,
+.nav .open > a:focus {
+ background-color: #eeeeee;
+ border-color: #337cbb;
+}
+
+.nav .nav-divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+
+.nav > li > a > img {
+ max-width: none;
+}
+
+.nav-tabs {
+ border-bottom: 1px solid #dddddd;
+}
+
+.nav-tabs > li {
+ float: left;
+ margin-bottom: -1px;
+}
+
+.nav-tabs > li > a {
+ margin-right: 2px;
+ line-height: 1.42857143;
+ border: 1px solid transparent;
+ border-radius: 4px 4px 0 0;
+}
+
+.nav-tabs > li > a:hover {
+ border-color: #eeeeee #eeeeee #dddddd;
+}
+
+.nav-tabs > li.active > a,
+.nav-tabs > li.active > a:hover,
+.nav-tabs > li.active > a:focus {
+ color: #555555;
+ background-color: #ffffff;
+ border: 1px solid #dddddd;
+ border-bottom-color: transparent;
+ cursor: default;
+}
+
+.nav-tabs.nav-justified {
+ width: 100%;
+ border-bottom: 0;
+}
+
+.nav-tabs.nav-justified > li {
+ float: none;
+}
+
+.nav-tabs.nav-justified > li > a {
+ text-align: center;
+ margin-bottom: 5px;
+}
+
+.nav-tabs.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+
+ .nav-tabs.nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+
+.nav-tabs.nav-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px;
+}
+
+.nav-tabs.nav-justified > .active > a,
+.nav-tabs.nav-justified > .active > a:hover,
+.nav-tabs.nav-justified > .active > a:focus {
+ border: 1px solid #dddddd;
+}
+
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li > a {
+ border-bottom: 1px solid #dddddd;
+ border-radius: 4px 4px 0 0;
+ }
+
+ .nav-tabs.nav-justified > .active > a,
+ .nav-tabs.nav-justified > .active > a:hover,
+ .nav-tabs.nav-justified > .active > a:focus {
+ border-bottom-color: #ffffff;
+ }
+}
+
+.nav-pills > li {
+ float: left;
+}
+
+.nav-pills > li > a {
+ border-radius: 4px;
+}
+
+.nav-pills > li + li {
+ margin-left: 2px;
+}
+
+.nav-pills > li.active > a,
+.nav-pills > li.active > a:hover,
+.nav-pills > li.active > a:focus {
+ color: #ffffff;
+ background-color: #337cbb;
+}
+
+.nav-stacked > li {
+ float: none;
+}
+
+.nav-stacked > li + li {
+ margin-top: 2px;
+ margin-left: 0;
+}
+
+.nav-justified {
+ width: 100%;
+}
+
+.nav-justified > li {
+ float: none;
+}
+
+.nav-justified > li > a {
+ text-align: center;
+ margin-bottom: 5px;
+}
+
+.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+
+@media (min-width: 768px) {
+ .nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+
+ .nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+
+.nav-tabs-justified {
+ border-bottom: 0;
+}
+
+.nav-tabs-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px;
+}
+
+.nav-tabs-justified > .active > a,
+.nav-tabs-justified > .active > a:hover,
+.nav-tabs-justified > .active > a:focus {
+ border: 1px solid #dddddd;
+}
+
+@media (min-width: 768px) {
+ .nav-tabs-justified > li > a {
+ border-bottom: 1px solid #dddddd;
+ border-radius: 4px 4px 0 0;
+ }
+
+ .nav-tabs-justified > .active > a,
+ .nav-tabs-justified > .active > a:hover,
+ .nav-tabs-justified > .active > a:focus {
+ border-bottom-color: #ffffff;
+ }
+}
+
+.tab-content > .tab-pane {
+ display: none;
+}
+
+.tab-content > .active {
+ display: block;
+}
+
+.nav-tabs .dropdown-menu {
+ margin-top: -1px;
+ border-top-right-radius: 0;
+ border-top-left-radius: 0;
+}
+
+.navbar {
+ position: relative;
+ min-height: 50px;
+ margin-bottom: 0px;
+ border: 1px solid transparent;
+}
+
+@media (min-width: 768px) {
+ .navbar {
+ border-radius: 4px;
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-header {
+ float: left;
+ }
+}
+
+.navbar-collapse {
+ overflow-x: visible;
+ padding-right: 15px;
+ padding-left: 15px;
+ border-top: 1px solid transparent;
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
+ -webkit-overflow-scrolling: touch;
+}
+
+.navbar-collapse.in {
+ overflow-y: auto;
+}
+
+@media (min-width: 768px) {
+ .navbar-collapse {
+ width: auto;
+ border-top: 0;
+ box-shadow: none;
+ }
+
+ .navbar-collapse.collapse {
+ display: block !important;
+ height: auto !important;
+ padding-bottom: 0;
+ overflow: visible !important;
+ }
+
+ .navbar-collapse.in {
+ overflow-y: visible;
+ }
+
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-static-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ padding-left: 0;
+ padding-right: 0;
+ }
+}
+
+.navbar-fixed-top .navbar-collapse,
+.navbar-fixed-bottom .navbar-collapse {
+ max-height: 340px;
+}
+
+@media (max-device-width: 480px) and (orientation: landscape) {
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ max-height: 200px;
+ }
+}
+
+.container > .navbar-header,
+.container-fluid > .navbar-header,
+.container > .navbar-collapse,
+.container-fluid > .navbar-collapse {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+
+@media (min-width: 768px) {
+ .container > .navbar-header,
+ .container-fluid > .navbar-header,
+ .container > .navbar-collapse,
+ .container-fluid > .navbar-collapse {
+ margin-right: 0;
+ margin-left: 0;
+ }
+}
+
+.navbar-static-top {
+ z-index: 1000;
+ border-width: 0 0 1px;
+}
+
+@media (min-width: 768px) {
+ .navbar-static-top {
+ border-radius: 0;
+ }
+}
+
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+ position: fixed;
+ right: 0;
+ left: 0;
+ z-index: 1030;
+}
+
+@media (min-width: 768px) {
+ .navbar-fixed-top,
+ .navbar-fixed-bottom {
+ border-radius: 0;
+ }
+}
+
+.navbar-fixed-top {
+ top: 0;
+ border-width: 0 0 1px;
+}
+
+.navbar-fixed-bottom {
+ bottom: 0;
+ margin-bottom: 0;
+ border-width: 1px 0 0;
+}
+
+.navbar-brand {
+ float: left;
+ padding: 15px 15px;
+ font-size: 18px;
+ line-height: 20px;
+ height: 50px;
+}
+
+.navbar-brand:hover,
+.navbar-brand:focus {
+ text-decoration: none;
+}
+
+.navbar-brand > img {
+ display: block;
+}
+
+@media (min-width: 768px) {
+ .navbar > .container .navbar-brand,
+ .navbar > .container-fluid .navbar-brand {
+ margin-left: -15px;
+ }
+}
+
+.navbar-toggle {
+ position: relative;
+ float: right;
+ margin-right: 15px;
+ padding: 9px 10px;
+ margin-top: 8px;
+ margin-bottom: 8px;
+ background-color: transparent;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+
+.navbar-toggle:focus {
+ outline: 0;
+}
+
+.navbar-toggle .icon-bar {
+ display: block;
+ width: 22px;
+ height: 2px;
+ border-radius: 1px;
+}
+
+.navbar-toggle .icon-bar + .icon-bar {
+ margin-top: 4px;
+}
+
+@media (min-width: 768px) {
+ .navbar-toggle {
+ display: none;
+ }
+}
+
+.navbar-nav {
+ margin: 7.5px -15px;
+}
+
+.navbar-nav > li > a {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ line-height: 20px;
+}
+
+@media (max-width: 767px) {
+ .navbar-nav .open .dropdown-menu {
+ position: static;
+ float: none;
+ width: auto;
+ margin-top: 0;
+ background-color: transparent;
+ border: 0;
+ box-shadow: none;
+ }
+
+ .navbar-nav .open .dropdown-menu > li > a,
+ .navbar-nav .open .dropdown-menu .dropdown-header {
+ padding: 5px 15px 5px 25px;
+ }
+
+ .navbar-nav .open .dropdown-menu > li > a {
+ line-height: 20px;
+ }
+
+ .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-nav .open .dropdown-menu > li > a:focus {
+ background-image: none;
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-nav {
+ float: left;
+ margin: 0;
+ }
+
+ .navbar-nav > li {
+ float: left;
+ }
+
+ .navbar-nav > li > a {
+ padding-top: 15px;
+ padding-bottom: 15px;
+ }
+}
+
+.navbar-form {
+ margin-left: -15px;
+ margin-right: -15px;
+ padding: 10px 15px;
+ border-top: 1px solid transparent;
+ border-bottom: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
+ margin-top: 8px;
+ margin-bottom: 8px;
+}
+
+@media (min-width: 768px) {
+ .navbar-form .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .navbar-form .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+
+ .navbar-form .form-control-static {
+ display: inline-block;
+ }
+
+ .navbar-form .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+
+ .navbar-form .input-group .input-group-addon,
+ .navbar-form .input-group .input-group-btn,
+ .navbar-form .input-group .form-control {
+ width: auto;
+ }
+
+ .navbar-form .input-group > .form-control {
+ width: 100%;
+ }
+
+ .navbar-form .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .navbar-form .radio,
+ .navbar-form .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .navbar-form .radio label,
+ .navbar-form .checkbox label {
+ padding-left: 0;
+ }
+
+ .navbar-form .radio input[type="radio"],
+ .navbar-form .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+
+ .navbar-form .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+
+@media (max-width: 767px) {
+ .navbar-form .form-group {
+ margin-bottom: 5px;
+ }
+
+ .navbar-form .form-group:last-child {
+ margin-bottom: 0;
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-form {
+ width: auto;
+ border: 0;
+ margin-left: 0;
+ margin-right: 0;
+ padding-top: 0;
+ padding-bottom: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+}
+
+.navbar-nav > li > .dropdown-menu {
+ margin-top: 0;
+ border-top-right-radius: 0;
+ border-top-left-radius: 0;
+}
+
+.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
+ margin-bottom: 0;
+ border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.navbar-btn {
+ margin-top: 8px;
+ margin-bottom: 8px;
+}
+
+.navbar-btn.btn-sm {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+.navbar-btn.btn-xs {
+ margin-top: 14px;
+ margin-bottom: 14px;
+}
+
+.navbar-text {
+ margin-top: 15px;
+ margin-bottom: 15px;
+}
+
+@media (min-width: 768px) {
+ .navbar-text {
+ float: left;
+ margin-left: 15px;
+ margin-right: 15px;
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-left {
+ float: left !important;
+ }
+
+ .navbar-right {
+ float: right !important;
+ margin-right: -15px;
+ }
+
+ .navbar-right ~ .navbar-right {
+ margin-right: 0;
+ }
+}
+
+.navbar-default {
+ background-color: #0f1221;
+ border-color: #e7e7e7;
+}
+
+.navbar-default .navbar-brand {
+ color: #000000;
+}
+
+.navbar-default .navbar-brand:hover,
+.navbar-default .navbar-brand:focus {
+ color: #000000;
+ background-color: transparent;
+}
+
+.navbar-default .navbar-text {
+ color: #000000;
+}
+
+.navbar-default .navbar-nav > li > a {
+ color: #000000;
+}
+
+.navbar-default .navbar-nav > li > a:hover,
+.navbar-default .navbar-nav > li > a:focus {
+ color: #000000;
+ background-color: transparent;
+}
+
+.navbar-default .navbar-nav > .active > a,
+.navbar-default .navbar-nav > .active > a:hover,
+.navbar-default .navbar-nav > .active > a:focus {
+ color: #000000;
+ background-color: #e7e7e7;
+}
+
+.navbar-default .navbar-nav > .disabled > a,
+.navbar-default .navbar-nav > .disabled > a:hover,
+.navbar-default .navbar-nav > .disabled > a:focus {
+ color: #cccccc;
+ background-color: transparent;
+}
+
+.navbar-default .navbar-toggle {
+ border-color: #dddddd;
+}
+
+.navbar-default .navbar-toggle:hover,
+.navbar-default .navbar-toggle:focus {
+ background-color: #dddddd;
+}
+
+.navbar-default .navbar-toggle .icon-bar {
+ background-color: #888888;
+}
+
+.navbar-default .navbar-collapse,
+.navbar-default .navbar-form {
+ border-color: #e7e7e7;
+}
+
+.navbar-default .navbar-nav > .open > a,
+.navbar-default .navbar-nav > .open > a:hover,
+.navbar-default .navbar-nav > .open > a:focus {
+ background-color: #e7e7e7;
+ color: #000000;
+}
+
+@media (max-width: 767px) {
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a {
+ color: #000000;
+ }
+
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #000000;
+ background-color: transparent;
+ }
+
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #000000;
+ background-color: #e7e7e7;
+ }
+
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #cccccc;
+ background-color: transparent;
+ }
+}
+
+.navbar-default .navbar-link {
+ color: #000000;
+}
+
+.navbar-default .navbar-link:hover {
+ color: #000000;
+}
+
+.navbar-default .btn-link {
+ color: #000000;
+}
+
+.navbar-default .btn-link:hover,
+.navbar-default .btn-link:focus {
+ color: #000000;
+}
+
+.navbar-default .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-default .btn-link:hover,
+.navbar-default .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-default .btn-link:focus {
+ color: #cccccc;
+}
+
+.navbar-inverse {
+ background-color: #222222;
+ border-color: #080808;
+}
+
+.navbar-inverse .navbar-brand {
+ color: #9d9d9d;
+}
+
+.navbar-inverse .navbar-brand:hover,
+.navbar-inverse .navbar-brand:focus {
+ color: #ffffff;
+ background-color: transparent;
+}
+
+.navbar-inverse .navbar-text {
+ color: #9d9d9d;
+}
+
+.navbar-inverse .navbar-nav > li > a {
+ color: #9d9d9d;
+}
+
+.navbar-inverse .navbar-nav > li > a:hover,
+.navbar-inverse .navbar-nav > li > a:focus {
+ color: #ffffff;
+ background-color: transparent;
+}
+
+.navbar-inverse .navbar-nav > .active > a,
+.navbar-inverse .navbar-nav > .active > a:hover,
+.navbar-inverse .navbar-nav > .active > a:focus {
+ color: #ffffff;
+ background-color: #080808;
+}
+
+.navbar-inverse .navbar-nav > .disabled > a,
+.navbar-inverse .navbar-nav > .disabled > a:hover,
+.navbar-inverse .navbar-nav > .disabled > a:focus {
+ color: #444444;
+ background-color: transparent;
+}
+
+.navbar-inverse .navbar-toggle {
+ border-color: #333333;
+}
+
+.navbar-inverse .navbar-toggle:hover,
+.navbar-inverse .navbar-toggle:focus {
+ background-color: #333333;
+}
+
+.navbar-inverse .navbar-toggle .icon-bar {
+ background-color: #ffffff;
+}
+
+.navbar-inverse .navbar-collapse,
+.navbar-inverse .navbar-form {
+ border-color: #101010;
+}
+
+.navbar-inverse .navbar-nav > .open > a,
+.navbar-inverse .navbar-nav > .open > a:hover,
+.navbar-inverse .navbar-nav > .open > a:focus {
+ background-color: #080808;
+ color: #ffffff;
+}
+
+@media (max-width: 767px) {
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
+ border-color: #080808;
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
+ background-color: #080808;
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
+ color: #9d9d9d;
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #ffffff;
+ background-color: transparent;
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #ffffff;
+ background-color: #080808;
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #444444;
+ background-color: transparent;
+ }
+}
+
+.navbar-inverse .navbar-link {
+ color: #9d9d9d;
+}
+
+.navbar-inverse .navbar-link:hover {
+ color: #ffffff;
+}
+
+.navbar-inverse .btn-link {
+ color: #9d9d9d;
+}
+
+.navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link:focus {
+ color: #ffffff;
+}
+
+.navbar-inverse .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-inverse .btn-link:focus {
+ color: #444444;
+}
+
+.breadcrumb {
+ padding: 8px 15px;
+ margin-bottom: 20px;
+ list-style: none;
+ background-color: #f5f5f5;
+ border-radius: 4px;
+}
+
+.breadcrumb > li {
+ display: inline-block;
+}
+
+.breadcrumb > li + li:before {
+ content: "/\00a0";
+ padding: 0 5px;
+ color: #cccccc;
+}
+
+.breadcrumb > .active {
+ color: #777777;
+}
+
+.pagination {
+ display: inline-block;
+ padding-left: 0;
+ margin: 20px 0;
+ border-radius: 4px;
+}
+
+.pagination > li {
+ display: inline;
+}
+
+.pagination > li > a,
+.pagination > li > span {
+ position: relative;
+ float: left;
+ padding: 6px 12px;
+ line-height: 1.42857143;
+ text-decoration: none;
+ color: #337cbb;
+ background-color: #ffffff;
+ border: 1px solid #dddddd;
+ margin-left: -1px;
+}
+
+.pagination > li:first-child > a,
+.pagination > li:first-child > span {
+ margin-left: 0;
+ border-bottom-left-radius: 4px;
+ border-top-left-radius: 4px;
+}
+
+.pagination > li:last-child > a,
+.pagination > li:last-child > span {
+ border-bottom-right-radius: 4px;
+ border-top-right-radius: 4px;
+}
+
+.pagination > li > a:hover,
+.pagination > li > span:hover,
+.pagination > li > a:focus,
+.pagination > li > span:focus {
+ color: #23547f;
+ background-color: #eeeeee;
+ border-color: #dddddd;
+}
+
+.pagination > .active > a,
+.pagination > .active > span,
+.pagination > .active > a:hover,
+.pagination > .active > span:hover,
+.pagination > .active > a:focus,
+.pagination > .active > span:focus {
+ z-index: 2;
+ color: #ffffff;
+ background-color: #337cbb;
+ border-color: #337cbb;
+ cursor: default;
+}
+
+.pagination > .disabled > span,
+.pagination > .disabled > span:hover,
+.pagination > .disabled > span:focus,
+.pagination > .disabled > a,
+.pagination > .disabled > a:hover,
+.pagination > .disabled > a:focus {
+ color: #777777;
+ background-color: #ffffff;
+ border-color: #dddddd;
+ cursor: not-allowed;
+}
+
+.pagination-lg > li > a,
+.pagination-lg > li > span {
+ padding: 10px 16px;
+ font-size: 18px;
+}
+
+.pagination-lg > li:first-child > a,
+.pagination-lg > li:first-child > span {
+ border-bottom-left-radius: 5px;
+ border-top-left-radius: 5px;
+}
+
+.pagination-lg > li:last-child > a,
+.pagination-lg > li:last-child > span {
+ border-bottom-right-radius: 5px;
+ border-top-right-radius: 5px;
+}
+
+.pagination-sm > li > a,
+.pagination-sm > li > span {
+ padding: 5px 10px;
+ font-size: 12px;
+}
+
+.pagination-sm > li:first-child > a,
+.pagination-sm > li:first-child > span {
+ border-bottom-left-radius: 2px;
+ border-top-left-radius: 2px;
+}
+
+.pagination-sm > li:last-child > a,
+.pagination-sm > li:last-child > span {
+ border-bottom-right-radius: 2px;
+ border-top-right-radius: 2px;
+}
+
+.pager {
+ padding-left: 0;
+ margin: 20px 0;
+ list-style: none;
+ text-align: center;
+}
+
+.pager li {
+ display: inline;
+}
+
+.pager li > a,
+.pager li > span {
+ display: inline-block;
+ padding: 5px 14px;
+ background-color: #ffffff;
+ border: 1px solid #dddddd;
+ border-radius: 15px;
+}
+
+.pager li > a:hover,
+.pager li > a:focus {
+ text-decoration: none;
+ background-color: #eeeeee;
+}
+
+.pager .next > a,
+.pager .next > span {
+ float: right;
+}
+
+.pager .previous > a,
+.pager .previous > span {
+ float: left;
+}
+
+.pager .disabled > a,
+.pager .disabled > a:hover,
+.pager .disabled > a:focus,
+.pager .disabled > span {
+ color: #777777;
+ background-color: #ffffff;
+ cursor: not-allowed;
+}
+
+.label {
+ display: inline;
+ padding: .2em .6em .3em;
+ font-size: 75%;
+ font-weight: bold;
+ line-height: 1;
+ color: #ffffff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ border-radius: .25em;
+}
+
+a.label:hover,
+a.label:focus {
+ color: #ffffff;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.label:empty {
+ display: none;
+}
+
+.btn .label {
+ position: relative;
+ top: -1px;
+}
+
+.label-default {
+ background-color: #777777;
+}
+
+.label-default[href]:hover,
+.label-default[href]:focus {
+ background-color: #5e5e5e;
+}
+
+.label-primary {
+ background-color: #337cbb;
+}
+
+.label-primary[href]:hover,
+.label-primary[href]:focus {
+ background-color: #286193;
+}
+
+.label-success {
+ background-color: #5cb85c;
+}
+
+.label-success[href]:hover,
+.label-success[href]:focus {
+ background-color: #449d44;
+}
+
+.label-info {
+ background-color: #5bc0de;
+}
+
+.label-info[href]:hover,
+.label-info[href]:focus {
+ background-color: #31b0d5;
+}
+
+.label-warning {
+ background-color: #f0ad4e;
+}
+
+.label-warning[href]:hover,
+.label-warning[href]:focus {
+ background-color: #ec971f;
+}
+
+.label-danger {
+ background-color: #d9534f;
+}
+
+.label-danger[href]:hover,
+.label-danger[href]:focus {
+ background-color: #c9302c;
+}
+
+.badge {
+ display: inline-block;
+ min-width: 10px;
+ padding: 3px 7px;
+ font-size: 12px;
+ font-weight: bold;
+ color: #ffffff;
+ line-height: 1;
+ vertical-align: baseline;
+ white-space: nowrap;
+ text-align: center;
+ background-color: #777777;
+ border-radius: 10px;
+}
+
+.badge:empty {
+ display: none;
+}
+
+.btn .badge {
+ position: relative;
+ top: -1px;
+}
+
+.btn-xs .badge,
+.btn-group-xs > .btn .badge {
+ top: 0;
+ padding: 1px 5px;
+}
+
+a.badge:hover,
+a.badge:focus {
+ color: #ffffff;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.list-group-item.active > .badge,
+.nav-pills > .active > a > .badge {
+ color: #337cbb;
+ background-color: #ffffff;
+}
+
+.list-group-item > .badge {
+ float: right;
+}
+
+.list-group-item > .badge + .badge {
+ margin-right: 5px;
+}
+
+.nav-pills > li > a > .badge {
+ margin-left: 3px;
+}
+
+.jumbotron {
+ padding: 30px 15px;
+ margin-bottom: 30px;
+ color: inherit;
+ background-color: #eeeeee;
+}
+
+.jumbotron h1,
+.jumbotron .h1 {
+ color: inherit;
+}
+
+.jumbotron p {
+ margin-bottom: 15px;
+ font-size: 21px;
+ font-weight: 200;
+}
+
+.jumbotron > hr {
+ border-top-color: #d5d5d5;
+}
+
+.container .jumbotron,
+.container-fluid .jumbotron {
+ border-radius: 5px;
+}
+
+.jumbotron .container {
+ max-width: 100%;
+}
+
+@media screen and (min-width: 768px) {
+ .jumbotron {
+ padding: 48px 0;
+ }
+
+ .container .jumbotron,
+ .container-fluid .jumbotron {
+ padding-left: 60px;
+ padding-right: 60px;
+ }
+
+ .jumbotron h1,
+ .jumbotron .h1 {
+ font-size: 63px;
+ }
+}
+
+.thumbnail {
+ display: block;
+ padding: 4px;
+ margin-bottom: 20px;
+ line-height: 1.42857143;
+ background-color: #ffffff;
+ border: 1px solid #dddddd;
+ border-radius: 4px;
+ -webkit-transition: border 0.2s ease-in-out;
+ -o-transition: border 0.2s ease-in-out;
+ transition: border 0.2s ease-in-out;
+}
+
+.thumbnail > img,
+.thumbnail a > img {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+a.thumbnail:hover,
+a.thumbnail:focus,
+a.thumbnail.active {
+ border-color: #337cbb;
+}
+
+.thumbnail .caption {
+ padding: 9px;
+ color: #000000;
+}
+
+.alert {
+ padding: 15px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+
+.alert h4 {
+ margin-top: 0;
+ color: inherit;
+}
+
+.alert .alert-link {
+ font-weight: bold;
+}
+
+.alert > p,
+.alert > ul {
+ margin-bottom: 0;
+}
+
+.alert > p + p {
+ margin-top: 5px;
+}
+
+.alert-dismissable,
+.alert-dismissible {
+ padding-right: 35px;
+}
+
+.alert-dismissable .close,
+.alert-dismissible .close {
+ position: relative;
+ top: -2px;
+ right: -21px;
+ color: inherit;
+}
+
+.alert-success {
+ background-color: #a3d7a3;
+ border-color: #9ccf91;
+ color: #5cb85c;
+}
+
+.alert-success hr {
+ border-top-color: #8cc780;
+}
+
+.alert-success .alert-link {
+ color: #449d44;
+}
+
+.alert-info {
+ background-color: #b0e1ef;
+ border-color: #92e4e9;
+ color: #5bc0de;
+}
+
+.alert-info hr {
+ border-top-color: #7ddee5;
+}
+
+.alert-info .alert-link {
+ color: #31b0d5;
+}
+
+.alert-warning {
+ background-color: #f8d9ac;
+ border-color: #f6bd95;
+ color: #f0ad4e;
+}
+
+.alert-warning hr {
+ border-top-color: #f4af7d;
+}
+
+.alert-warning .alert-link {
+ color: #ec971f;
+}
+
+.alert-danger {
+ background-color: #eba5a3;
+ border-color: #e78e9a;
+ color: #d9534f;
+}
+
+.alert-danger hr {
+ border-top-color: #e27987;
+}
+
+.alert-danger .alert-link {
+ color: #c9302c;
+}
+
+@-webkit-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+
+@keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+
+.progress {
+ overflow: hidden;
+ height: 20px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+}
+
+.progress-bar {
+ float: left;
+ width: 0%;
+ height: 100%;
+ font-size: 12px;
+ line-height: 20px;
+ color: #ffffff;
+ text-align: center;
+ background-color: #337cbb;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ -webkit-transition: width 0.6s ease;
+ -o-transition: width 0.6s ease;
+ transition: width 0.6s ease;
+}
+
+.progress-striped .progress-bar,
+.progress-bar-striped {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-size: 40px 40px;
+}
+
+.progress.active .progress-bar,
+.progress-bar.active {
+ -webkit-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite;
+}
+
+.progress-bar-success {
+ background-color: #5cb85c;
+}
+
+.progress-striped .progress-bar-success {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+
+.progress-bar-info {
+ background-color: #5bc0de;
+}
+
+.progress-striped .progress-bar-info {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+
+.progress-bar-warning {
+ background-color: #f0ad4e;
+}
+
+.progress-striped .progress-bar-warning {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+
+.progress-bar-danger {
+ background-color: #d9534f;
+}
+
+.progress-striped .progress-bar-danger {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+
+.media {
+ margin-top: 15px;
+}
+
+.media:first-child {
+ margin-top: 0;
+}
+
+.media,
+.media-body {
+ zoom: 1;
+ overflow: hidden;
+}
+
+.media-body {
+ width: 10000px;
+}
+
+.media-object {
+ display: block;
+}
+
+.media-right,
+.media > .pull-right {
+ padding-left: 10px;
+}
+
+.media-left,
+.media > .pull-left {
+ padding-right: 10px;
+}
+
+.media-left,
+.media-right,
+.media-body {
+ display: table-cell;
+ vertical-align: top;
+}
+
+.media-middle {
+ vertical-align: middle;
+}
+
+.media-bottom {
+ vertical-align: bottom;
+}
+
+.media-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+
+.media-list {
+ padding-left: 0;
+ list-style: none;
+}
+
+.list-group {
+ margin-bottom: 20px;
+ padding-left: 0;
+}
+
+.list-group-item {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+ margin-bottom: -1px;
+ background-color: #ffffff;
+ border: 1px solid #999999;
+}
+
+.list-group-item:first-child {
+ border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+}
+
+.list-group-item:last-child {
+ margin-bottom: 0;
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+
+a.list-group-item {
+ color: #555555;
+}
+
+a.list-group-item .list-group-item-heading {
+ color: #333333;
+}
+
+a.list-group-item:hover,
+a.list-group-item:focus {
+ text-decoration: none;
+ color: #555555;
+ background-color: #f5f5f5;
+}
+
+.list-group-item.disabled,
+.list-group-item.disabled:hover,
+.list-group-item.disabled:focus {
+ background-color: #eeeeee;
+ color: #777777;
+ cursor: not-allowed;
+}
+
+.list-group-item.disabled .list-group-item-heading,
+.list-group-item.disabled:hover .list-group-item-heading,
+.list-group-item.disabled:focus .list-group-item-heading {
+ color: inherit;
+}
+
+.list-group-item.disabled .list-group-item-text,
+.list-group-item.disabled:hover .list-group-item-text,
+.list-group-item.disabled:focus .list-group-item-text {
+ color: #777777;
+}
+
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
+ z-index: 2;
+ color: #ffffff;
+ background-color: #337cbb;
+ border-color: #337cbb;
+}
+
+.list-group-item.active .list-group-item-heading,
+.list-group-item.active:hover .list-group-item-heading,
+.list-group-item.active:focus .list-group-item-heading,
+.list-group-item.active .list-group-item-heading > small,
+.list-group-item.active:hover .list-group-item-heading > small,
+.list-group-item.active:focus .list-group-item-heading > small,
+.list-group-item.active .list-group-item-heading > .small,
+.list-group-item.active:hover .list-group-item-heading > .small,
+.list-group-item.active:focus .list-group-item-heading > .small {
+ color: inherit;
+}
+
+.list-group-item.active .list-group-item-text,
+.list-group-item.active:hover .list-group-item-text,
+.list-group-item.active:focus .list-group-item-text {
+ color: #07121b;
+}
+
+.list-group-item-success {
+ color: #5cb85c;
+ background-color: #a3d7a3;
+}
+
+a.list-group-item-success {
+ color: #5cb85c;
+}
+
+a.list-group-item-success .list-group-item-heading {
+ color: inherit;
+}
+
+a.list-group-item-success:hover,
+a.list-group-item-success:focus {
+ color: #5cb85c;
+ background-color: #91cf91;
+}
+
+a.list-group-item-success.active,
+a.list-group-item-success.active:hover,
+a.list-group-item-success.active:focus {
+ color: #fff;
+ background-color: #5cb85c;
+ border-color: #5cb85c;
+}
+
+.list-group-item-info {
+ color: #5bc0de;
+ background-color: #b0e1ef;
+}
+
+a.list-group-item-info {
+ color: #5bc0de;
+}
+
+a.list-group-item-info .list-group-item-heading {
+ color: inherit;
+}
+
+a.list-group-item-info:hover,
+a.list-group-item-info:focus {
+ color: #5bc0de;
+ background-color: #9bd8eb;
+}
+
+a.list-group-item-info.active,
+a.list-group-item-info.active:hover,
+a.list-group-item-info.active:focus {
+ color: #fff;
+ background-color: #5bc0de;
+ border-color: #5bc0de;
+}
+
+.list-group-item-warning {
+ color: #f0ad4e;
+ background-color: #f8d9ac;
+}
+
+a.list-group-item-warning {
+ color: #f0ad4e;
+}
+
+a.list-group-item-warning .list-group-item-heading {
+ color: inherit;
+}
+
+a.list-group-item-warning:hover,
+a.list-group-item-warning:focus {
+ color: #f0ad4e;
+ background-color: #f6ce95;
+}
+
+a.list-group-item-warning.active,
+a.list-group-item-warning.active:hover,
+a.list-group-item-warning.active:focus {
+ color: #fff;
+ background-color: #f0ad4e;
+ border-color: #f0ad4e;
+}
+
+.list-group-item-danger {
+ color: #d9534f;
+ background-color: #eba5a3;
+}
+
+a.list-group-item-danger {
+ color: #d9534f;
+}
+
+a.list-group-item-danger .list-group-item-heading {
+ color: inherit;
+}
+
+a.list-group-item-danger:hover,
+a.list-group-item-danger:focus {
+ color: #d9534f;
+ background-color: #e7908e;
+}
+
+a.list-group-item-danger.active,
+a.list-group-item-danger.active:hover,
+a.list-group-item-danger.active:focus {
+ color: #fff;
+ background-color: #d9534f;
+ border-color: #d9534f;
+}
+
+.list-group-item-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+
+.list-group-item-text {
+ margin-bottom: 0;
+ line-height: 1.3;
+}
+
+.panel {
+ margin-bottom: 20px;
+ background-color: #ffffff;
+ border: 1px solid transparent;
+ border-radius: 4px;
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
+}
+
+.panel-body {
+ padding: 15px;
+}
+
+.panel-heading {
+ padding: 10px 15px;
+ border-bottom: 1px solid transparent;
+ border-top-right-radius: 3px;
+ border-top-left-radius: 3px;
+}
+
+.panel-heading > .dropdown .dropdown-toggle {
+ color: inherit;
+}
+
+.panel-title {
+ margin-top: 0;
+ margin-bottom: 0;
+ font-size: 16px;
+ color: inherit;
+}
+
+.panel-title > a,
+.panel-title > small,
+.panel-title > .small,
+.panel-title > small > a,
+.panel-title > .small > a {
+ color: inherit;
+}
+
+.panel-footer {
+ padding: 10px 15px;
+ background-color: #f5f5f5;
+ border-top: 1px solid #dddddd;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+
+.panel > .list-group,
+.panel > .panel-collapse > .list-group {
+ margin-bottom: 0;
+}
+
+.panel > .list-group .list-group-item,
+.panel > .panel-collapse > .list-group .list-group-item {
+ border-width: 1px 0;
+ border-radius: 0;
+}
+
+.panel > .list-group:first-child .list-group-item:first-child,
+.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
+ border-top: 0;
+ border-top-right-radius: 3px;
+ border-top-left-radius: 3px;
+}
+
+.panel > .list-group:last-child .list-group-item:last-child,
+.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
+ border-bottom: 0;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+
+.panel-heading + .list-group .list-group-item:first-child {
+ border-top-width: 0;
+}
+
+.list-group + .panel-footer {
+ border-top-width: 0;
+}
+
+.panel > .table,
+.panel > .table-responsive > .table,
+.panel > .panel-collapse > .table {
+ margin-bottom: 0;
+}
+
+.panel > .table caption,
+.panel > .table-responsive > .table caption,
+.panel > .panel-collapse > .table caption {
+ padding-left: 15px;
+ padding-right: 15px;
+}
+
+.panel > .table:first-child,
+.panel > .table-responsive:first-child > .table:first-child {
+ border-top-right-radius: 3px;
+ border-top-left-radius: 3px;
+}
+
+.panel > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+
+.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
+ border-top-left-radius: 3px;
+}
+
+.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
+ border-top-right-radius: 3px;
+}
+
+.panel > .table:last-child,
+.panel > .table-responsive:last-child > .table:last-child {
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+
+.panel > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+}
+
+.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
+ border-bottom-left-radius: 3px;
+}
+
+.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
+ border-bottom-right-radius: 3px;
+}
+
+.panel > .panel-body + .table,
+.panel > .panel-body + .table-responsive,
+.panel > .table + .panel-body,
+.panel > .table-responsive + .panel-body {
+ border-top: 1px solid #dddddd;
+}
+
+.panel > .table > tbody:first-child > tr:first-child th,
+.panel > .table > tbody:first-child > tr:first-child td {
+ border-top: 0;
+}
+
+.panel > .table-bordered,
+.panel > .table-responsive > .table-bordered {
+ border: 0;
+}
+
+.panel > .table-bordered > thead > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
+.panel > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-bordered > thead > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
+.panel > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-bordered > tfoot > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+}
+
+.panel > .table-bordered > thead > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
+.panel > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-bordered > thead > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
+.panel > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-bordered > tfoot > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+}
+
+.panel > .table-bordered > thead > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
+.panel > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-bordered > thead > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
+.panel > .table-bordered > tbody > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
+ border-bottom: 0;
+}
+
+.panel > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-bordered > tfoot > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
+ border-bottom: 0;
+}
+
+.panel > .table-responsive {
+ border: 0;
+ margin-bottom: 0;
+}
+
+.panel-group {
+ margin-bottom: 20px;
+}
+
+.panel-group .panel {
+ margin-bottom: 0;
+ border-radius: 4px;
+}
+
+.panel-group .panel + .panel {
+ margin-top: 5px;
+}
+
+.panel-group .panel-heading {
+ border-bottom: 0;
+}
+
+.panel-group .panel-heading + .panel-collapse > .panel-body,
+.panel-group .panel-heading + .panel-collapse > .list-group {
+ border-top: 1px solid #dddddd;
+}
+
+.panel-group .panel-footer {
+ border-top: 0;
+}
+
+.panel-group .panel-footer + .panel-collapse .panel-body {
+ border-bottom: 1px solid #dddddd;
+}
+
+.panel-default {
+ border-color: #dddddd;
+}
+
+.panel-default > .panel-heading {
+ color: #333333;
+ background-color: #f5f5f5;
+ border-color: #dddddd;
+}
+
+.panel-default > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #dddddd;
+}
+
+.panel-default > .panel-heading .badge {
+ color: #f5f5f5;
+ background-color: #333333;
+}
+
+.panel-default > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #dddddd;
+}
+
+.panel-primary {
+ border-color: #337cbb;
+}
+
+.panel-primary > .panel-heading {
+ color: #ffffff;
+ background-color: #337cbb;
+ border-color: #337cbb;
+}
+
+.panel-primary > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #337cbb;
+}
+
+.panel-primary > .panel-heading .badge {
+ color: #337cbb;
+ background-color: #ffffff;
+}
+
+.panel-primary > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #337cbb;
+}
+
+.panel-success {
+ border-color: #9ccf91;
+}
+
+.panel-success > .panel-heading {
+ color: #5cb85c;
+ background-color: #a3d7a3;
+ border-color: #9ccf91;
+}
+
+.panel-success > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #9ccf91;
+}
+
+.panel-success > .panel-heading .badge {
+ color: #a3d7a3;
+ background-color: #5cb85c;
+}
+
+.panel-success > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #9ccf91;
+}
+
+.panel-info {
+ border-color: #92e4e9;
+}
+
+.panel-info > .panel-heading {
+ color: #5bc0de;
+ background-color: #b0e1ef;
+ border-color: #92e4e9;
+}
+
+.panel-info > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #92e4e9;
+}
+
+.panel-info > .panel-heading .badge {
+ color: #b0e1ef;
+ background-color: #5bc0de;
+}
+
+.panel-info > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #92e4e9;
+}
+
+.panel-warning {
+ border-color: #f6bd95;
+}
+
+.panel-warning > .panel-heading {
+ color: #f0ad4e;
+ background-color: #f8d9ac;
+ border-color: #f6bd95;
+}
+
+.panel-warning > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #f6bd95;
+}
+
+.panel-warning > .panel-heading .badge {
+ color: #f8d9ac;
+ background-color: #f0ad4e;
+}
+
+.panel-warning > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #f6bd95;
+}
+
+.panel-danger {
+ border-color: #e78e9a;
+}
+
+.panel-danger > .panel-heading {
+ color: #d9534f;
+ background-color: #eba5a3;
+ border-color: #e78e9a;
+}
+
+.panel-danger > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #e78e9a;
+}
+
+.panel-danger > .panel-heading .badge {
+ color: #eba5a3;
+ background-color: #d9534f;
+}
+
+.panel-danger > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #e78e9a;
+}
+
+.embed-responsive {
+ position: relative;
+ display: block;
+ height: 0;
+ padding: 0;
+ overflow: hidden;
+}
+
+.embed-responsive .embed-responsive-item,
+.embed-responsive iframe,
+.embed-responsive embed,
+.embed-responsive object,
+.embed-responsive video {
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ height: 100%;
+ width: 100%;
+ border: 0;
+}
+
+.embed-responsive-16by9 {
+ padding-bottom: 56.25%;
+}
+
+.embed-responsive-4by3 {
+ padding-bottom: 75%;
+}
+
+.well {
+ min-height: 20px;
+ padding: 19px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ border: 1px solid #e3e3e3;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+}
+
+.well blockquote {
+ border-color: #ddd;
+ border-color: rgba(0, 0, 0, 0.15);
+}
+
+.well-lg {
+ padding: 24px;
+ border-radius: 5px;
+}
+
+.well-sm {
+ padding: 9px;
+ border-radius: 2px;
+}
+
+.close {
+ float: right;
+ font-size: 21px;
+ font-weight: bold;
+ line-height: 1;
+ color: #000000;
+ text-shadow: 0 1px 0 #ffffff;
+ opacity: 0.2;
+ filter: alpha(opacity=20);
+}
+
+.close:hover,
+.close:focus {
+ color: #000000;
+ text-decoration: none;
+ cursor: pointer;
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+}
+
+button.close {
+ padding: 0;
+ cursor: pointer;
+ background: transparent;
+ border: 0;
+ -webkit-appearance: none;
+}
+
+.modal-open {
+ overflow: hidden;
+}
+
+.modal {
+ display: none;
+ overflow: hidden;
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1050;
+ -webkit-overflow-scrolling: touch;
+ outline: 0;
+}
+
+.modal.fade .modal-dialog {
+ -webkit-transform: translate(0, -25%);
+ -ms-transform: translate(0, -25%);
+ -o-transform: translate(0, -25%);
+ transform: translate(0, -25%);
+ -webkit-transition: -webkit-transform 0.3s ease-out;
+ -moz-transition: -moz-transform 0.3s ease-out;
+ -o-transition: -o-transform 0.3s ease-out;
+ transition: transform 0.3s ease-out;
+}
+
+.modal.in .modal-dialog {
+ -webkit-transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
+ transform: translate(0, 0);
+}
+
+.modal-open .modal {
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+
+.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: 10px;
+}
+
+.modal-content {
+ position: relative;
+ background-color: #ffffff;
+ border: 1px solid #999999;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ border-radius: 5px;
+ -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
+ box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
+ background-clip: padding-box;
+ outline: 0;
+}
+
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1040;
+ background-color: #000000;
+}
+
+.modal-backdrop.fade {
+ opacity: 0;
+ filter: alpha(opacity=0);
+}
+
+.modal-backdrop.in {
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+}
+
+.modal-header {
+ padding: 15px;
+ border-bottom: 1px solid #e5e5e5;
+ min-height: 16.42857143px;
+}
+
+.modal-header .close {
+ margin-top: -2px;
+}
+
+.modal-title {
+ margin: 0;
+ line-height: 1.42857143;
+}
+
+.modal-body {
+ position: relative;
+ padding: 15px;
+}
+
+.modal-footer {
+ padding: 15px;
+ text-align: right;
+ border-top: 1px solid #e5e5e5;
+}
+
+.modal-footer .btn + .btn {
+ margin-left: 5px;
+ margin-bottom: 0;
+}
+
+.modal-footer .btn-group .btn + .btn {
+ margin-left: -1px;
+}
+
+.modal-footer .btn-block + .btn-block {
+ margin-left: 0;
+}
+
+.modal-scrollbar-measure {
+ position: absolute;
+ top: -9999px;
+ width: 50px;
+ height: 50px;
+ overflow: scroll;
+}
+
+@media (min-width: 768px) {
+ .modal-dialog {
+ width: 600px;
+ margin: 30px auto;
+ }
+
+ .modal-content {
+ -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
+ }
+
+ .modal-sm {
+ width: 300px;
+ }
+}
+
+@media (min-width: 992px) {
+ .modal-lg {
+ width: 900px;
+ }
+}
+
+.tooltip {
+ position: absolute;
+ z-index: 1070;
+ display: block;
+ font-family: Lato;
+ font-size: 12px;
+ font-weight: normal;
+ line-height: 1.4;
+ opacity: 0;
+ filter: alpha(opacity=0);
+}
+
+.tooltip.in {
+ opacity: 0.9;
+ filter: alpha(opacity=90);
+}
+
+.tooltip.top {
+ margin-top: -3px;
+ padding: 5px 0;
+}
+
+.tooltip.right {
+ margin-left: 3px;
+ padding: 0 5px;
+}
+
+.tooltip.bottom {
+ margin-top: 3px;
+ padding: 5px 0;
+}
+
+.tooltip.left {
+ margin-left: -3px;
+ padding: 0 5px;
+}
+
+.tooltip-inner {
+ max-width: 200px;
+ padding: 3px 8px;
+ color: #ffffff;
+ text-align: center;
+ text-decoration: none;
+ background-color: #000000;
+ border-radius: 4px;
+}
+
+.tooltip-arrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+
+.tooltip.top .tooltip-arrow {
+ bottom: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000000;
+}
+
+.tooltip.top-left .tooltip-arrow {
+ bottom: 0;
+ right: 5px;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000000;
+}
+
+.tooltip.top-right .tooltip-arrow {
+ bottom: 0;
+ left: 5px;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000000;
+}
+
+.tooltip.right .tooltip-arrow {
+ top: 50%;
+ left: 0;
+ margin-top: -5px;
+ border-width: 5px 5px 5px 0;
+ border-right-color: #000000;
+}
+
+.tooltip.left .tooltip-arrow {
+ top: 50%;
+ right: 0;
+ margin-top: -5px;
+ border-width: 5px 0 5px 5px;
+ border-left-color: #000000;
+}
+
+.tooltip.bottom .tooltip-arrow {
+ top: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000000;
+}
+
+.tooltip.bottom-left .tooltip-arrow {
+ top: 0;
+ right: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000000;
+}
+
+.tooltip.bottom-right .tooltip-arrow {
+ top: 0;
+ left: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000000;
+}
+
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 1060;
+ display: none;
+ max-width: 276px;
+ padding: 1px;
+ font-family: Lato;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: left;
+ background-color: #ffffff;
+ background-clip: padding-box;
+ border: 1px solid #cccccc;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ border-radius: 5px;
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ white-space: normal;
+}
+
+.popover.top {
+ margin-top: -10px;
+}
+
+.popover.right {
+ margin-left: 10px;
+}
+
+.popover.bottom {
+ margin-top: 10px;
+}
+
+.popover.left {
+ margin-left: -10px;
+}
+
+.popover-title {
+ margin: 0;
+ padding: 8px 14px;
+ font-size: 14px;
+ background-color: #f7f7f7;
+ border-bottom: 1px solid #ebebeb;
+ border-radius: 4px 4px 0 0;
+}
+
+.popover-content {
+ padding: 9px 14px;
+}
+
+.popover > .arrow,
+.popover > .arrow:after {
+ position: absolute;
+ display: block;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+
+.popover > .arrow {
+ border-width: 11px;
+}
+
+.popover > .arrow:after {
+ border-width: 10px;
+ content: "";
+}
+
+.popover.top > .arrow {
+ left: 50%;
+ margin-left: -11px;
+ border-bottom-width: 0;
+ border-top-color: #999999;
+ border-top-color: rgba(0, 0, 0, 0.25);
+ bottom: -11px;
+}
+
+.popover.top > .arrow:after {
+ content: " ";
+ bottom: 1px;
+ margin-left: -10px;
+ border-bottom-width: 0;
+ border-top-color: #ffffff;
+}
+
+.popover.right > .arrow {
+ top: 50%;
+ left: -11px;
+ margin-top: -11px;
+ border-left-width: 0;
+ border-right-color: #999999;
+ border-right-color: rgba(0, 0, 0, 0.25);
+}
+
+.popover.right > .arrow:after {
+ content: " ";
+ left: 1px;
+ bottom: -10px;
+ border-left-width: 0;
+ border-right-color: #ffffff;
+}
+
+.popover.bottom > .arrow {
+ left: 50%;
+ margin-left: -11px;
+ border-top-width: 0;
+ border-bottom-color: #999999;
+ border-bottom-color: rgba(0, 0, 0, 0.25);
+ top: -11px;
+}
+
+.popover.bottom > .arrow:after {
+ content: " ";
+ top: 1px;
+ margin-left: -10px;
+ border-top-width: 0;
+ border-bottom-color: #ffffff;
+}
+
+.popover.left > .arrow {
+ top: 50%;
+ right: -11px;
+ margin-top: -11px;
+ border-right-width: 0;
+ border-left-color: #999999;
+ border-left-color: rgba(0, 0, 0, 0.25);
+}
+
+.popover.left > .arrow:after {
+ content: " ";
+ right: 1px;
+ border-right-width: 0;
+ border-left-color: #ffffff;
+ bottom: -10px;
+}
+
+.carousel {
+ position: relative;
+}
+
+.carousel-inner {
+ position: relative;
+ overflow: hidden;
+ width: 100%;
+}
+
+.carousel-inner > .item {
+ display: none;
+ position: relative;
+ -webkit-transition: 0.6s ease-in-out left;
+ -o-transition: 0.6s ease-in-out left;
+ transition: 0.6s ease-in-out left;
+}
+
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ line-height: 1;
+}
+
+@media all and (transform-3d), (-webkit-transform-3d) {
+ .carousel-inner > .item {
+ -webkit-transition: -webkit-transform 0.6s ease-in-out;
+ -moz-transition: -moz-transform 0.6s ease-in-out;
+ -o-transition: -o-transform 0.6s ease-in-out;
+ transition: transform 0.6s ease-in-out;
+ -webkit-backface-visibility: hidden;
+ -moz-backface-visibility: hidden;
+ backface-visibility: hidden;
+ -webkit-perspective: 1000;
+ -moz-perspective: 1000;
+ perspective: 1000;
+ }
+
+ .carousel-inner > .item.next,
+ .carousel-inner > .item.active.right {
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ left: 0;
+ }
+
+ .carousel-inner > .item.prev,
+ .carousel-inner > .item.active.left {
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ left: 0;
+ }
+
+ .carousel-inner > .item.next.left,
+ .carousel-inner > .item.prev.right,
+ .carousel-inner > .item.active {
+ -webkit-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ left: 0;
+ }
+}
+
+.carousel-inner > .active,
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ display: block;
+}
+
+.carousel-inner > .active {
+ left: 0;
+}
+
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ position: absolute;
+ top: 0;
+ width: 100%;
+}
+
+.carousel-inner > .next {
+ left: 100%;
+}
+
+.carousel-inner > .prev {
+ left: -100%;
+}
+
+.carousel-inner > .next.left,
+.carousel-inner > .prev.right {
+ left: 0;
+}
+
+.carousel-inner > .active.left {
+ left: -100%;
+}
+
+.carousel-inner > .active.right {
+ left: 100%;
+}
+
+.carousel-control {
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ width: 15%;
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+ font-size: 20px;
+ color: #ffffff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
+}
+
+.carousel-control.left {
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
+ background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
+}
+
+.carousel-control.right {
+ left: auto;
+ right: 0;
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
+ background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
+}
+
+.carousel-control:hover,
+.carousel-control:focus {
+ outline: 0;
+ color: #ffffff;
+ text-decoration: none;
+ opacity: 0.9;
+ filter: alpha(opacity=90);
+}
+
+.carousel-control .icon-prev,
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-left,
+.carousel-control .glyphicon-chevron-right {
+ position: absolute;
+ top: 50%;
+ z-index: 5;
+ display: inline-block;
+}
+
+.carousel-control .icon-prev,
+.carousel-control .glyphicon-chevron-left {
+ left: 50%;
+ margin-left: -10px;
+}
+
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-right {
+ right: 50%;
+ margin-right: -10px;
+}
+
+.carousel-control .icon-prev,
+.carousel-control .icon-next {
+ width: 20px;
+ height: 20px;
+ margin-top: -10px;
+ line-height: 1;
+ font-family: serif;
+}
+
+.carousel-control .icon-prev:before {
+ content: '\2039';
+}
+
+.carousel-control .icon-next:before {
+ content: '\203a';
+}
+
+.carousel-indicators {
+ position: absolute;
+ bottom: 10px;
+ left: 50%;
+ z-index: 15;
+ width: 60%;
+ margin-left: -30%;
+ padding-left: 0;
+ list-style: none;
+ text-align: center;
+}
+
+.carousel-indicators li {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ margin: 1px;
+ text-indent: -999px;
+ border: 1px solid #ffffff;
+ border-radius: 10px;
+ cursor: pointer;
+ background-color: #000 \9;
+ background-color: rgba(0, 0, 0, 0);
+}
+
+.carousel-indicators .active {
+ margin: 0;
+ width: 12px;
+ height: 12px;
+ background-color: #ffffff;
+}
+
+.carousel-caption {
+ position: absolute;
+ left: 15%;
+ right: 15%;
+ bottom: 20px;
+ z-index: 10;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ color: #ffffff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
+}
+
+.carousel-caption .btn {
+ text-shadow: none;
+}
+
+@media screen and (min-width: 768px) {
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-prev,
+ .carousel-control .icon-next {
+ width: 30px;
+ height: 30px;
+ margin-top: -15px;
+ font-size: 30px;
+ }
+
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .icon-prev {
+ margin-left: -15px;
+ }
+
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-next {
+ margin-right: -15px;
+ }
+
+ .carousel-caption {
+ left: 20%;
+ right: 20%;
+ padding-bottom: 30px;
+ }
+
+ .carousel-indicators {
+ bottom: 20px;
+ }
+}
+
+.clearfix:before,
+.clearfix:after,
+.dl-horizontal dd:before,
+.dl-horizontal dd:after,
+.container:before,
+.container:after,
+.container-fluid:before,
+.container-fluid:after,
+.row:before,
+.row:after,
+.form-horizontal .form-group:before,
+.form-horizontal .form-group:after,
+.btn-toolbar:before,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:before,
+.btn-group-vertical > .btn-group:after,
+.nav:before,
+.nav:after,
+.navbar:before,
+.navbar:after,
+.navbar-header:before,
+.navbar-header:after,
+.navbar-collapse:before,
+.navbar-collapse:after,
+.pager:before,
+.pager:after,
+.panel-body:before,
+.panel-body:after,
+.modal-footer:before,
+.modal-footer:after {
+ content: " ";
+ display: table;
+}
+
+.clearfix:after,
+.dl-horizontal dd:after,
+.container:after,
+.container-fluid:after,
+.row:after,
+.form-horizontal .form-group:after,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:after,
+.nav:after,
+.navbar:after,
+.navbar-header:after,
+.navbar-collapse:after,
+.pager:after,
+.panel-body:after,
+.modal-footer:after {
+ clear: both;
+}
+
+.center-block {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.pull-right {
+ float: right !important;
+}
+
+.pull-left {
+ float: left !important;
+}
+
+.hide {
+ display: none !important;
+}
+
+.show {
+ display: block !important;
+}
+
+.invisible {
+ visibility: hidden;
+}
+
+.text-hide {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+
+.hidden {
+ display: none !important;
+}
+
+.affix {
+ position: fixed;
+}
+
+@-ms-viewport {
+ width: device-width;
+}
+
+.visible-xs,
+.visible-sm,
+.visible-md,
+.visible-lg {
+ display: none !important;
+}
+
+.visible-xs-block,
+.visible-xs-inline,
+.visible-xs-inline-block,
+.visible-sm-block,
+.visible-sm-inline,
+.visible-sm-inline-block,
+.visible-md-block,
+.visible-md-inline,
+.visible-md-inline-block,
+.visible-lg-block,
+.visible-lg-inline,
+.visible-lg-inline-block {
+ display: none !important;
+}
+
+@media (max-width: 767px) {
+ .visible-xs {
+ display: block !important;
+ }
+
+ table.visible-xs {
+ display: table;
+ }
+
+ tr.visible-xs {
+ display: table-row !important;
+ }
+
+ th.visible-xs,
+ td.visible-xs {
+ display: table-cell !important;
+ }
+}
+
+@media (max-width: 767px) {
+ .visible-xs-block {
+ display: block !important;
+ }
+}
+
+@media (max-width: 767px) {
+ .visible-xs-inline {
+ display: inline !important;
+ }
+}
+
+@media (max-width: 767px) {
+ .visible-xs-inline-block {
+ display: inline-block !important;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm {
+ display: block !important;
+ }
+
+ table.visible-sm {
+ display: table;
+ }
+
+ tr.visible-sm {
+ display: table-row !important;
+ }
+
+ th.visible-sm,
+ td.visible-sm {
+ display: table-cell !important;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-block {
+ display: block !important;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline {
+ display: inline !important;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline-block {
+ display: inline-block !important;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md {
+ display: block !important;
+ }
+
+ table.visible-md {
+ display: table;
+ }
+
+ tr.visible-md {
+ display: table-row !important;
+ }
+
+ th.visible-md,
+ td.visible-md {
+ display: table-cell !important;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-block {
+ display: block !important;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline {
+ display: inline !important;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline-block {
+ display: inline-block !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .visible-lg {
+ display: block !important;
+ }
+
+ table.visible-lg {
+ display: table;
+ }
+
+ tr.visible-lg {
+ display: table-row !important;
+ }
+
+ th.visible-lg,
+ td.visible-lg {
+ display: table-cell !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .visible-lg-block {
+ display: block !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .visible-lg-inline {
+ display: inline !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .visible-lg-inline-block {
+ display: inline-block !important;
+ }
+}
+
+@media (max-width: 767px) {
+ .hidden-xs {
+ display: none !important;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .hidden-sm {
+ display: none !important;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .hidden-md {
+ display: none !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .hidden-lg {
+ display: none !important;
+ }
+}
+
+.visible-print {
+ display: none !important;
+}
+
+@media print {
+ .visible-print {
+ display: block !important;
+ }
+
+ table.visible-print {
+ display: table;
+ }
+
+ tr.visible-print {
+ display: table-row !important;
+ }
+
+ th.visible-print,
+ td.visible-print {
+ display: table-cell !important;
+ }
+}
+
+.visible-print-block {
+ display: none !important;
+}
+
+@media print {
+ .visible-print-block {
+ display: block !important;
+ }
+}
+
+.visible-print-inline {
+ display: none !important;
+}
+
+@media print {
+ .visible-print-inline {
+ display: inline !important;
+ }
+}
+
+.visible-print-inline-block {
+ display: none !important;
+}
+
+@media print {
+ .visible-print-inline-block {
+ display: inline-block !important;
+ }
+}
+
+@media print {
+ .hidden-print {
+ display: none !important;
+ }
+}
+
+/*!
+ * Pingendo customization for Bootstrap
+ * Homepage: http://pingendo.com
+ * Copyright 2015 Pingendo
+ * Licensed under MIT
+*/
+/* Google web fonts support */
+/* TODO: webkit need this why ?*/
+html,
+body {
+ height: 100%;
+}
+
+/* text-inverse is deprecated */
+.text-inverse {
+ color: #ffffff;
+}
+
+/* TODO: verify if we can touch only section */
+.jumbotron {
+ margin-bottom: 0px !important;
+}
+
+.jumbotron h1.text-primary {
+ color: #337cbb !important;
+}
+
+.jumbotron h1.text-inverse {
+ color: #ffffff !important;
+}
+
+.jumbotron h1.text-info {
+ color: #5bc0de !important;
+}
+
+.jumbotron h1.text-success {
+ color: #5cb85c !important;
+}
+
+.jumbotron h1.text-warning {
+ color: #f0ad4e !important;
+}
+
+.jumbotron h1.text-danger {
+ color: #d9534f !important;
+}
+
+.carousel .item img {
+ min-width: 100%;
+}
+
+.section {
+ position: relative;
+ padding: 35px 0;
+ margin-top: 10%;
+ margin-bottom: 8%;
+}
+
+.section .background-image {
+ z-index: 0;
+ position: absolute;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ background-size: cover;
+ background-position: center;
+}
+
+.section .background-image.background-image-fixed {
+ background-attachment: fixed;
+}
+
+.section-primary {
+ background-color: #8bc4c9 !important;
+ color: #ffffff;
+}
+
+.section-primary .background-image {
+ opacity: 0.5;
+}
+
+.section-info {
+ background-color: #5bc0de !important;
+ color: #ffffff;
+}
+
+.section-info .background-image {
+ opacity: 0.5;
+}
+
+.section-success {
+ background-color: #5cb85c !important;
+ color: #ffffff;
+}
+
+.section-success .background-image {
+ opacity: 0.5;
+}
+
+.section-warning {
+ background-color: #f0ad4e !important;
+ color: #ffffff;
+}
+
+.section-warning .background-image {
+ opacity: 0.5;
+}
+
+.section-danger {
+ background-color: #d9534f !important;
+ color: #ffffff;
+}
+
+.section-danger .background-image {
+ opacity: 0.5;
+}
+
+.cover {
+ padding: 30px 15px;
+ margin-bottom: 30px;
+ color: inherit;
+ background-color: #eeeeee;
+ margin-bottom: 0px !important;
+ padding: 0px 0px;
+ background-color: transparent;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
+ -webkit-align-items: center;
+ align-items: center;
+ overflow: hidden;
+ position: relative;
+ min-height: 100%;
+}
+
+.cover h1,
+.cover .h1 {
+ color: inherit;
+}
+
+.cover p {
+ margin-bottom: 15px;
+ font-size: 21px;
+ font-weight: 200;
+}
+
+.cover > hr {
+ border-top-color: #d5d5d5;
+}
+
+.container .cover,
+.container-fluid .cover {
+ border-radius: 5px;
+}
+
+.cover .container {
+ max-width: 100%;
+}
+
+@media screen and (min-width: 768px) {
+ .cover {
+ padding: 48px 0;
+ }
+
+ .container .cover,
+ .container-fluid .cover {
+ padding-left: 60px;
+ padding-right: 60px;
+ }
+
+ .cover h1,
+ .cover .h1 {
+ font-size: 63px;
+ }
+}
+
+.cover h1.text-primary {
+ color: #337cbb !important;
+}
+
+.cover h1.text-inverse {
+ color: #ffffff !important;
+}
+
+.cover h1.text-info {
+ color: #5bc0de !important;
+}
+
+.cover h1.text-success {
+ color: #5cb85c !important;
+}
+
+.cover h1.text-warning {
+ color: #f0ad4e !important;
+}
+
+.cover h1.text-danger {
+ color: #d9534f !important;
+}
+
+@media screen and (min-width: 768px) {
+ .cover {
+ padding: 0px;
+ }
+
+ .container .cover,
+ .container-fluid .cover {
+ padding-left: 0px;
+ padding-right: 0px;
+ }
+}
+
+.cover .navbar {
+ position: absolute;
+ top: 0px;
+ width: 100%;
+ border: none;
+ background-color: transparent !important;
+}
+
+.cover .navbar .navbar-nav li.active a {
+ background-color: transparent !important;
+}
+
+.cover .navbar .navbar-toggle {
+ border-color: transparent;
+}
+
+.cover .navbar .navbar-toggle:hover,
+.cover .navbar .navbar-toggle:focus {
+ background-color: transparent;
+}
+
+.cover .navbar .navbar-toggle .icon-bar {
+ background-color: #000000;
+}
+
+.cover .navbar.navbar-inverse .navbar-toggle {
+ border-color: transparent;
+}
+
+.cover .navbar.navbar-inverse .navbar-toggle:hover,
+.cover .navbar.navbar-inverse .navbar-toggle:focus {
+ background-color: transparent;
+}
+
+.cover .navbar.navbar-inverse .navbar-toggle .icon-bar {
+ background-color: #ffffff;
+}
+
+
+
+.cover .cover-image {
+ z-index: -1;
+ position: absolute;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ background-size: cover;
+ background-position: center;
+}
+
+.cover .cover-image.background-image-fixed,
+.cover .cover-image.cover-image-fixed {
+ background-attachment: fixed;
+}
+
+.user {
+ padding-bottom: 4%;
+ padding-right: 2%;
+ background-position: 6px 7px;
+ background-repeat: no-repeat;
+ background-color: white;
+ padding: 5px 8px 4px 8px;
+ -webkit-border-radius: 0px 0px 8px 8px;
+ -moz-border-radius: 0px 0px 8px 8px;
+ border-radius: 1px 1px 1px 1px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ float: left;
+ margin-left: 8px;
+ background-color: #333;
+ padding: 4px 4px 0px 4px;
+ -webkit-border-radius: 0px 0px 10px 10px;
+ -moz-border-radius: 0px 0px 10px 10px;
+ border-radius: 0px 0px 10px 10px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #794646;
+ background-color: #fff;
+}
+.u_P{
+ padding-right: 2%;
+ padding-bottom:0.5%;
+ margin-right: 1%;
+}
+/* PINGENDO COMMENT DO NOT REMOVE */
diff --git a/membership/static/font-awesome/.bower.json b/membership/static/font-awesome/.bower.json
new file mode 100755
index 0000000..ba41dfe
--- /dev/null
+++ b/membership/static/font-awesome/.bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "font-awesome",
+ "description": "Font Awesome",
+ "keywords": [],
+ "homepage": "http://fontawesome.io",
+ "dependencies": {},
+ "devDependencies": {},
+ "license": [
+ "OFL-1.1",
+ "MIT",
+ "CC-BY-3.0"
+ ],
+ "main": [
+ "less/font-awesome.less",
+ "scss/font-awesome.scss"
+ ],
+ "ignore": [
+ "*/.*",
+ "*.json",
+ "src",
+ "*.yml",
+ "Gemfile",
+ "Gemfile.lock",
+ "*.md"
+ ],
+ "version": "4.6.1",
+ "_release": "4.6.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v4.6.1",
+ "commit": "2ea06070a708a56c260d4b60b23318ff55ce67f4"
+ },
+ "_source": "https://github.com/FortAwesome/Font-Awesome.git",
+ "_target": "^4.6.1",
+ "_originalSource": "font-awesome",
+ "_direct": true
+}
\ No newline at end of file
diff --git a/membership/static/font-awesome/.gitignore b/membership/static/font-awesome/.gitignore
new file mode 100755
index 0000000..39c4f20
--- /dev/null
+++ b/membership/static/font-awesome/.gitignore
@@ -0,0 +1,33 @@
+*.pyc
+*.egg-info
+*.db
+*.db.old
+*.swp
+*.db-journal
+
+.coverage
+.DS_Store
+.installed.cfg
+_gh_pages/*
+
+.idea/*
+.svn/*
+src/website/static/*
+src/website/media/*
+
+bin
+cfcache
+develop-eggs
+dist
+downloads
+eggs
+parts
+tmp
+.sass-cache
+node_modules
+
+src/website/settingslocal.py
+stunnel.log
+
+.ruby-version
+.bundle
diff --git a/membership/static/font-awesome/.npmignore b/membership/static/font-awesome/.npmignore
new file mode 100755
index 0000000..54a691f
--- /dev/null
+++ b/membership/static/font-awesome/.npmignore
@@ -0,0 +1,42 @@
+*.pyc
+*.egg-info
+*.db
+*.db.old
+*.swp
+*.db-journal
+
+.coverage
+.DS_Store
+.installed.cfg
+_gh_pages/*
+
+.idea/*
+.svn/*
+src/website/static/*
+src/website/media/*
+
+bin
+cfcache
+develop-eggs
+dist
+downloads
+eggs
+parts
+tmp
+.sass-cache
+node_modules
+
+src/website/settingslocal.py
+stunnel.log
+
+.ruby-version
+
+# don't need these in the npm package.
+src/
+_config.yml
+bower.json
+component.json
+composer.json
+CONTRIBUTING.md
+Gemfile
+Gemfile.lock
diff --git a/membership/static/font-awesome/HELP-US-OUT.txt b/membership/static/font-awesome/HELP-US-OUT.txt
new file mode 100755
index 0000000..83d083d
--- /dev/null
+++ b/membership/static/font-awesome/HELP-US-OUT.txt
@@ -0,0 +1,7 @@
+I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project,
+Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome,
+comprehensive icon sets or copy and paste your own.
+
+Please. Check it out.
+
+-Dave Gandy
diff --git a/membership/static/font-awesome/bower.json b/membership/static/font-awesome/bower.json
new file mode 100755
index 0000000..9e21126
--- /dev/null
+++ b/membership/static/font-awesome/bower.json
@@ -0,0 +1,22 @@
+{
+ "name": "font-awesome",
+ "description": "Font Awesome",
+ "keywords": [],
+ "homepage": "http://fontawesome.io",
+ "dependencies": {},
+ "devDependencies": {},
+ "license": ["OFL-1.1", "MIT", "CC-BY-3.0"],
+ "main": [
+ "less/font-awesome.less",
+ "scss/font-awesome.scss"
+ ],
+ "ignore": [
+ "*/.*",
+ "*.json",
+ "src",
+ "*.yml",
+ "Gemfile",
+ "Gemfile.lock",
+ "*.md"
+ ]
+}
diff --git a/membership/static/font-awesome/css/font-awesome.css b/membership/static/font-awesome/css/font-awesome.css
new file mode 100755
index 0000000..bb0fe51
--- /dev/null
+++ b/membership/static/font-awesome/css/font-awesome.css
@@ -0,0 +1,2178 @@
+/*!
+ * Font Awesome 4.6.1 by @davegandy - http://fontawesome.io - @fontawesome
+ * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+/* FONT PATH
+ * -------------------------- */
+@font-face {
+ font-family: 'FontAwesome';
+ src: url('../fonts/fontawesome-webfont.eot?v=4.6.1');
+ src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.6.1') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.6.1') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.6.1') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.6.1') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.6.1#fontawesomeregular') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+.fa {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+/* makes the font 33% larger relative to the icon container */
+.fa-lg {
+ font-size: 1.33333333em;
+ line-height: 0.75em;
+ vertical-align: -15%;
+}
+.fa-2x {
+ font-size: 2em;
+}
+.fa-3x {
+ font-size: 3em;
+}
+.fa-4x {
+ font-size: 4em;
+}
+.fa-5x {
+ font-size: 5em;
+}
+.fa-fw {
+ width: 1.28571429em;
+ text-align: center;
+}
+.fa-ul {
+ padding-left: 0;
+ margin-left: 2.14285714em;
+ list-style-type: none;
+}
+.fa-ul > li {
+ position: relative;
+}
+.fa-li {
+ position: absolute;
+ left: -2.14285714em;
+ width: 2.14285714em;
+ top: 0.14285714em;
+ text-align: center;
+}
+.fa-li.fa-lg {
+ left: -1.85714286em;
+}
+.fa-border {
+ padding: .2em .25em .15em;
+ border: solid 0.08em #eeeeee;
+ border-radius: .1em;
+}
+.fa-pull-left {
+ float: left;
+}
+.fa-pull-right {
+ float: right;
+}
+.fa.fa-pull-left {
+ margin-right: .3em;
+}
+.fa.fa-pull-right {
+ margin-left: .3em;
+}
+/* Deprecated as of 4.4.0 */
+.pull-right {
+ float: right;
+}
+.pull-left {
+ float: left;
+}
+.fa.pull-left {
+ margin-right: .3em;
+}
+.fa.pull-right {
+ margin-left: .3em;
+}
+.fa-spin {
+ -webkit-animation: fa-spin 2s infinite linear;
+ animation: fa-spin 2s infinite linear;
+}
+.fa-pulse {
+ -webkit-animation: fa-spin 1s infinite steps(8);
+ animation: fa-spin 1s infinite steps(8);
+}
+@-webkit-keyframes fa-spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+}
+@keyframes fa-spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+}
+.fa-rotate-90 {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
+ -webkit-transform: rotate(90deg);
+ -ms-transform: rotate(90deg);
+ transform: rotate(90deg);
+}
+.fa-rotate-180 {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
+ -webkit-transform: rotate(180deg);
+ -ms-transform: rotate(180deg);
+ transform: rotate(180deg);
+}
+.fa-rotate-270 {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
+ -webkit-transform: rotate(270deg);
+ -ms-transform: rotate(270deg);
+ transform: rotate(270deg);
+}
+.fa-flip-horizontal {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
+ -webkit-transform: scale(-1, 1);
+ -ms-transform: scale(-1, 1);
+ transform: scale(-1, 1);
+}
+.fa-flip-vertical {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
+ -webkit-transform: scale(1, -1);
+ -ms-transform: scale(1, -1);
+ transform: scale(1, -1);
+}
+:root .fa-rotate-90,
+:root .fa-rotate-180,
+:root .fa-rotate-270,
+:root .fa-flip-horizontal,
+:root .fa-flip-vertical {
+ filter: none;
+}
+.fa-stack {
+ position: relative;
+ display: inline-block;
+ width: 2em;
+ height: 2em;
+ line-height: 2em;
+ vertical-align: middle;
+}
+.fa-stack-1x,
+.fa-stack-2x {
+ position: absolute;
+ left: 0;
+ width: 100%;
+ text-align: center;
+}
+.fa-stack-1x {
+ line-height: inherit;
+}
+.fa-stack-2x {
+ font-size: 2em;
+}
+.fa-inverse {
+ color: #ffffff;
+}
+/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+ readers do not read off random characters that represent icons */
+.fa-glass:before {
+ content: "\f000";
+}
+.fa-music:before {
+ content: "\f001";
+}
+.fa-search:before {
+ content: "\f002";
+}
+.fa-envelope-o:before {
+ content: "\f003";
+}
+.fa-heart:before {
+ content: "\f004";
+}
+.fa-star:before {
+ content: "\f005";
+}
+.fa-star-o:before {
+ content: "\f006";
+}
+.fa-user:before {
+ content: "\f007";
+}
+.fa-film:before {
+ content: "\f008";
+}
+.fa-th-large:before {
+ content: "\f009";
+}
+.fa-th:before {
+ content: "\f00a";
+}
+.fa-th-list:before {
+ content: "\f00b";
+}
+.fa-check:before {
+ content: "\f00c";
+}
+.fa-remove:before,
+.fa-close:before,
+.fa-times:before {
+ content: "\f00d";
+}
+.fa-search-plus:before {
+ content: "\f00e";
+}
+.fa-search-minus:before {
+ content: "\f010";
+}
+.fa-power-off:before {
+ content: "\f011";
+}
+.fa-signal:before {
+ content: "\f012";
+}
+.fa-gear:before,
+.fa-cog:before {
+ content: "\f013";
+}
+.fa-trash-o:before {
+ content: "\f014";
+}
+.fa-home:before {
+ content: "\f015";
+}
+.fa-file-o:before {
+ content: "\f016";
+}
+.fa-clock-o:before {
+ content: "\f017";
+}
+.fa-road:before {
+ content: "\f018";
+}
+.fa-download:before {
+ content: "\f019";
+}
+.fa-arrow-circle-o-down:before {
+ content: "\f01a";
+}
+.fa-arrow-circle-o-up:before {
+ content: "\f01b";
+}
+.fa-inbox:before {
+ content: "\f01c";
+}
+.fa-play-circle-o:before {
+ content: "\f01d";
+}
+.fa-rotate-right:before,
+.fa-repeat:before {
+ content: "\f01e";
+}
+.fa-refresh:before {
+ content: "\f021";
+}
+.fa-list-alt:before {
+ content: "\f022";
+}
+.fa-lock:before {
+ content: "\f023";
+}
+.fa-flag:before {
+ content: "\f024";
+}
+.fa-headphones:before {
+ content: "\f025";
+}
+.fa-volume-off:before {
+ content: "\f026";
+}
+.fa-volume-down:before {
+ content: "\f027";
+}
+.fa-volume-up:before {
+ content: "\f028";
+}
+.fa-qrcode:before {
+ content: "\f029";
+}
+.fa-barcode:before {
+ content: "\f02a";
+}
+.fa-tag:before {
+ content: "\f02b";
+}
+.fa-tags:before {
+ content: "\f02c";
+}
+.fa-book:before {
+ content: "\f02d";
+}
+.fa-bookmark:before {
+ content: "\f02e";
+}
+.fa-print:before {
+ content: "\f02f";
+}
+.fa-camera:before {
+ content: "\f030";
+}
+.fa-font:before {
+ content: "\f031";
+}
+.fa-bold:before {
+ content: "\f032";
+}
+.fa-italic:before {
+ content: "\f033";
+}
+.fa-text-height:before {
+ content: "\f034";
+}
+.fa-text-width:before {
+ content: "\f035";
+}
+.fa-align-left:before {
+ content: "\f036";
+}
+.fa-align-center:before {
+ content: "\f037";
+}
+.fa-align-right:before {
+ content: "\f038";
+}
+.fa-align-justify:before {
+ content: "\f039";
+}
+.fa-list:before {
+ content: "\f03a";
+}
+.fa-dedent:before,
+.fa-outdent:before {
+ content: "\f03b";
+}
+.fa-indent:before {
+ content: "\f03c";
+}
+.fa-video-camera:before {
+ content: "\f03d";
+}
+.fa-photo:before,
+.fa-image:before,
+.fa-picture-o:before {
+ content: "\f03e";
+}
+.fa-pencil:before {
+ content: "\f040";
+}
+.fa-map-marker:before {
+ content: "\f041";
+}
+.fa-adjust:before {
+ content: "\f042";
+}
+.fa-tint:before {
+ content: "\f043";
+}
+.fa-edit:before,
+.fa-pencil-square-o:before {
+ content: "\f044";
+}
+.fa-share-square-o:before {
+ content: "\f045";
+}
+.fa-check-square-o:before {
+ content: "\f046";
+}
+.fa-arrows:before {
+ content: "\f047";
+}
+.fa-step-backward:before {
+ content: "\f048";
+}
+.fa-fast-backward:before {
+ content: "\f049";
+}
+.fa-backward:before {
+ content: "\f04a";
+}
+.fa-play:before {
+ content: "\f04b";
+}
+.fa-pause:before {
+ content: "\f04c";
+}
+.fa-stop:before {
+ content: "\f04d";
+}
+.fa-forward:before {
+ content: "\f04e";
+}
+.fa-fast-forward:before {
+ content: "\f050";
+}
+.fa-step-forward:before {
+ content: "\f051";
+}
+.fa-eject:before {
+ content: "\f052";
+}
+.fa-chevron-left:before {
+ content: "\f053";
+}
+.fa-chevron-right:before {
+ content: "\f054";
+}
+.fa-plus-circle:before {
+ content: "\f055";
+}
+.fa-minus-circle:before {
+ content: "\f056";
+}
+.fa-times-circle:before {
+ content: "\f057";
+}
+.fa-check-circle:before {
+ content: "\f058";
+}
+.fa-question-circle:before {
+ content: "\f059";
+}
+.fa-info-circle:before {
+ content: "\f05a";
+}
+.fa-crosshairs:before {
+ content: "\f05b";
+}
+.fa-times-circle-o:before {
+ content: "\f05c";
+}
+.fa-check-circle-o:before {
+ content: "\f05d";
+}
+.fa-ban:before {
+ content: "\f05e";
+}
+.fa-arrow-left:before {
+ content: "\f060";
+}
+.fa-arrow-right:before {
+ content: "\f061";
+}
+.fa-arrow-up:before {
+ content: "\f062";
+}
+.fa-arrow-down:before {
+ content: "\f063";
+}
+.fa-mail-forward:before,
+.fa-share:before {
+ content: "\f064";
+}
+.fa-expand:before {
+ content: "\f065";
+}
+.fa-compress:before {
+ content: "\f066";
+}
+.fa-plus:before {
+ content: "\f067";
+}
+.fa-minus:before {
+ content: "\f068";
+}
+.fa-asterisk:before {
+ content: "\f069";
+}
+.fa-exclamation-circle:before {
+ content: "\f06a";
+}
+.fa-gift:before {
+ content: "\f06b";
+}
+.fa-leaf:before {
+ content: "\f06c";
+}
+.fa-fire:before {
+ content: "\f06d";
+}
+.fa-eye:before {
+ content: "\f06e";
+}
+.fa-eye-slash:before {
+ content: "\f070";
+}
+.fa-warning:before,
+.fa-exclamation-triangle:before {
+ content: "\f071";
+}
+.fa-plane:before {
+ content: "\f072";
+}
+.fa-calendar:before {
+ content: "\f073";
+}
+.fa-random:before {
+ content: "\f074";
+}
+.fa-comment:before {
+ content: "\f075";
+}
+.fa-magnet:before {
+ content: "\f076";
+}
+.fa-chevron-up:before {
+ content: "\f077";
+}
+.fa-chevron-down:before {
+ content: "\f078";
+}
+.fa-retweet:before {
+ content: "\f079";
+}
+.fa-shopping-cart:before {
+ content: "\f07a";
+}
+.fa-folder:before {
+ content: "\f07b";
+}
+.fa-folder-open:before {
+ content: "\f07c";
+}
+.fa-arrows-v:before {
+ content: "\f07d";
+}
+.fa-arrows-h:before {
+ content: "\f07e";
+}
+.fa-bar-chart-o:before,
+.fa-bar-chart:before {
+ content: "\f080";
+}
+.fa-twitter-square:before {
+ content: "\f081";
+}
+.fa-facebook-square:before {
+ content: "\f082";
+}
+.fa-camera-retro:before {
+ content: "\f083";
+}
+.fa-key:before {
+ content: "\f084";
+}
+.fa-gears:before,
+.fa-cogs:before {
+ content: "\f085";
+}
+.fa-comments:before {
+ content: "\f086";
+}
+.fa-thumbs-o-up:before {
+ content: "\f087";
+}
+.fa-thumbs-o-down:before {
+ content: "\f088";
+}
+.fa-star-half:before {
+ content: "\f089";
+}
+.fa-heart-o:before {
+ content: "\f08a";
+}
+.fa-sign-out:before {
+ content: "\f08b";
+}
+.fa-linkedin-square:before {
+ content: "\f08c";
+}
+.fa-thumb-tack:before {
+ content: "\f08d";
+}
+.fa-external-link:before {
+ content: "\f08e";
+}
+.fa-sign-in:before {
+ content: "\f090";
+}
+.fa-trophy:before {
+ content: "\f091";
+}
+.fa-github-square:before {
+ content: "\f092";
+}
+.fa-upload:before {
+ content: "\f093";
+}
+.fa-lemon-o:before {
+ content: "\f094";
+}
+.fa-phone:before {
+ content: "\f095";
+}
+.fa-square-o:before {
+ content: "\f096";
+}
+.fa-bookmark-o:before {
+ content: "\f097";
+}
+.fa-phone-square:before {
+ content: "\f098";
+}
+.fa-twitter:before {
+ content: "\f099";
+}
+.fa-facebook-f:before,
+.fa-facebook:before {
+ content: "\f09a";
+}
+.fa-github:before {
+ content: "\f09b";
+}
+.fa-unlock:before {
+ content: "\f09c";
+}
+.fa-credit-card:before {
+ content: "\f09d";
+}
+.fa-feed:before,
+.fa-rss:before {
+ content: "\f09e";
+}
+.fa-hdd-o:before {
+ content: "\f0a0";
+}
+.fa-bullhorn:before {
+ content: "\f0a1";
+}
+.fa-bell:before {
+ content: "\f0f3";
+}
+.fa-certificate:before {
+ content: "\f0a3";
+}
+.fa-hand-o-right:before {
+ content: "\f0a4";
+}
+.fa-hand-o-left:before {
+ content: "\f0a5";
+}
+.fa-hand-o-up:before {
+ content: "\f0a6";
+}
+.fa-hand-o-down:before {
+ content: "\f0a7";
+}
+.fa-arrow-circle-left:before {
+ content: "\f0a8";
+}
+.fa-arrow-circle-right:before {
+ content: "\f0a9";
+}
+.fa-arrow-circle-up:before {
+ content: "\f0aa";
+}
+.fa-arrow-circle-down:before {
+ content: "\f0ab";
+}
+.fa-globe:before {
+ content: "\f0ac";
+}
+.fa-wrench:before {
+ content: "\f0ad";
+}
+.fa-tasks:before {
+ content: "\f0ae";
+}
+.fa-filter:before {
+ content: "\f0b0";
+}
+.fa-briefcase:before {
+ content: "\f0b1";
+}
+.fa-arrows-alt:before {
+ content: "\f0b2";
+}
+.fa-group:before,
+.fa-users:before {
+ content: "\f0c0";
+}
+.fa-chain:before,
+.fa-link:before {
+ content: "\f0c1";
+}
+.fa-cloud:before {
+ content: "\f0c2";
+}
+.fa-flask:before {
+ content: "\f0c3";
+}
+.fa-cut:before,
+.fa-scissors:before {
+ content: "\f0c4";
+}
+.fa-copy:before,
+.fa-files-o:before {
+ content: "\f0c5";
+}
+.fa-paperclip:before {
+ content: "\f0c6";
+}
+.fa-save:before,
+.fa-floppy-o:before {
+ content: "\f0c7";
+}
+.fa-square:before {
+ content: "\f0c8";
+}
+.fa-navicon:before,
+.fa-reorder:before,
+.fa-bars:before {
+ content: "\f0c9";
+}
+.fa-list-ul:before {
+ content: "\f0ca";
+}
+.fa-list-ol:before {
+ content: "\f0cb";
+}
+.fa-strikethrough:before {
+ content: "\f0cc";
+}
+.fa-underline:before {
+ content: "\f0cd";
+}
+.fa-table:before {
+ content: "\f0ce";
+}
+.fa-magic:before {
+ content: "\f0d0";
+}
+.fa-truck:before {
+ content: "\f0d1";
+}
+.fa-pinterest:before {
+ content: "\f0d2";
+}
+.fa-pinterest-square:before {
+ content: "\f0d3";
+}
+.fa-google-plus-square:before {
+ content: "\f0d4";
+}
+.fa-google-plus:before {
+ content: "\f0d5";
+}
+.fa-money:before {
+ content: "\f0d6";
+}
+.fa-caret-down:before {
+ content: "\f0d7";
+}
+.fa-caret-up:before {
+ content: "\f0d8";
+}
+.fa-caret-left:before {
+ content: "\f0d9";
+}
+.fa-caret-right:before {
+ content: "\f0da";
+}
+.fa-columns:before {
+ content: "\f0db";
+}
+.fa-unsorted:before,
+.fa-sort:before {
+ content: "\f0dc";
+}
+.fa-sort-down:before,
+.fa-sort-desc:before {
+ content: "\f0dd";
+}
+.fa-sort-up:before,
+.fa-sort-asc:before {
+ content: "\f0de";
+}
+.fa-envelope:before {
+ content: "\f0e0";
+}
+.fa-linkedin:before {
+ content: "\f0e1";
+}
+.fa-rotate-left:before,
+.fa-undo:before {
+ content: "\f0e2";
+}
+.fa-legal:before,
+.fa-gavel:before {
+ content: "\f0e3";
+}
+.fa-dashboard:before,
+.fa-tachometer:before {
+ content: "\f0e4";
+}
+.fa-comment-o:before {
+ content: "\f0e5";
+}
+.fa-comments-o:before {
+ content: "\f0e6";
+}
+.fa-flash:before,
+.fa-bolt:before {
+ content: "\f0e7";
+}
+.fa-sitemap:before {
+ content: "\f0e8";
+}
+.fa-umbrella:before {
+ content: "\f0e9";
+}
+.fa-paste:before,
+.fa-clipboard:before {
+ content: "\f0ea";
+}
+.fa-lightbulb-o:before {
+ content: "\f0eb";
+}
+.fa-exchange:before {
+ content: "\f0ec";
+}
+.fa-cloud-download:before {
+ content: "\f0ed";
+}
+.fa-cloud-upload:before {
+ content: "\f0ee";
+}
+.fa-user-md:before {
+ content: "\f0f0";
+}
+.fa-stethoscope:before {
+ content: "\f0f1";
+}
+.fa-suitcase:before {
+ content: "\f0f2";
+}
+.fa-bell-o:before {
+ content: "\f0a2";
+}
+.fa-coffee:before {
+ content: "\f0f4";
+}
+.fa-cutlery:before {
+ content: "\f0f5";
+}
+.fa-file-text-o:before {
+ content: "\f0f6";
+}
+.fa-building-o:before {
+ content: "\f0f7";
+}
+.fa-hospital-o:before {
+ content: "\f0f8";
+}
+.fa-ambulance:before {
+ content: "\f0f9";
+}
+.fa-medkit:before {
+ content: "\f0fa";
+}
+.fa-fighter-jet:before {
+ content: "\f0fb";
+}
+.fa-beer:before {
+ content: "\f0fc";
+}
+.fa-h-square:before {
+ content: "\f0fd";
+}
+.fa-plus-square:before {
+ content: "\f0fe";
+}
+.fa-angle-double-left:before {
+ content: "\f100";
+}
+.fa-angle-double-right:before {
+ content: "\f101";
+}
+.fa-angle-double-up:before {
+ content: "\f102";
+}
+.fa-angle-double-down:before {
+ content: "\f103";
+}
+.fa-angle-left:before {
+ content: "\f104";
+}
+.fa-angle-right:before {
+ content: "\f105";
+}
+.fa-angle-up:before {
+ content: "\f106";
+}
+.fa-angle-down:before {
+ content: "\f107";
+}
+.fa-desktop:before {
+ content: "\f108";
+}
+.fa-laptop:before {
+ content: "\f109";
+}
+.fa-tablet:before {
+ content: "\f10a";
+}
+.fa-mobile-phone:before,
+.fa-mobile:before {
+ content: "\f10b";
+}
+.fa-circle-o:before {
+ content: "\f10c";
+}
+.fa-quote-left:before {
+ content: "\f10d";
+}
+.fa-quote-right:before {
+ content: "\f10e";
+}
+.fa-spinner:before {
+ content: "\f110";
+}
+.fa-circle:before {
+ content: "\f111";
+}
+.fa-mail-reply:before,
+.fa-reply:before {
+ content: "\f112";
+}
+.fa-github-alt:before {
+ content: "\f113";
+}
+.fa-folder-o:before {
+ content: "\f114";
+}
+.fa-folder-open-o:before {
+ content: "\f115";
+}
+.fa-smile-o:before {
+ content: "\f118";
+}
+.fa-frown-o:before {
+ content: "\f119";
+}
+.fa-meh-o:before {
+ content: "\f11a";
+}
+.fa-gamepad:before {
+ content: "\f11b";
+}
+.fa-keyboard-o:before {
+ content: "\f11c";
+}
+.fa-flag-o:before {
+ content: "\f11d";
+}
+.fa-flag-checkered:before {
+ content: "\f11e";
+}
+.fa-terminal:before {
+ content: "\f120";
+}
+.fa-code:before {
+ content: "\f121";
+}
+.fa-mail-reply-all:before,
+.fa-reply-all:before {
+ content: "\f122";
+}
+.fa-star-half-empty:before,
+.fa-star-half-full:before,
+.fa-star-half-o:before {
+ content: "\f123";
+}
+.fa-location-arrow:before {
+ content: "\f124";
+}
+.fa-crop:before {
+ content: "\f125";
+}
+.fa-code-fork:before {
+ content: "\f126";
+}
+.fa-unlink:before,
+.fa-chain-broken:before {
+ content: "\f127";
+}
+.fa-question:before {
+ content: "\f128";
+}
+.fa-info:before {
+ content: "\f129";
+}
+.fa-exclamation:before {
+ content: "\f12a";
+}
+.fa-superscript:before {
+ content: "\f12b";
+}
+.fa-subscript:before {
+ content: "\f12c";
+}
+.fa-eraser:before {
+ content: "\f12d";
+}
+.fa-puzzle-piece:before {
+ content: "\f12e";
+}
+.fa-microphone:before {
+ content: "\f130";
+}
+.fa-microphone-slash:before {
+ content: "\f131";
+}
+.fa-shield:before {
+ content: "\f132";
+}
+.fa-calendar-o:before {
+ content: "\f133";
+}
+.fa-fire-extinguisher:before {
+ content: "\f134";
+}
+.fa-rocket:before {
+ content: "\f135";
+}
+.fa-maxcdn:before {
+ content: "\f136";
+}
+.fa-chevron-circle-left:before {
+ content: "\f137";
+}
+.fa-chevron-circle-right:before {
+ content: "\f138";
+}
+.fa-chevron-circle-up:before {
+ content: "\f139";
+}
+.fa-chevron-circle-down:before {
+ content: "\f13a";
+}
+.fa-html5:before {
+ content: "\f13b";
+}
+.fa-css3:before {
+ content: "\f13c";
+}
+.fa-anchor:before {
+ content: "\f13d";
+}
+.fa-unlock-alt:before {
+ content: "\f13e";
+}
+.fa-bullseye:before {
+ content: "\f140";
+}
+.fa-ellipsis-h:before {
+ content: "\f141";
+}
+.fa-ellipsis-v:before {
+ content: "\f142";
+}
+.fa-rss-square:before {
+ content: "\f143";
+}
+.fa-play-circle:before {
+ content: "\f144";
+}
+.fa-ticket:before {
+ content: "\f145";
+}
+.fa-minus-square:before {
+ content: "\f146";
+}
+.fa-minus-square-o:before {
+ content: "\f147";
+}
+.fa-level-up:before {
+ content: "\f148";
+}
+.fa-level-down:before {
+ content: "\f149";
+}
+.fa-check-square:before {
+ content: "\f14a";
+}
+.fa-pencil-square:before {
+ content: "\f14b";
+}
+.fa-external-link-square:before {
+ content: "\f14c";
+}
+.fa-share-square:before {
+ content: "\f14d";
+}
+.fa-compass:before {
+ content: "\f14e";
+}
+.fa-toggle-down:before,
+.fa-caret-square-o-down:before {
+ content: "\f150";
+}
+.fa-toggle-up:before,
+.fa-caret-square-o-up:before {
+ content: "\f151";
+}
+.fa-toggle-right:before,
+.fa-caret-square-o-right:before {
+ content: "\f152";
+}
+.fa-euro:before,
+.fa-eur:before {
+ content: "\f153";
+}
+.fa-gbp:before {
+ content: "\f154";
+}
+.fa-dollar:before,
+.fa-usd:before {
+ content: "\f155";
+}
+.fa-rupee:before,
+.fa-inr:before {
+ content: "\f156";
+}
+.fa-cny:before,
+.fa-rmb:before,
+.fa-yen:before,
+.fa-jpy:before {
+ content: "\f157";
+}
+.fa-ruble:before,
+.fa-rouble:before,
+.fa-rub:before {
+ content: "\f158";
+}
+.fa-won:before,
+.fa-krw:before {
+ content: "\f159";
+}
+.fa-bitcoin:before,
+.fa-btc:before {
+ content: "\f15a";
+}
+.fa-file:before {
+ content: "\f15b";
+}
+.fa-file-text:before {
+ content: "\f15c";
+}
+.fa-sort-alpha-asc:before {
+ content: "\f15d";
+}
+.fa-sort-alpha-desc:before {
+ content: "\f15e";
+}
+.fa-sort-amount-asc:before {
+ content: "\f160";
+}
+.fa-sort-amount-desc:before {
+ content: "\f161";
+}
+.fa-sort-numeric-asc:before {
+ content: "\f162";
+}
+.fa-sort-numeric-desc:before {
+ content: "\f163";
+}
+.fa-thumbs-up:before {
+ content: "\f164";
+}
+.fa-thumbs-down:before {
+ content: "\f165";
+}
+.fa-youtube-square:before {
+ content: "\f166";
+}
+.fa-youtube:before {
+ content: "\f167";
+}
+.fa-xing:before {
+ content: "\f168";
+}
+.fa-xing-square:before {
+ content: "\f169";
+}
+.fa-youtube-play:before {
+ content: "\f16a";
+}
+.fa-dropbox:before {
+ content: "\f16b";
+}
+.fa-stack-overflow:before {
+ content: "\f16c";
+}
+.fa-instagram:before {
+ content: "\f16d";
+}
+.fa-flickr:before {
+ content: "\f16e";
+}
+.fa-adn:before {
+ content: "\f170";
+}
+.fa-bitbucket:before {
+ content: "\f171";
+}
+.fa-bitbucket-square:before {
+ content: "\f172";
+}
+.fa-tumblr:before {
+ content: "\f173";
+}
+.fa-tumblr-square:before {
+ content: "\f174";
+}
+.fa-long-arrow-down:before {
+ content: "\f175";
+}
+.fa-long-arrow-up:before {
+ content: "\f176";
+}
+.fa-long-arrow-left:before {
+ content: "\f177";
+}
+.fa-long-arrow-right:before {
+ content: "\f178";
+}
+.fa-apple:before {
+ content: "\f179";
+}
+.fa-windows:before {
+ content: "\f17a";
+}
+.fa-android:before {
+ content: "\f17b";
+}
+.fa-linux:before {
+ content: "\f17c";
+}
+.fa-dribbble:before {
+ content: "\f17d";
+}
+.fa-skype:before {
+ content: "\f17e";
+}
+.fa-foursquare:before {
+ content: "\f180";
+}
+.fa-trello:before {
+ content: "\f181";
+}
+.fa-female:before {
+ content: "\f182";
+}
+.fa-male:before {
+ content: "\f183";
+}
+.fa-gittip:before,
+.fa-gratipay:before {
+ content: "\f184";
+}
+.fa-sun-o:before {
+ content: "\f185";
+}
+.fa-moon-o:before {
+ content: "\f186";
+}
+.fa-archive:before {
+ content: "\f187";
+}
+.fa-bug:before {
+ content: "\f188";
+}
+.fa-vk:before {
+ content: "\f189";
+}
+.fa-weibo:before {
+ content: "\f18a";
+}
+.fa-renren:before {
+ content: "\f18b";
+}
+.fa-pagelines:before {
+ content: "\f18c";
+}
+.fa-stack-exchange:before {
+ content: "\f18d";
+}
+.fa-arrow-circle-o-right:before {
+ content: "\f18e";
+}
+.fa-arrow-circle-o-left:before {
+ content: "\f190";
+}
+.fa-toggle-left:before,
+.fa-caret-square-o-left:before {
+ content: "\f191";
+}
+.fa-dot-circle-o:before {
+ content: "\f192";
+}
+.fa-wheelchair:before {
+ content: "\f193";
+}
+.fa-vimeo-square:before {
+ content: "\f194";
+}
+.fa-turkish-lira:before,
+.fa-try:before {
+ content: "\f195";
+}
+.fa-plus-square-o:before {
+ content: "\f196";
+}
+.fa-space-shuttle:before {
+ content: "\f197";
+}
+.fa-slack:before {
+ content: "\f198";
+}
+.fa-envelope-square:before {
+ content: "\f199";
+}
+.fa-wordpress:before {
+ content: "\f19a";
+}
+.fa-openid:before {
+ content: "\f19b";
+}
+.fa-institution:before,
+.fa-bank:before,
+.fa-university:before {
+ content: "\f19c";
+}
+.fa-mortar-board:before,
+.fa-graduation-cap:before {
+ content: "\f19d";
+}
+.fa-yahoo:before {
+ content: "\f19e";
+}
+.fa-google:before {
+ content: "\f1a0";
+}
+.fa-reddit:before {
+ content: "\f1a1";
+}
+.fa-reddit-square:before {
+ content: "\f1a2";
+}
+.fa-stumbleupon-circle:before {
+ content: "\f1a3";
+}
+.fa-stumbleupon:before {
+ content: "\f1a4";
+}
+.fa-delicious:before {
+ content: "\f1a5";
+}
+.fa-digg:before {
+ content: "\f1a6";
+}
+.fa-pied-piper:before {
+ content: "\f1a7";
+}
+.fa-pied-piper-alt:before {
+ content: "\f1a8";
+}
+.fa-drupal:before {
+ content: "\f1a9";
+}
+.fa-joomla:before {
+ content: "\f1aa";
+}
+.fa-language:before {
+ content: "\f1ab";
+}
+.fa-fax:before {
+ content: "\f1ac";
+}
+.fa-building:before {
+ content: "\f1ad";
+}
+.fa-child:before {
+ content: "\f1ae";
+}
+.fa-paw:before {
+ content: "\f1b0";
+}
+.fa-spoon:before {
+ content: "\f1b1";
+}
+.fa-cube:before {
+ content: "\f1b2";
+}
+.fa-cubes:before {
+ content: "\f1b3";
+}
+.fa-behance:before {
+ content: "\f1b4";
+}
+.fa-behance-square:before {
+ content: "\f1b5";
+}
+.fa-steam:before {
+ content: "\f1b6";
+}
+.fa-steam-square:before {
+ content: "\f1b7";
+}
+.fa-recycle:before {
+ content: "\f1b8";
+}
+.fa-automobile:before,
+.fa-car:before {
+ content: "\f1b9";
+}
+.fa-cab:before,
+.fa-taxi:before {
+ content: "\f1ba";
+}
+.fa-tree:before {
+ content: "\f1bb";
+}
+.fa-spotify:before {
+ content: "\f1bc";
+}
+.fa-deviantart:before {
+ content: "\f1bd";
+}
+.fa-soundcloud:before {
+ content: "\f1be";
+}
+.fa-database:before {
+ content: "\f1c0";
+}
+.fa-file-pdf-o:before {
+ content: "\f1c1";
+}
+.fa-file-word-o:before {
+ content: "\f1c2";
+}
+.fa-file-excel-o:before {
+ content: "\f1c3";
+}
+.fa-file-powerpoint-o:before {
+ content: "\f1c4";
+}
+.fa-file-photo-o:before,
+.fa-file-picture-o:before,
+.fa-file-image-o:before {
+ content: "\f1c5";
+}
+.fa-file-zip-o:before,
+.fa-file-archive-o:before {
+ content: "\f1c6";
+}
+.fa-file-sound-o:before,
+.fa-file-audio-o:before {
+ content: "\f1c7";
+}
+.fa-file-movie-o:before,
+.fa-file-video-o:before {
+ content: "\f1c8";
+}
+.fa-file-code-o:before {
+ content: "\f1c9";
+}
+.fa-vine:before {
+ content: "\f1ca";
+}
+.fa-codepen:before {
+ content: "\f1cb";
+}
+.fa-jsfiddle:before {
+ content: "\f1cc";
+}
+.fa-life-bouy:before,
+.fa-life-buoy:before,
+.fa-life-saver:before,
+.fa-support:before,
+.fa-life-ring:before {
+ content: "\f1cd";
+}
+.fa-circle-o-notch:before {
+ content: "\f1ce";
+}
+.fa-ra:before,
+.fa-rebel:before {
+ content: "\f1d0";
+}
+.fa-ge:before,
+.fa-empire:before {
+ content: "\f1d1";
+}
+.fa-git-square:before {
+ content: "\f1d2";
+}
+.fa-git:before {
+ content: "\f1d3";
+}
+.fa-y-combinator-square:before,
+.fa-yc-square:before,
+.fa-hacker-news:before {
+ content: "\f1d4";
+}
+.fa-tencent-weibo:before {
+ content: "\f1d5";
+}
+.fa-qq:before {
+ content: "\f1d6";
+}
+.fa-wechat:before,
+.fa-weixin:before {
+ content: "\f1d7";
+}
+.fa-send:before,
+.fa-paper-plane:before {
+ content: "\f1d8";
+}
+.fa-send-o:before,
+.fa-paper-plane-o:before {
+ content: "\f1d9";
+}
+.fa-history:before {
+ content: "\f1da";
+}
+.fa-circle-thin:before {
+ content: "\f1db";
+}
+.fa-header:before {
+ content: "\f1dc";
+}
+.fa-paragraph:before {
+ content: "\f1dd";
+}
+.fa-sliders:before {
+ content: "\f1de";
+}
+.fa-share-alt:before {
+ content: "\f1e0";
+}
+.fa-share-alt-square:before {
+ content: "\f1e1";
+}
+.fa-bomb:before {
+ content: "\f1e2";
+}
+.fa-soccer-ball-o:before,
+.fa-futbol-o:before {
+ content: "\f1e3";
+}
+.fa-tty:before {
+ content: "\f1e4";
+}
+.fa-binoculars:before {
+ content: "\f1e5";
+}
+.fa-plug:before {
+ content: "\f1e6";
+}
+.fa-slideshare:before {
+ content: "\f1e7";
+}
+.fa-twitch:before {
+ content: "\f1e8";
+}
+.fa-yelp:before {
+ content: "\f1e9";
+}
+.fa-newspaper-o:before {
+ content: "\f1ea";
+}
+.fa-wifi:before {
+ content: "\f1eb";
+}
+.fa-calculator:before {
+ content: "\f1ec";
+}
+.fa-paypal:before {
+ content: "\f1ed";
+}
+.fa-google-wallet:before {
+ content: "\f1ee";
+}
+.fa-cc-visa:before {
+ content: "\f1f0";
+}
+.fa-cc-mastercard:before {
+ content: "\f1f1";
+}
+.fa-cc-discover:before {
+ content: "\f1f2";
+}
+.fa-cc-amex:before {
+ content: "\f1f3";
+}
+.fa-cc-paypal:before {
+ content: "\f1f4";
+}
+.fa-cc-stripe:before {
+ content: "\f1f5";
+}
+.fa-bell-slash:before {
+ content: "\f1f6";
+}
+.fa-bell-slash-o:before {
+ content: "\f1f7";
+}
+.fa-trash:before {
+ content: "\f1f8";
+}
+.fa-copyright:before {
+ content: "\f1f9";
+}
+.fa-at:before {
+ content: "\f1fa";
+}
+.fa-eyedropper:before {
+ content: "\f1fb";
+}
+.fa-paint-brush:before {
+ content: "\f1fc";
+}
+.fa-birthday-cake:before {
+ content: "\f1fd";
+}
+.fa-area-chart:before {
+ content: "\f1fe";
+}
+.fa-pie-chart:before {
+ content: "\f200";
+}
+.fa-line-chart:before {
+ content: "\f201";
+}
+.fa-lastfm:before {
+ content: "\f202";
+}
+.fa-lastfm-square:before {
+ content: "\f203";
+}
+.fa-toggle-off:before {
+ content: "\f204";
+}
+.fa-toggle-on:before {
+ content: "\f205";
+}
+.fa-bicycle:before {
+ content: "\f206";
+}
+.fa-bus:before {
+ content: "\f207";
+}
+.fa-ioxhost:before {
+ content: "\f208";
+}
+.fa-angellist:before {
+ content: "\f209";
+}
+.fa-cc:before {
+ content: "\f20a";
+}
+.fa-shekel:before,
+.fa-sheqel:before,
+.fa-ils:before {
+ content: "\f20b";
+}
+.fa-meanpath:before {
+ content: "\f20c";
+}
+.fa-buysellads:before {
+ content: "\f20d";
+}
+.fa-connectdevelop:before {
+ content: "\f20e";
+}
+.fa-dashcube:before {
+ content: "\f210";
+}
+.fa-forumbee:before {
+ content: "\f211";
+}
+.fa-leanpub:before {
+ content: "\f212";
+}
+.fa-sellsy:before {
+ content: "\f213";
+}
+.fa-shirtsinbulk:before {
+ content: "\f214";
+}
+.fa-simplybuilt:before {
+ content: "\f215";
+}
+.fa-skyatlas:before {
+ content: "\f216";
+}
+.fa-cart-plus:before {
+ content: "\f217";
+}
+.fa-cart-arrow-down:before {
+ content: "\f218";
+}
+.fa-diamond:before {
+ content: "\f219";
+}
+.fa-ship:before {
+ content: "\f21a";
+}
+.fa-user-secret:before {
+ content: "\f21b";
+}
+.fa-motorcycle:before {
+ content: "\f21c";
+}
+.fa-street-view:before {
+ content: "\f21d";
+}
+.fa-heartbeat:before {
+ content: "\f21e";
+}
+.fa-venus:before {
+ content: "\f221";
+}
+.fa-mars:before {
+ content: "\f222";
+}
+.fa-mercury:before {
+ content: "\f223";
+}
+.fa-intersex:before,
+.fa-transgender:before {
+ content: "\f224";
+}
+.fa-transgender-alt:before {
+ content: "\f225";
+}
+.fa-venus-double:before {
+ content: "\f226";
+}
+.fa-mars-double:before {
+ content: "\f227";
+}
+.fa-venus-mars:before {
+ content: "\f228";
+}
+.fa-mars-stroke:before {
+ content: "\f229";
+}
+.fa-mars-stroke-v:before {
+ content: "\f22a";
+}
+.fa-mars-stroke-h:before {
+ content: "\f22b";
+}
+.fa-neuter:before {
+ content: "\f22c";
+}
+.fa-genderless:before {
+ content: "\f22d";
+}
+.fa-facebook-official:before {
+ content: "\f230";
+}
+.fa-pinterest-p:before {
+ content: "\f231";
+}
+.fa-whatsapp:before {
+ content: "\f232";
+}
+.fa-server:before {
+ content: "\f233";
+}
+.fa-user-plus:before {
+ content: "\f234";
+}
+.fa-user-times:before {
+ content: "\f235";
+}
+.fa-hotel:before,
+.fa-bed:before {
+ content: "\f236";
+}
+.fa-viacoin:before {
+ content: "\f237";
+}
+.fa-train:before {
+ content: "\f238";
+}
+.fa-subway:before {
+ content: "\f239";
+}
+.fa-medium:before {
+ content: "\f23a";
+}
+.fa-yc:before,
+.fa-y-combinator:before {
+ content: "\f23b";
+}
+.fa-optin-monster:before {
+ content: "\f23c";
+}
+.fa-opencart:before {
+ content: "\f23d";
+}
+.fa-expeditedssl:before {
+ content: "\f23e";
+}
+.fa-battery-4:before,
+.fa-battery-full:before {
+ content: "\f240";
+}
+.fa-battery-3:before,
+.fa-battery-three-quarters:before {
+ content: "\f241";
+}
+.fa-battery-2:before,
+.fa-battery-half:before {
+ content: "\f242";
+}
+.fa-battery-1:before,
+.fa-battery-quarter:before {
+ content: "\f243";
+}
+.fa-battery-0:before,
+.fa-battery-empty:before {
+ content: "\f244";
+}
+.fa-mouse-pointer:before {
+ content: "\f245";
+}
+.fa-i-cursor:before {
+ content: "\f246";
+}
+.fa-object-group:before {
+ content: "\f247";
+}
+.fa-object-ungroup:before {
+ content: "\f248";
+}
+.fa-sticky-note:before {
+ content: "\f249";
+}
+.fa-sticky-note-o:before {
+ content: "\f24a";
+}
+.fa-cc-jcb:before {
+ content: "\f24b";
+}
+.fa-cc-diners-club:before {
+ content: "\f24c";
+}
+.fa-clone:before {
+ content: "\f24d";
+}
+.fa-balance-scale:before {
+ content: "\f24e";
+}
+.fa-hourglass-o:before {
+ content: "\f250";
+}
+.fa-hourglass-1:before,
+.fa-hourglass-start:before {
+ content: "\f251";
+}
+.fa-hourglass-2:before,
+.fa-hourglass-half:before {
+ content: "\f252";
+}
+.fa-hourglass-3:before,
+.fa-hourglass-end:before {
+ content: "\f253";
+}
+.fa-hourglass:before {
+ content: "\f254";
+}
+.fa-hand-grab-o:before,
+.fa-hand-rock-o:before {
+ content: "\f255";
+}
+.fa-hand-stop-o:before,
+.fa-hand-paper-o:before {
+ content: "\f256";
+}
+.fa-hand-scissors-o:before {
+ content: "\f257";
+}
+.fa-hand-lizard-o:before {
+ content: "\f258";
+}
+.fa-hand-spock-o:before {
+ content: "\f259";
+}
+.fa-hand-pointer-o:before {
+ content: "\f25a";
+}
+.fa-hand-peace-o:before {
+ content: "\f25b";
+}
+.fa-trademark:before {
+ content: "\f25c";
+}
+.fa-registered:before {
+ content: "\f25d";
+}
+.fa-creative-commons:before {
+ content: "\f25e";
+}
+.fa-gg:before {
+ content: "\f260";
+}
+.fa-gg-circle:before {
+ content: "\f261";
+}
+.fa-tripadvisor:before {
+ content: "\f262";
+}
+.fa-odnoklassniki:before {
+ content: "\f263";
+}
+.fa-odnoklassniki-square:before {
+ content: "\f264";
+}
+.fa-get-pocket:before {
+ content: "\f265";
+}
+.fa-wikipedia-w:before {
+ content: "\f266";
+}
+.fa-safari:before {
+ content: "\f267";
+}
+.fa-chrome:before {
+ content: "\f268";
+}
+.fa-firefox:before {
+ content: "\f269";
+}
+.fa-opera:before {
+ content: "\f26a";
+}
+.fa-internet-explorer:before {
+ content: "\f26b";
+}
+.fa-tv:before,
+.fa-television:before {
+ content: "\f26c";
+}
+.fa-contao:before {
+ content: "\f26d";
+}
+.fa-500px:before {
+ content: "\f26e";
+}
+.fa-amazon:before {
+ content: "\f270";
+}
+.fa-calendar-plus-o:before {
+ content: "\f271";
+}
+.fa-calendar-minus-o:before {
+ content: "\f272";
+}
+.fa-calendar-times-o:before {
+ content: "\f273";
+}
+.fa-calendar-check-o:before {
+ content: "\f274";
+}
+.fa-industry:before {
+ content: "\f275";
+}
+.fa-map-pin:before {
+ content: "\f276";
+}
+.fa-map-signs:before {
+ content: "\f277";
+}
+.fa-map-o:before {
+ content: "\f278";
+}
+.fa-map:before {
+ content: "\f279";
+}
+.fa-commenting:before {
+ content: "\f27a";
+}
+.fa-commenting-o:before {
+ content: "\f27b";
+}
+.fa-houzz:before {
+ content: "\f27c";
+}
+.fa-vimeo:before {
+ content: "\f27d";
+}
+.fa-black-tie:before {
+ content: "\f27e";
+}
+.fa-fonticons:before {
+ content: "\f280";
+}
+.fa-reddit-alien:before {
+ content: "\f281";
+}
+.fa-edge:before {
+ content: "\f282";
+}
+.fa-credit-card-alt:before {
+ content: "\f283";
+}
+.fa-codiepie:before {
+ content: "\f284";
+}
+.fa-modx:before {
+ content: "\f285";
+}
+.fa-fort-awesome:before {
+ content: "\f286";
+}
+.fa-usb:before {
+ content: "\f287";
+}
+.fa-product-hunt:before {
+ content: "\f288";
+}
+.fa-mixcloud:before {
+ content: "\f289";
+}
+.fa-scribd:before {
+ content: "\f28a";
+}
+.fa-pause-circle:before {
+ content: "\f28b";
+}
+.fa-pause-circle-o:before {
+ content: "\f28c";
+}
+.fa-stop-circle:before {
+ content: "\f28d";
+}
+.fa-stop-circle-o:before {
+ content: "\f28e";
+}
+.fa-shopping-bag:before {
+ content: "\f290";
+}
+.fa-shopping-basket:before {
+ content: "\f291";
+}
+.fa-hashtag:before {
+ content: "\f292";
+}
+.fa-bluetooth:before {
+ content: "\f293";
+}
+.fa-bluetooth-b:before {
+ content: "\f294";
+}
+.fa-percent:before {
+ content: "\f295";
+}
+.fa-gitlab:before {
+ content: "\f296";
+}
+.fa-wpbeginner:before {
+ content: "\f297";
+}
+.fa-wpforms:before {
+ content: "\f298";
+}
+.fa-envira:before {
+ content: "\f299";
+}
+.fa-universal-access:before {
+ content: "\f29a";
+}
+.fa-wheelchair-alt:before {
+ content: "\f29b";
+}
+.fa-question-circle-o:before {
+ content: "\f29c";
+}
+.fa-blind:before {
+ content: "\f29d";
+}
+.fa-audio-description:before {
+ content: "\f29e";
+}
+.fa-volume-control-phone:before {
+ content: "\f2a0";
+}
+.fa-braille:before {
+ content: "\f2a1";
+}
+.fa-assistive-listening-systems:before {
+ content: "\f2a2";
+}
+.fa-asl-interpreting:before,
+.fa-american-sign-language-interpreting:before {
+ content: "\f2a3";
+}
+.fa-deafness:before,
+.fa-hard-of-hearing:before,
+.fa-deaf:before {
+ content: "\f2a4";
+}
+.fa-glide:before {
+ content: "\f2a5";
+}
+.fa-glide-g:before {
+ content: "\f2a6";
+}
+.fa-signing:before,
+.fa-sign-language:before {
+ content: "\f2a7";
+}
+.fa-low-vision:before {
+ content: "\f2a8";
+}
+.fa-viadeo:before {
+ content: "\f2a9";
+}
+.fa-viadeo-square:before {
+ content: "\f2aa";
+}
+.fa-snapchat:before {
+ content: "\f2ab";
+}
+.fa-snapchat-ghost:before {
+ content: "\f2ac";
+}
+.fa-snapchat-square:before {
+ content: "\f2ad";
+}
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0;
+}
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+}
diff --git a/membership/static/font-awesome/css/font-awesome.css.map b/membership/static/font-awesome/css/font-awesome.css.map
new file mode 100755
index 0000000..60763a8
--- /dev/null
+++ b/membership/static/font-awesome/css/font-awesome.css.map
@@ -0,0 +1,7 @@
+{
+"version": 3,
+"mappings": ";;;;;;;AAGA,UAUC;EATC,WAAW,EAAE,aAAa;EAC1B,GAAG,EAAE,+CAAgE;EACrE,GAAG,EAAE,ySAAmG;EAKxG,WAAW,EAAE,MAAM;EACnB,UAAU,EAAE,MAAM;ACTpB,GAAmB;EACjB,OAAO,EAAE,YAAY;EACrB,IAAI,EAAE,uCAAwD;EAC9D,SAAS,EAAE,OAAO;EAClB,cAAc,EAAE,IAAI;EACpB,sBAAsB,EAAE,WAAW;EACnC,uBAAuB,EAAE,SAAS;EAClC,SAAS,EAAE,eAAe;;;ACN5B,MAAsB;EACpB,SAAS,EAAE,SAAS;EACpB,WAAW,EAAE,MAAS;EACtB,cAAc,EAAE,IAAI;;AAEtB,MAAsB;EAAE,SAAS,EAAE,GAAG;;AACtC,MAAsB;EAAE,SAAS,EAAE,GAAG;;AACtC,MAAsB;EAAE,SAAS,EAAE,GAAG;;AACtC,MAAsB;EAAE,SAAS,EAAE,GAAG;;ACVtC,MAAsB;EACpB,KAAK,EAAE,SAAW;EAClB,UAAU,EAAE,MAAM;;ACDpB,MAAsB;EACpB,YAAY,EAAE,CAAC;EACf,WAAW,ECKU,SAAS;EDJ9B,eAAe,EAAE,IAAI;EACrB,WAAK;IAAE,QAAQ,EAAE,QAAQ;;AAE3B,MAAsB;EACpB,QAAQ,EAAE,QAAQ;EAClB,IAAI,EAAE,UAAa;EACnB,KAAK,ECFgB,SAAS;EDG9B,GAAG,EAAE,SAAU;EACf,UAAU,EAAE,MAAM;EAClB,YAAuB;IACrB,IAAI,EAAE,UAA0B;;AEbpC,UAA0B;EACxB,OAAO,EAAE,gBAAgB;EACzB,MAAM,EAAE,iBAA4B;EACpC,aAAa,EAAE,IAAI;;AAGrB,WAAY;EAAE,KAAK,EAAE,KAAK;;AAC1B,UAAW;EAAE,KAAK,EAAE,IAAI;;AAGtB,aAAY;EAAE,YAAY,EAAE,IAAI;AAChC,cAAa;EAAE,WAAW,EAAE,IAAI;;ACXlC,QAAwB;EACtB,iBAAiB,EAAE,0BAA0B;EACrC,SAAS,EAAE,0BAA0B;;AAG/C,SAAyB;EACvB,iBAAiB,EAAE,4BAA4B;EACvC,SAAS,EAAE,4BAA4B;;AAGjD,0BASC;EARC,EAAG;IACD,iBAAiB,EAAE,YAAY;IACvB,SAAS,EAAE,YAAY;EAEjC,IAAK;IACH,iBAAiB,EAAE,cAAc;IACzB,SAAS,EAAE,cAAc;AAIrC,kBASC;EARC,EAAG;IACD,iBAAiB,EAAE,YAAY;IACvB,SAAS,EAAE,YAAY;EAEjC,IAAK;IACH,iBAAiB,EAAE,cAAc;IACzB,SAAS,EAAE,cAAc;AC5BrC,aAA8B;ECY5B,MAAM,EAAE,wDAAmE;EAC3E,iBAAiB,EAAE,aAAgB;EAC/B,aAAa,EAAE,aAAgB;EAC3B,SAAS,EAAE,aAAgB;;ADdrC,cAA8B;ECW5B,MAAM,EAAE,wDAAmE;EAC3E,iBAAiB,EAAE,cAAgB;EAC/B,aAAa,EAAE,cAAgB;EAC3B,SAAS,EAAE,cAAgB;;ADbrC,cAA8B;ECU5B,MAAM,EAAE,wDAAmE;EAC3E,iBAAiB,EAAE,cAAgB;EAC/B,aAAa,EAAE,cAAgB;EAC3B,SAAS,EAAE,cAAgB;;ADXrC,mBAAmC;ECejC,MAAM,EAAE,wDAAmE;EAC3E,iBAAiB,EAAE,YAAoB;EACnC,aAAa,EAAE,YAAoB;EAC/B,SAAS,EAAE,YAAoB;;ADjBzC,iBAAmC;ECcjC,MAAM,EAAE,wDAAmE;EAC3E,iBAAiB,EAAE,YAAoB;EACnC,aAAa,EAAE,YAAoB;EAC/B,SAAS,EAAE,YAAoB;;ADZzC;;;;uBAIuC;EACrC,MAAM,EAAE,IAAI;;AEfd,SAAyB;EACvB,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,YAAY;EACrB,KAAK,EAAE,GAAG;EACV,MAAM,EAAE,GAAG;EACX,WAAW,EAAE,GAAG;EAChB,cAAc,EAAE,MAAM;;AAExB,0BAAyD;EACvD,QAAQ,EAAE,QAAQ;EAClB,IAAI,EAAE,CAAC;EACP,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,MAAM;;AAEpB,YAA4B;EAAE,WAAW,EAAE,OAAO;;AAClD,YAA4B;EAAE,SAAS,EAAE,GAAG;;AAC5C,WAA2B;EAAE,KAAK,ELVZ,IAAI;;;;AMN1B,gBAAgC;EAAE,OAAO,ENoQ1B,GAAO;;AMnQtB,gBAAgC;EAAE,OAAO,EN0W1B,GAAO;;AMzWtB,iBAAiC;EAAE,OAAO,ENmb1B,GAAO;;AMlbvB,qBAAqC;EAAE,OAAO,ENmL1B,GAAO;;AMlL3B,gBAAgC;EAAE,OAAO,ENkR1B,GAAO;;AMjRtB,eAA+B;EAAE,OAAO,ENke1B,GAAO;;AMjerB,iBAAiC;EAAE,OAAO,ENse1B,GAAO;;AMrevB,eAA+B;EAAE,OAAO,EN+iB1B,GAAO;;AM9iBrB,eAA+B;EAAE,OAAO,ENyN1B,GAAO;;AMxNrB,mBAAmC;EAAE,OAAO,ENggB1B,GAAO;;AM/fzB,aAA6B;EAAE,OAAO,EN8f1B,GAAO;;AM7fnB,kBAAkC;EAAE,OAAO,EN+f1B,GAAO;;AM9fxB,gBAAgC;EAAE,OAAO,ENoG1B,GAAO;;AMnGtB;;gBAEgC;EAAE,OAAO,ENkgB1B,GAAO;;AMjgBtB,sBAAsC;EAAE,OAAO,ENua1B,GAAO;;AMta5B,uBAAuC;EAAE,OAAO,ENqa1B,GAAO;;AMpa7B,oBAAoC;EAAE,OAAO,EN+X1B,GAAO;;AM9X1B,iBAAiC;EAAE,OAAO,ENsb1B,GAAO;;AMrbvB;cAC8B;EAAE,OAAO,ENwH1B,GAAO;;AMvHpB,kBAAkC;EAAE,OAAO,ENygB1B,GAAO;;AMxgBxB,eAA+B;EAAE,OAAO,ENmQ1B,GAAO;;AMlQrB,iBAAiC;EAAE,OAAO,EN6L1B,GAAO;;AM5LvB,kBAAkC;EAAE,OAAO,EN0G1B,GAAO;;AMzGxB,eAA+B;EAAE,OAAO,EN+Y1B,GAAO;;AM9YrB,mBAAmC;EAAE,OAAO,ENiJ1B,GAAO;;AMhJzB,8BAA8C;EAAE,OAAO,ENI1B,GAAO;;AMHpC,4BAA4C;EAAE,OAAO,ENM1B,GAAO;;AMLlC,gBAAgC;EAAE,OAAO,ENkQ1B,GAAO;;AMjQtB,wBAAwC;EAAE,OAAO,EN4W1B,GAAO;;AM3W9B;iBACiC;EAAE,OAAO,ENmY1B,GAAO;;AMlYvB,kBAAkC;EAAE,OAAO,EN8X1B,GAAO;;AM7XxB,mBAAmC;EAAE,OAAO,ENiS1B,GAAO;;AMhSzB,eAA+B;EAAE,OAAO,ENoS1B,GAAO;;AMnSrB,eAA+B;EAAE,OAAO,ENgM1B,GAAO;;AM/LrB,qBAAqC;EAAE,OAAO,EN+O1B,GAAO;;AM9O3B,qBAAqC;EAAE,OAAO,EN8hB1B,GAAO;;AM7hB3B,sBAAsC;EAAE,OAAO,EN4hB1B,GAAO;;AM3hB5B,oBAAoC;EAAE,OAAO,EN6hB1B,GAAO;;AM5hB1B,iBAAiC;EAAE,OAAO,EN2W1B,GAAO;;AM1WvB,kBAAkC;EAAE,OAAO,ENW1B,GAAO;;AMVxB,cAA8B;EAAE,OAAO,ENod1B,GAAO;;AMndpB,eAA+B;EAAE,OAAO,ENod1B,GAAO;;AMndrB,eAA+B;EAAE,OAAO,EN2B1B,GAAO;;AM1BrB,mBAAmC;EAAE,OAAO,EN2B1B,GAAO;;AM1BzB,gBAAgC;EAAE,OAAO,ENkW1B,GAAO;;AMjWtB,iBAAiC;EAAE,OAAO,ENwC1B,GAAO;;AMvCvB,eAA+B;EAAE,OAAO,EN8L1B,GAAO;;AM7LrB,eAA+B;EAAE,OAAO,ENmB1B,GAAO;;AMlBrB,iBAAiC;EAAE,OAAO,ENoP1B,GAAO;;AMnPvB,sBAAsC;EAAE,OAAO,ENid1B,GAAO;;AMhd5B,qBAAqC;EAAE,OAAO,ENid1B,GAAO;;AMhd3B,qBAAqC;EAAE,OAAO,EN1C1B,GAAO;;AM2C3B,uBAAuC;EAAE,OAAO,EN7C1B,GAAO;;AM8C7B,sBAAsC;EAAE,OAAO,EN3C1B,GAAO;;AM4C5B,wBAAwC;EAAE,OAAO,EN9C1B,GAAO;;AM+C9B,eAA+B;EAAE,OAAO,ENwQ1B,GAAO;;AMvQrB;kBACkC;EAAE,OAAO,ENmT1B,GAAO;;AMlTxB,iBAAiC;EAAE,OAAO,ENmO1B,GAAO;;AMlOvB,uBAAuC;EAAE,OAAO,ENigB1B,GAAO;;AMhgB7B;;oBAEoC;EAAE,OAAO,EN+T1B,GAAO;;AM9T1B,iBAAiC;EAAE,OAAO,ENwT1B,GAAO;;AMvTvB,qBAAqC;EAAE,OAAO,EN+Q1B,GAAO;;AM9Q3B,iBAAiC;EAAE,OAAO,EN5D1B,GAAO;;AM6DvB,eAA+B;EAAE,OAAO,EN8c1B,GAAO;;AM7crB;0BAC0C;EAAE,OAAO,ENqT1B,GAAO;;AMpThC,yBAAyC;EAAE,OAAO,ENuX1B,GAAO;;AMtX/B,yBAAyC;EAAE,OAAO,EN0C1B,GAAO;;AMzC/B,iBAAiC;EAAE,OAAO,ENjC1B,GAAO;;AMkCvB,wBAAwC;EAAE,OAAO,ENma1B,GAAO;;AMla9B,wBAAwC;EAAE,OAAO,EN4H1B,GAAO;;AM3H9B,mBAAmC;EAAE,OAAO,EN7B1B,GAAO;;AM8BzB,eAA+B;EAAE,OAAO,EN0T1B,GAAO;;AMzTrB,gBAAgC;EAAE,OAAO,ENwS1B,GAAO;;AMvStB,eAA+B;EAAE,OAAO,ENia1B,GAAO;;AMharB,kBAAkC;EAAE,OAAO,ENgK1B,GAAO;;AM/JxB,uBAAuC;EAAE,OAAO,ENuH1B,GAAO;;AMtH7B,uBAAuC;EAAE,OAAO,EN4Z1B,GAAO;;AM3Z7B,gBAAgC;EAAE,OAAO,EN4F1B,GAAO;;AM3FtB,uBAAuC;EAAE,OAAO,ENoC1B,GAAO;;AMnC7B,wBAAwC;EAAE,OAAO,ENoC1B,GAAO;;AMnC9B,sBAAsC;EAAE,OAAO,ENsT1B,GAAO;;AMrT5B,uBAAuC;EAAE,OAAO,ENyQ1B,GAAO;;AMxQ7B,uBAAuC;EAAE,OAAO,ENwb1B,GAAO;;AMvb7B,uBAAuC;EAAE,OAAO,ENsB1B,GAAO;;AMrB7B,0BAA0C;EAAE,OAAO,EN2T1B,GAAO;;AM1ThC,sBAAsC;EAAE,OAAO,ENsM1B,GAAO;;AMrM5B,qBAAqC;EAAE,OAAO,EN6D1B,GAAO;;AM5D3B,yBAAyC;EAAE,OAAO,ENob1B,GAAO;;AMnb/B,yBAAyC;EAAE,OAAO,ENkB1B,GAAO;;AMjB/B,cAA8B;EAAE,OAAO,EN/C1B,GAAO;;AMgDpB,qBAAqC;EAAE,OAAO,EN3D1B,GAAO;;AM4D3B,sBAAsC;EAAE,OAAO,EN3D1B,GAAO;;AM4D5B,mBAAmC;EAAE,OAAO,EN3D1B,GAAO;;AM4DzB,qBAAqC;EAAE,OAAO,EN/D1B,GAAO;;AMgE3B;gBACgC;EAAE,OAAO,ENqV1B,GAAO;;AMpVtB,iBAAiC;EAAE,OAAO,ENuF1B,GAAO;;AMtFvB,mBAAmC;EAAE,OAAO,EN4C1B,GAAO;;AM3CzB,eAA+B;EAAE,OAAO,ENmS1B,GAAO;;AMlSrB,gBAAgC;EAAE,OAAO,ENsP1B,GAAO;;AMrPtB,mBAAmC;EAAE,OAAO,EN9D1B,GAAO;;AM+DzB,6BAA6C;EAAE,OAAO,ENgF1B,GAAO;;AM/EnC,eAA+B;EAAE,OAAO,EN+I1B,GAAO;;AM9IrB,eAA+B;EAAE,OAAO,ENoM1B,GAAO;;AMnMrB,eAA+B;EAAE,OAAO,ENmH1B,GAAO;;AMlHrB,cAA8B;EAAE,OAAO,ENiF1B,GAAO;;AMhFpB,oBAAoC;EAAE,OAAO,ENiF1B,GAAO;;AMhF1B;+BAC+C;EAAE,OAAO,EN0E1B,GAAO;;AMzErC,gBAAgC;EAAE,OAAO,ENmR1B,GAAO;;AMlRtB,mBAAmC;EAAE,OAAO,EN/B1B,GAAO;;AMgCzB,iBAAiC;EAAE,OAAO,ENoS1B,GAAO;;AMnSvB,kBAAkC;EAAE,OAAO,ENwB1B,GAAO;;AMvBxB,iBAAiC;EAAE,OAAO,ENqN1B,GAAO;;AMpNvB,qBAAqC;EAAE,OAAO,ENE1B,GAAO;;AMD3B,uBAAuC;EAAE,OAAO,ENF1B,GAAO;;AMG7B,kBAAkC;EAAE,OAAO,EN2S1B,GAAO;;AM1SxB,wBAAwC;EAAE,OAAO,ENyU1B,GAAO;;AMxU9B,iBAAiC;EAAE,OAAO,EN8G1B,GAAO;;AM7GvB,sBAAsC;EAAE,OAAO,EN+G1B,GAAO;;AM9G5B,mBAAmC;EAAE,OAAO,ENnF1B,GAAO;;AMoFzB,mBAAmC;EAAE,OAAO,ENrF1B,GAAO;;AMsFzB;oBACoC;EAAE,OAAO,EN/E1B,GAAO;;AMgF1B,yBAAyC;EAAE,OAAO,ENua1B,GAAO;;AMta/B,0BAA0C;EAAE,OAAO,ENmE1B,GAAO;;AMlEhC,uBAAuC;EAAE,OAAO,EN5C1B,GAAO;;AM6C7B,cAA8B;EAAE,OAAO,ENqK1B,GAAO;;AMpKpB;eAC+B;EAAE,OAAO,ENK1B,GAAO;;AMJrB,mBAAmC;EAAE,OAAO,ENQ1B,GAAO;;AMPzB,sBAAsC;EAAE,OAAO,ENmY1B,GAAO;;AMlY5B,wBAAwC;EAAE,OAAO,ENiY1B,GAAO;;AMhY9B,oBAAoC;EAAE,OAAO,EN2V1B,GAAO;;AM1V1B,kBAAkC;EAAE,OAAO,ENyI1B,GAAO;;AMxIxB,mBAAmC;EAAE,OAAO,ENyT1B,GAAO;;AMxTzB,0BAA0C;EAAE,OAAO,ENiL1B,GAAO;;AMhLhC,qBAAqC;EAAE,OAAO,EN0X1B,GAAO;;AMzX3B,wBAAwC;EAAE,OAAO,EN8C1B,GAAO;;AM7C9B,kBAAkC;EAAE,OAAO,ENoT1B,GAAO;;AMnTxB,iBAAiC;EAAE,OAAO,EN8Y1B,GAAO;;AM7YvB,wBAAwC;EAAE,OAAO,EN6G1B,GAAO;;AM5G9B,iBAAiC;EAAE,OAAO,EN8Z1B,GAAO;;AM7ZvB,kBAAkC;EAAE,OAAO,EN+J1B,GAAO;;AM9JxB,gBAAgC;EAAE,OAAO,ENsO1B,GAAO;;AMrOtB,mBAAmC;EAAE,OAAO,EN2U1B,GAAO;;AM1UzB,qBAAqC;EAAE,OAAO,EN/E1B,GAAO;;AMgF3B,uBAAuC;EAAE,OAAO,ENoO1B,GAAO;;AMnO7B,kBAAkC;EAAE,OAAO,EN8Y1B,GAAO;;AM7YxB;mBACmC;EAAE,OAAO,ENuC1B,GAAO;;AMtCzB,iBAAiC;EAAE,OAAO,ENiG1B,GAAO;;AMhGvB,iBAAiC;EAAE,OAAO,ENiZ1B,GAAO;;AMhZvB,sBAAsC;EAAE,OAAO,ENR1B,GAAO;;AMS5B,cAA8B;EAAE,OAAO,EN4Q1B,GAAO;;AM3QpB,gBAAgC;EAAE,OAAO,ENgH1B,GAAO;;AM/GtB,mBAAmC;EAAE,OAAO,ENnF1B,GAAO;;AMoFzB,eAA+B;EAAE,OAAO,ENzG1B,GAAO;;AM0GrB,sBAAsC;EAAE,OAAO,ENzD1B,GAAO;;AM0D5B,uBAAuC;EAAE,OAAO,EN0G1B,GAAO;;AMzG7B,sBAAsC;EAAE,OAAO,ENwG1B,GAAO;;AMvG5B,oBAAoC;EAAE,OAAO,ENyG1B,GAAO;;AMxG1B,sBAAsC;EAAE,OAAO,ENqG1B,GAAO;;AMpG5B,4BAA4C;EAAE,OAAO,EN5I1B,GAAO;;AM6IlC,6BAA6C;EAAE,OAAO,ENxI1B,GAAO;;AMyInC,0BAA0C;EAAE,OAAO,ENxI1B,GAAO;;AMyIhC,4BAA4C;EAAE,OAAO,ENhJ1B,GAAO;;AMiJlC,gBAAgC;EAAE,OAAO,ENsF1B,GAAO;;AMrFtB,iBAAiC;EAAE,OAAO,ENia1B,GAAO;;AMhavB,gBAAgC;EAAE,OAAO,ENiV1B,GAAO;;AMhVtB,iBAAiC;EAAE,OAAO,ENgD1B,GAAO;;AM/CvB,oBAAoC;EAAE,OAAO,ENvG1B,GAAO;;AMwG1B,qBAAqC;EAAE,OAAO,ENzI1B,GAAO;;AM0I3B;gBACgC;EAAE,OAAO,ENqY1B,GAAO;;AMpYtB;eAC+B;EAAE,OAAO,ENuI1B,GAAO;;AMtIrB,gBAAgC;EAAE,OAAO,ENpD1B,GAAO;;AMqDtB,gBAAgC;EAAE,OAAO,EN+C1B,GAAO;;AM9CtB;mBACmC;EAAE,OAAO,ENwP1B,GAAO;;AMvPzB;kBACkC;EAAE,OAAO,ENkC1B,GAAO;;AMjCxB,oBAAoC;EAAE,OAAO,ENsL1B,GAAO;;AMrL1B;mBACmC;EAAE,OAAO,EN0C1B,GAAO;;AMzCzB,iBAAiC;EAAE,OAAO,ENiS1B,GAAO;;AMhSvB;;eAE+B;EAAE,OAAO,EN9I1B,GAAO;;AM+IrB,kBAAkC;EAAE,OAAO,ENgI1B,GAAO;;AM/HxB,kBAAkC;EAAE,OAAO,EN8H1B,GAAO;;AM7HxB,wBAAwC;EAAE,OAAO,EN4S1B,GAAO;;AM3S9B,oBAAoC;EAAE,OAAO,ENoW1B,GAAO;;AMnW1B,gBAAgC;EAAE,OAAO,ENmT1B,GAAO;;AMlTtB,gBAAgC;EAAE,OAAO,ENkI1B,GAAO;;AMjItB,gBAAgC;EAAE,OAAO,ENuV1B,GAAO;;AMtVtB,oBAAoC;EAAE,OAAO,ENwL1B,GAAO;;AMvL1B,2BAA2C;EAAE,OAAO,ENyL1B,GAAO;;AMxLjC,6BAA6C;EAAE,OAAO,ENyD1B,GAAO;;AMxDnC,sBAAsC;EAAE,OAAO,ENuD1B,GAAO;;AMtD5B,gBAAgC;EAAE,OAAO,ENsJ1B,GAAO;;AMrJtB,qBAAqC;EAAE,OAAO,ENtH1B,GAAO;;AMuH3B,mBAAmC;EAAE,OAAO,ENhH1B,GAAO;;AMiHzB,qBAAqC;EAAE,OAAO,ENvH1B,GAAO;;AMwH3B,sBAAsC;EAAE,OAAO,ENvH1B,GAAO;;AMwH5B,kBAAkC;EAAE,OAAO,ENvE1B,GAAO;;AMwExB;eAC+B;EAAE,OAAO,EN2P1B,GAAO;;AM1PrB;oBACoC;EAAE,OAAO,EN+P1B,GAAO;;AM9P1B;mBACmC;EAAE,OAAO,EN4P1B,GAAO;;AM3PzB,mBAAmC;EAAE,OAAO,ENxC1B,GAAO;;AMyCzB,mBAAmC;EAAE,OAAO,ENkG1B,GAAO;;AMjGzB;eAC+B;EAAE,OAAO,EN8U1B,GAAO;;AM7UrB;gBACgC;EAAE,OAAO,ENqB1B,GAAO;;AMpBtB;qBACqC;EAAE,OAAO,EN2R1B,GAAO;;AM1R3B,oBAAoC;EAAE,OAAO,ENpF1B,GAAO;;AMqF1B,qBAAqC;EAAE,OAAO,ENnF1B,GAAO;;AMoF3B;eAC+B;EAAE,OAAO,ENjK1B,GAAO;;AMkKrB,kBAAkC;EAAE,OAAO,ENkO1B,GAAO;;AMjOxB,mBAAmC;EAAE,OAAO,ENkU1B,GAAO;;AMjUzB;oBACoC;EAAE,OAAO,EN1G1B,GAAO;;AM2G1B,sBAAsC;EAAE,OAAO,ENgF1B,GAAO;;AM/E5B,mBAAmC;EAAE,OAAO,ENnD1B,GAAO;;AMoDzB,yBAAyC;EAAE,OAAO,ENzG1B,GAAO;;AM0G/B,uBAAuC;EAAE,OAAO,ENzG1B,GAAO;;AM0G7B,kBAAkC;EAAE,OAAO,ENsU1B,GAAO;;AMrUxB,sBAAsC;EAAE,OAAO,EN+P1B,GAAO;;AM9P5B,mBAAmC;EAAE,OAAO,ENsQ1B,GAAO;;AMrQzB,iBAAiC;EAAE,OAAO,ENvL1B,GAAO;;AMwLvB,iBAAiC;EAAE,OAAO,ENzG1B,GAAO;;AM0GvB,kBAAkC;EAAE,OAAO,ENtF1B,GAAO;;AMuFxB,sBAAsC;EAAE,OAAO,EN3B1B,GAAO;;AM4B5B,qBAAqC;EAAE,OAAO,ENxK1B,GAAO;;AMyK3B,qBAAqC;EAAE,OAAO,ENkC1B,GAAO;;AMjC3B,oBAAoC;EAAE,OAAO,EN3O1B,GAAO;;AM4O1B,iBAAiC;EAAE,OAAO,ENiG1B,GAAO;;AMhGvB,sBAAsC;EAAE,OAAO,EN/C1B,GAAO;;AMgD5B,eAA+B;EAAE,OAAO,ENpM1B,GAAO;;AMqMrB,mBAAmC;EAAE,OAAO,ENe1B,GAAO;;AMdzB,sBAAsC;EAAE,OAAO,ENgJ1B,GAAO;;AM/I5B,4BAA4C;EAAE,OAAO,EN5O1B,GAAO;;AM6OlC,6BAA6C;EAAE,OAAO,EN5O1B,GAAO;;AM6OnC,0BAA0C;EAAE,OAAO,EN5O1B,GAAO;;AM6OhC,4BAA4C;EAAE,OAAO,ENhP1B,GAAO;;AMiPlC,qBAAqC;EAAE,OAAO,EN5O1B,GAAO;;AM6O3B,sBAAsC;EAAE,OAAO,EN5O1B,GAAO;;AM6O5B,mBAAmC;EAAE,OAAO,EN5O1B,GAAO;;AM6OzB,qBAAqC;EAAE,OAAO,ENhP1B,GAAO;;AMiP3B,kBAAkC;EAAE,OAAO,ENlG1B,GAAO;;AMmGxB,iBAAiC;EAAE,OAAO,ENuC1B,GAAO;;AMtCvB,iBAAiC;EAAE,OAAO,ENoP1B,GAAO;;AMnPvB;iBACiC;EAAE,OAAO,ENyF1B,GAAO;;AMxFvB,mBAAmC;EAAE,OAAO,EN9I1B,GAAO;;AM+IzB,qBAAqC;EAAE,OAAO,EN0I1B,GAAO;;AMzI3B,sBAAsC;EAAE,OAAO,EN0I1B,GAAO;;AMzI5B,kBAAkC;EAAE,OAAO,ENgN1B,GAAO;;AM/MxB,iBAAiC;EAAE,OAAO,ENnJ1B,GAAO;;AMoJvB;gBACgC;EAAE,OAAO,ENkJ1B,GAAO;;AMjJtB,qBAAqC;EAAE,OAAO,ENnB1B,GAAO;;AMoB3B,mBAAmC;EAAE,OAAO,ENxC1B,GAAO;;AMyCzB,wBAAwC;EAAE,OAAO,ENvC1B,GAAO;;AMwC9B,kBAAkC;EAAE,OAAO,EN0L1B,GAAO;;AMzLxB,kBAAkC;EAAE,OAAO,ENpC1B,GAAO;;AMqCxB,gBAAgC;EAAE,OAAO,ENoE1B,GAAO;;AMnEtB,kBAAkC;EAAE,OAAO,ENpC1B,GAAO;;AMqCxB,qBAAqC;EAAE,OAAO,ENkB1B,GAAO;;AMjB3B,iBAAiC;EAAE,OAAO,ENrD1B,GAAO;;AMsDvB,yBAAyC;EAAE,OAAO,ENvD1B,GAAO;;AMwD/B,mBAAmC;EAAE,OAAO,ENuO1B,GAAO;;AMtOzB,eAA+B;EAAE,OAAO,ENtJ1B,GAAO;;AMuJrB;oBACoC;EAAE,OAAO,ENqI1B,GAAO;;AMpI1B;;sBAEsC;EAAE,OAAO,ENuM1B,GAAO;;AMtM5B,yBAAyC;EAAE,OAAO,ENkC1B,GAAO;;AMjC/B,eAA+B;EAAE,OAAO,EN5I1B,GAAO;;AM6IrB,oBAAoC;EAAE,OAAO,EN7J1B,GAAO;;AM8J1B;uBACuC;EAAE,OAAO,EN1L1B,GAAO;;AM2L7B,mBAAmC;EAAE,OAAO,EN4G1B,GAAO;;AM3GzB,eAA+B;EAAE,OAAO,ENT1B,GAAO;;AMUrB,sBAAsC;EAAE,OAAO,ENhH1B,GAAO;;AMiH5B,sBAAsC;EAAE,OAAO,EN8M1B,GAAO;;AM7M5B,oBAAoC;EAAE,OAAO,ENyM1B,GAAO;;AMxM1B,iBAAiC;EAAE,OAAO,ENvH1B,GAAO;;AMwHvB,uBAAuC;EAAE,OAAO,ENmG1B,GAAO;;AMlG7B,qBAAqC;EAAE,OAAO,EN8C1B,GAAO;;AM7C3B,2BAA2C;EAAE,OAAO,EN8C1B,GAAO;;AM7CjC,iBAAiC;EAAE,OAAO,ENgJ1B,GAAO;;AM/IvB,qBAAqC;EAAE,OAAO,EN5N1B,GAAO;;AM6N3B,4BAA4C;EAAE,OAAO,ENjF1B,GAAO;;AMkFlC,iBAAiC;EAAE,OAAO,ENoH1B,GAAO;;AMnHvB,iBAAiC;EAAE,OAAO,ENkC1B,GAAO;;AMjCvB,8BAA8C;EAAE,OAAO,ENlM1B,GAAO;;AMmMpC,+BAA+C;EAAE,OAAO,ENlM1B,GAAO;;AMmMrC,4BAA4C;EAAE,OAAO,ENlM1B,GAAO;;AMmMlC,8BAA8C;EAAE,OAAO,ENtM1B,GAAO;;AMuMpC,gBAAgC;EAAE,OAAO,EN/B1B,GAAO;;AMgCtB,eAA+B;EAAE,OAAO,ENjK1B,GAAO;;AMkKrB,iBAAiC;EAAE,OAAO,EN9S1B,GAAO;;AM+SvB,qBAAqC;EAAE,OAAO,ENmP1B,GAAO;;AMlP3B,mBAAmC;EAAE,OAAO,EN9O1B,GAAO;;AM+OzB,qBAAqC;EAAE,OAAO,EN/I1B,GAAO;;AMgJ3B,qBAAqC;EAAE,OAAO,EN/I1B,GAAO;;AMgJ3B,qBAAqC;EAAE,OAAO,EN4G1B,GAAO;;AM3G3B,sBAAsC;EAAE,OAAO,ENsE1B,GAAO;;AMrE5B,iBAAiC;EAAE,OAAO,EN2M1B,GAAO;;AM1MvB,uBAAuC;EAAE,OAAO,EN6B1B,GAAO;;AM5B7B,yBAAyC;EAAE,OAAO,EN6B1B,GAAO;;AM5B/B,mBAAmC;EAAE,OAAO,ENhB1B,GAAO;;AMiBzB,qBAAqC;EAAE,OAAO,ENlB1B,GAAO;;AMmB3B,uBAAuC;EAAE,OAAO,ENvN1B,GAAO;;AMwN7B,wBAAwC;EAAE,OAAO,ENiD1B,GAAO;;AMhD9B,+BAA+C;EAAE,OAAO,EN3I1B,GAAO;;AM4IrC,uBAAuC;EAAE,OAAO,ENkH1B,GAAO;;AMjH7B,kBAAkC;EAAE,OAAO,EN1L1B,GAAO;;AM2LxB;8BAC8C;EAAE,OAAO,ENjP1B,GAAO;;AMkPpC;4BAC4C;EAAE,OAAO,ENhP1B,GAAO;;AMiPlC;+BAC+C;EAAE,OAAO,ENnP1B,GAAO;;AMoPrC;cAC8B;EAAE,OAAO,EN7J1B,GAAO;;AM8JpB,cAA8B;EAAE,OAAO,EN/F1B,GAAO;;AMgGpB;cAC8B;EAAE,OAAO,EN4N1B,GAAO;;AM3NpB;cAC8B;EAAE,OAAO,ENvD1B,GAAO;;AMwDpB;;;cAG8B;EAAE,OAAO,ENrD1B,GAAO;;AMsDpB;;cAE8B;EAAE,OAAO,EN8E1B,GAAO;;AM7EpB;cAC8B;EAAE,OAAO,ENtD1B,GAAO;;AMuDpB;cAC8B;EAAE,OAAO,ENzR1B,GAAO;;AM0RpB,eAA+B;EAAE,OAAO,ENzJ1B,GAAO;;AM0JrB,oBAAoC;EAAE,OAAO,EN7I1B,GAAO;;AM8I1B,yBAAyC;EAAE,OAAO,EN2G1B,GAAO;;AM1G/B,0BAA0C;EAAE,OAAO,EN2G1B,GAAO;;AM1GhC,0BAA0C;EAAE,OAAO,EN2G1B,GAAO;;AM1GhC,2BAA2C;EAAE,OAAO,EN2G1B,GAAO;;AM1GjC,2BAA2C;EAAE,OAAO,EN8G1B,GAAO;;AM7GjC,4BAA4C;EAAE,OAAO,EN8G1B,GAAO;;AM7GlC,oBAAoC;EAAE,OAAO,ENgK1B,GAAO;;AM/J1B,sBAAsC;EAAE,OAAO,EN4J1B,GAAO;;AM3J5B,yBAAyC;EAAE,OAAO,ENwO1B,GAAO;;AMvO/B,kBAAkC;EAAE,OAAO,ENqO1B,GAAO;;AMpOxB,eAA+B;EAAE,OAAO,EN+N1B,GAAO;;AM9NrB,sBAAsC;EAAE,OAAO,EN+N1B,GAAO;;AM9N5B,uBAAuC;EAAE,OAAO,ENmO1B,GAAO;;AMlO7B,kBAAkC;EAAE,OAAO,ENxM1B,GAAO;;AMyMxB,yBAAyC;EAAE,OAAO,EN+G1B,GAAO;;AM9G/B,oBAAoC;EAAE,OAAO,ENnF1B,GAAO;;AMoF1B,iBAAiC;EAAE,OAAO,EN/I1B,GAAO;;AMgJvB,cAA8B;EAAE,OAAO,ENhX1B,GAAO;;AMiXpB,oBAAoC;EAAE,OAAO,ENxT1B,GAAO;;AMyT1B,2BAA2C;EAAE,OAAO,ENxT1B,GAAO;;AMyTjC,iBAAiC;EAAE,OAAO,ENyK1B,GAAO;;AMxKvB,wBAAwC;EAAE,OAAO,ENyK1B,GAAO;;AMxK9B,0BAA0C;EAAE,OAAO,ENtD1B,GAAO;;AMuDhC,wBAAwC;EAAE,OAAO,ENpD1B,GAAO;;AMqD9B,0BAA0C;EAAE,OAAO,ENvD1B,GAAO;;AMwDhC,2BAA2C;EAAE,OAAO,ENvD1B,GAAO;;AMwDjC,gBAAgC;EAAE,OAAO,ENxW1B,GAAO;;AMyWtB,kBAAkC;EAAE,OAAO,EN0M1B,GAAO;;AMzMxB,kBAAkC;EAAE,OAAO,ENpX1B,GAAO;;AMqXxB,gBAAgC;EAAE,OAAO,ENpE1B,GAAO;;AMqEtB,mBAAmC;EAAE,OAAO,EN1N1B,GAAO;;AM2NzB,gBAAgC;EAAE,OAAO,ENqE1B,GAAO;;AMpEtB,qBAAqC;EAAE,OAAO,ENtJ1B,GAAO;;AMuJ3B,iBAAiC;EAAE,OAAO,ENuJ1B,GAAO;;AMtJvB,iBAAiC;EAAE,OAAO,EN/L1B,GAAO;;AMgMvB,eAA+B;EAAE,OAAO,EN1D1B,GAAO;;AM2DrB;mBACmC;EAAE,OAAO,ENnI1B,GAAO;;AMoIzB,gBAAgC;EAAE,OAAO,EN2G1B,GAAO;;AM1GtB,iBAAiC;EAAE,OAAO,ENxC1B,GAAO;;AMyCvB,kBAAkC;EAAE,OAAO,ENrX1B,GAAO;;AMsXxB,cAA8B;EAAE,OAAO,ENpU1B,GAAO;;AMqUpB,aAA6B;EAAE,OAAO,ENgL1B,GAAO;;AM/KnB,gBAAgC;EAAE,OAAO,ENqL1B,GAAO;;AMpLtB,iBAAiC;EAAE,OAAO,ENa1B,GAAO;;AMZvB,oBAAoC;EAAE,OAAO,ENrC1B,GAAO;;AMsC1B,yBAAyC;EAAE,OAAO,EN8E1B,GAAO;;AM7E/B,+BAA+C;EAAE,OAAO,ENtX1B,GAAO;;AMuXrC,8BAA8C;EAAE,OAAO,ENxX1B,GAAO;;AMyXpC;8BAC8C;EAAE,OAAO,EN3T1B,GAAO;;AM4TpC,uBAAuC;EAAE,OAAO,ENjP1B,GAAO;;AMkP7B,qBAAqC;EAAE,OAAO,EN+K1B,GAAO;;AM9K3B,uBAAuC;EAAE,OAAO,ENmK1B,GAAO;;AMlK7B;cAC8B;EAAE,OAAO,ENoI1B,GAAO;;AMnIpB,wBAAwC;EAAE,OAAO,ENjB1B,GAAO;;AMkB9B,wBAAwC;EAAE,OAAO,EN6D1B,GAAO;;AM5D9B,gBAAgC;EAAE,OAAO,EN2C1B,GAAO;;AM1CtB,0BAA0C;EAAE,OAAO,EN7O1B,GAAO;;AM8OhC,oBAAoC;EAAE,OAAO,EN2K1B,GAAO;;AM1K1B,iBAAiC;EAAE,OAAO,ENvD1B,GAAO;;AMwDvB;;qBAEqC;EAAE,OAAO,ENsI1B,GAAO;;AMrI3B;yBACyC;EAAE,OAAO,ENjK1B,GAAO;;AMkK/B,gBAAgC;EAAE,OAAO,ENwK1B,GAAO;;AMvKtB,iBAAiC;EAAE,OAAO,ENvK1B,GAAO;;AMwKvB,iBAAiC;EAAE,OAAO,ENhB1B,GAAO;;AMiBvB,wBAAwC;EAAE,OAAO,ENhB1B,GAAO;;AMiB9B,6BAA6C;EAAE,OAAO,ENsE1B,GAAO;;AMrEnC,sBAAsC;EAAE,OAAO,ENoE1B,GAAO;;AMnE5B,oBAAoC;EAAE,OAAO,EN7Q1B,GAAO;;AM8Q1B,eAA+B;EAAE,OAAO,EN1Q1B,GAAO;;AM2QrB,qBAAqC;EAAE,OAAO,ENjD1B,GAAO;;AMkD3B,yBAAyC;EAAE,OAAO,ENjD1B,GAAO;;AMkD/B,iBAAiC;EAAE,OAAO,ENvQ1B,GAAO;;AMwQvB,iBAAiC;EAAE,OAAO,EN9I1B,GAAO;;AM+IvB,mBAAmC;EAAE,OAAO,ENzI1B,GAAO;;AM0IzB,cAA8B;EAAE,OAAO,EN9O1B,GAAO;;AM+OpB,mBAAmC;EAAE,OAAO,EN3W1B,GAAO;;AM4WzB,gBAAgC;EAAE,OAAO,EN9T1B,GAAO;;AM+TtB,cAA8B;EAAE,OAAO,ENnE1B,GAAO;;AMoEpB,gBAAgC;EAAE,OAAO,ENoC1B,GAAO;;AMnCtB,eAA+B;EAAE,OAAO,ENjS1B,GAAO;;AMkSrB,gBAAgC;EAAE,OAAO,ENjS1B,GAAO;;AMkStB,kBAAkC;EAAE,OAAO,ENtY1B,GAAO;;AMuYxB,yBAAyC;EAAE,OAAO,ENtY1B,GAAO;;AMuY/B,gBAAgC;EAAE,OAAO,EN2C1B,GAAO;;AM1CtB,uBAAuC;EAAE,OAAO,EN2C1B,GAAO;;AM1C7B,kBAAkC;EAAE,OAAO,ENvC1B,GAAO;;AMwCxB;cAC8B;EAAE,OAAO,EN3W1B,GAAO;;AM4WpB;eAC+B;EAAE,OAAO,EN2D1B,GAAO;;AM1DrB,eAA+B;EAAE,OAAO,ENuF1B,GAAO;;AMtFrB,kBAAkC;EAAE,OAAO,ENwB1B,GAAO;;AMvBxB,qBAAqC;EAAE,OAAO,ENpS1B,GAAO;;AMqS3B,qBAAqC;EAAE,OAAO,ENkB1B,GAAO;;AMjB3B,mBAAmC;EAAE,OAAO,EN1S1B,GAAO;;AM2SzB,qBAAqC;EAAE,OAAO,ENxP1B,GAAO;;AMyP3B,sBAAsC;EAAE,OAAO,ENjP1B,GAAO;;AMkP5B,uBAAuC;EAAE,OAAO,EN9P1B,GAAO;;AM+P7B,4BAA4C;EAAE,OAAO,ENxP1B,GAAO;;AMyPlC;;uBAEuC;EAAE,OAAO,ENjQ1B,GAAO;;AMkQ7B;yBACyC;EAAE,OAAO,ENvQ1B,GAAO;;AMwQ/B;uBACuC;EAAE,OAAO,ENxQ1B,GAAO;;AMyQ7B;uBACuC;EAAE,OAAO,EN7P1B,GAAO;;AM8P7B,sBAAsC;EAAE,OAAO,EN1Q1B,GAAO;;AM2Q5B,eAA+B;EAAE,OAAO,ENsG1B,GAAO;;AMrGrB,kBAAkC;EAAE,OAAO,ENlV1B,GAAO;;AMmVxB,mBAAmC;EAAE,OAAO,ENnL1B,GAAO;;AMoLzB;;;;oBAIoC;EAAE,OAAO,ENxK1B,GAAO;;AMyK1B,yBAAyC;EAAE,OAAO,ENpW1B,GAAO;;AMqW/B;gBACgC;EAAE,OAAO,EN1E1B,GAAO;;AM2EtB;iBACiC;EAAE,OAAO,ENpT1B,GAAO;;AMqTvB,qBAAqC;EAAE,OAAO,EN1O1B,GAAO;;AM2O3B,cAA8B;EAAE,OAAO,EN5O1B,GAAO;;AM6OpB,sBAAsC;EAAE,OAAO,EN7N1B,GAAO;;AM8N5B,wBAAwC;EAAE,OAAO,ENwB1B,GAAO;;AMvB9B,aAA6B;EAAE,OAAO,ENzF1B,GAAO;;AM0FnB;iBACiC;EAAE,OAAO,EN2F1B,GAAO;;AM1FvB;sBACsC;EAAE,OAAO,EN9H1B,GAAO;;AM+H5B;wBACwC;EAAE,OAAO,EN/H1B,GAAO;;AMgI9B,kBAAkC;EAAE,OAAO,EN3N1B,GAAO;;AM4NxB;sBACsC;EAAE,OAAO,ENrX1B,GAAO;;AMsX5B,iBAAiC;EAAE,OAAO,ENnO1B,GAAO;;AMoOvB,oBAAoC;EAAE,OAAO,ENlI1B,GAAO;;AMmI1B,kBAAkC;EAAE,OAAO,EN1C1B,GAAO;;AM2CxB,oBAAoC;EAAE,OAAO,EN7D1B,GAAO;;AM8D1B,2BAA2C;EAAE,OAAO,EN7D1B,GAAO;;AM8DjC,eAA+B;EAAE,OAAO,ENpb1B,GAAO;;AMqbrB;mBACmC;EAAE,OAAO,ENzQ1B,GAAO;;AM0QzB,cAA8B;EAAE,OAAO,ENsC1B,GAAO;;AMrCpB,qBAAqC;EAAE,OAAO,EN/b1B,GAAO;;AMgc3B,eAA+B;EAAE,OAAO,ENrH1B,GAAO;;AMsHrB,qBAAqC;EAAE,OAAO,ENlD1B,GAAO;;AMmD3B,iBAAiC;EAAE,OAAO,ENsC1B,GAAO;;AMrCvB,eAA+B;EAAE,OAAO,ENiF1B,GAAO;;AMhFrB,sBAAsC;EAAE,OAAO,ENvJ1B,GAAO;;AMwJ5B,eAA+B;EAAE,OAAO,ENuE1B,GAAO;;AMtErB,qBAAqC;EAAE,OAAO,ENjb1B,GAAO;;AMkb3B,iBAAiC;EAAE,OAAO,EN9I1B,GAAO;;AM+IvB,wBAAwC;EAAE,OAAO,ENhQ1B,GAAO;;AMiQ9B,kBAAkC;EAAE,OAAO,EN9Z1B,GAAO;;AM+ZxB,wBAAwC;EAAE,OAAO,ENla1B,GAAO;;AMma9B,sBAAsC;EAAE,OAAO,ENpa1B,GAAO;;AMqa5B,kBAAkC;EAAE,OAAO,ENta1B,GAAO;;AMuaxB,oBAAoC;EAAE,OAAO,ENpa1B,GAAO;;AMqa1B,oBAAoC;EAAE,OAAO,ENpa1B,GAAO;;AMqa1B,qBAAqC;EAAE,OAAO,ENld1B,GAAO;;AMmd3B,uBAAuC;EAAE,OAAO,ENld1B,GAAO;;AMmd7B,gBAAgC;EAAE,OAAO,ENY1B,GAAO;;AMXtB,oBAAoC;EAAE,OAAO,EN3X1B,GAAO;;AM4X1B,aAA6B;EAAE,OAAO,ENre1B,GAAO;;AMsenB,qBAAqC;EAAE,OAAO,ENjV1B,GAAO;;AMkV3B,sBAAsC;EAAE,OAAO,ENpK1B,GAAO;;AMqK5B,wBAAwC;EAAE,OAAO,ENrd1B,GAAO;;AMsd9B,qBAAqC;EAAE,OAAO,EN3f1B,GAAO;;AM4f3B,oBAAoC;EAAE,OAAO,ENvJ1B,GAAO;;AMwJ1B,qBAAqC;EAAE,OAAO,EN5N1B,GAAO;;AM6N3B,iBAAiC;EAAE,OAAO,EN1O1B,GAAO;;AM2OvB,wBAAwC;EAAE,OAAO,EN1O1B,GAAO;;AM2O9B,qBAAqC;EAAE,OAAO,ENN1B,GAAO;;AMO3B,oBAAoC;EAAE,OAAO,ENN1B,GAAO;;AMO1B,kBAAkC;EAAE,OAAO,EN/d1B,GAAO;;AMgexB,cAA8B;EAAE,OAAO,EN7c1B,GAAO;;AM8cpB,kBAAkC;EAAE,OAAO,EN1P1B,GAAO;;AM2PxB,oBAAoC;EAAE,OAAO,ENhhB1B,GAAO;;AMihB1B,aAA6B;EAAE,OAAO,EN7b1B,GAAO;;AM8bnB;;cAE8B;EAAE,OAAO,ENxQ1B,GAAO;;AMyQpB,mBAAmC;EAAE,OAAO,EN7M1B,GAAO;;AM8MzB,qBAAqC;EAAE,OAAO,ENpd1B,GAAO;;AMqd3B,yBAAyC;EAAE,OAAO,ENnZ1B,GAAO;;AMoZ/B,mBAAmC;EAAE,OAAO,ENxY1B,GAAO;;AMyYzB,mBAAmC;EAAE,OAAO,EN1T1B,GAAO;;AM2TzB,kBAAkC;EAAE,OAAO,ENxP1B,GAAO;;AMyPxB,iBAAiC;EAAE,OAAO,ENrH1B,GAAO;;AMsHvB,uBAAuC;EAAE,OAAO,ENzG1B,GAAO;;AM0G7B,sBAAsC;EAAE,OAAO,ENrG1B,GAAO;;AMsG5B,mBAAmC;EAAE,OAAO,ENpG1B,GAAO;;AMqGzB,oBAAoC;EAAE,OAAO,EN5c1B,GAAO;;AM6c1B,0BAA0C;EAAE,OAAO,EN9c1B,GAAO;;AM+chC,kBAAkC;EAAE,OAAO,EN3Y1B,GAAO;;AM4YxB,eAA+B;EAAE,OAAO,ENhH1B,GAAO;;AMiHrB,sBAAsC;EAAE,OAAO,ENI1B,GAAO;;AMH5B,qBAAqC;EAAE,OAAO,EN5M1B,GAAO;;AM6M3B,sBAAsC;EAAE,OAAO,ENpE1B,GAAO;;AMqE5B,oBAAoC;EAAE,OAAO,ENhS1B,GAAO;;AMiS1B,gBAAgC;EAAE,OAAO,ENG1B,GAAO;;AMFtB,eAA+B;EAAE,OAAO,ENtO1B,GAAO;;AMuOrB,kBAAkC;EAAE,OAAO,EN7N1B,GAAO;;AM8NxB,sBAAsC;EAAE,OAAO,ENhC1B,GAAO;;AMiC5B,0BAA0C;EAAE,OAAO,ENhC1B,GAAO;;AMiChC,uBAAuC;EAAE,OAAO,END1B,GAAO;;AME7B,sBAAsC;EAAE,OAAO,EN1O1B,GAAO;;AM2O5B,qBAAqC;EAAE,OAAO,ENF1B,GAAO;;AMG3B,sBAAsC;EAAE,OAAO,EN3O1B,GAAO;;AM4O5B,wBAAwC;EAAE,OAAO,EN1O1B,GAAO;;AM2O9B,wBAAwC;EAAE,OAAO,EN5O1B,GAAO;;AM6O9B,iBAAiC;EAAE,OAAO,ENvN1B,GAAO;;AMwNvB,4BAA4C;EAAE,OAAO,EN9X1B,GAAO;;AM+XlC,sBAAsC;EAAE,OAAO,ENhM1B,GAAO;;AMiM5B,mBAAmC;EAAE,OAAO,ENI1B,GAAO;;AMHzB,iBAAiC;EAAE,OAAO,EN7I1B,GAAO;;AM8IvB,oBAAoC;EAAE,OAAO,ENjB1B,GAAO;;AMkB1B,qBAAqC;EAAE,OAAO,ENhB1B,GAAO;;AMiB3B;cAC8B;EAAE,OAAO,ENphB1B,GAAO;;AMqhBpB,kBAAkC;EAAE,OAAO,ENd1B,GAAO;;AMexB,gBAAgC;EAAE,OAAO,ENnD1B,GAAO;;AMoDtB,iBAAiC;EAAE,OAAO,ENvF1B,GAAO;;AMwFvB,iBAAiC;EAAE,OAAO,ENrP1B,GAAO",
+"sources": ["../scss/_path.scss","../scss/_core.scss","../scss/_larger.scss","../scss/_fixed-width.scss","../scss/_list.scss","../scss/_variables.scss","../scss/_bordered-pulled.scss","../scss/_animated.scss","../scss/_rotated-flipped.scss","../scss/_mixins.scss","../scss/_stacked.scss","../scss/_icons.scss"],
+"names": [],
+"file": "font-awesome.css"
+}
diff --git a/membership/static/font-awesome/css/font-awesome.min.css b/membership/static/font-awesome/css/font-awesome.min.css
new file mode 100755
index 0000000..885b384
--- /dev/null
+++ b/membership/static/font-awesome/css/font-awesome.min.css
@@ -0,0 +1,4 @@
+/*!
+ * Font Awesome 4.6.1 by @davegandy - http://fontawesome.io - @fontawesome
+ * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.6.1');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.6.1') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.6.1') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.6.1') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.6.1') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.6.1#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}
diff --git a/membership/static/font-awesome/fonts/4.4.0/index.html b/membership/static/font-awesome/fonts/4.4.0/index.html
new file mode 100755
index 0000000..dcb5932
--- /dev/null
+++ b/membership/static/font-awesome/fonts/4.4.0/index.html
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+ 4.4.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/membership/static/font-awesome/fonts/FontAwesome.otf b/membership/static/font-awesome/fonts/FontAwesome.otf
new file mode 100755
index 0000000..59853bc
Binary files /dev/null and b/membership/static/font-awesome/fonts/FontAwesome.otf differ
diff --git a/membership/static/font-awesome/fonts/fontawesome-webfont.eot b/membership/static/font-awesome/fonts/fontawesome-webfont.eot
new file mode 100755
index 0000000..96f92f9
Binary files /dev/null and b/membership/static/font-awesome/fonts/fontawesome-webfont.eot differ
diff --git a/membership/static/font-awesome/fonts/fontawesome-webfont.svg b/membership/static/font-awesome/fonts/fontawesome-webfont.svg
new file mode 100755
index 0000000..5a5f0ec
--- /dev/null
+++ b/membership/static/font-awesome/fonts/fontawesome-webfont.svg
@@ -0,0 +1,685 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/membership/static/font-awesome/fonts/fontawesome-webfont.ttf b/membership/static/font-awesome/fonts/fontawesome-webfont.ttf
new file mode 100755
index 0000000..86784df
Binary files /dev/null and b/membership/static/font-awesome/fonts/fontawesome-webfont.ttf differ
diff --git a/membership/static/font-awesome/fonts/fontawesome-webfont.woff b/membership/static/font-awesome/fonts/fontawesome-webfont.woff
new file mode 100755
index 0000000..c7faa19
Binary files /dev/null and b/membership/static/font-awesome/fonts/fontawesome-webfont.woff differ
diff --git a/membership/static/font-awesome/fonts/fontawesome-webfont.woff2 b/membership/static/font-awesome/fonts/fontawesome-webfont.woff2
new file mode 100755
index 0000000..cab8571
Binary files /dev/null and b/membership/static/font-awesome/fonts/fontawesome-webfont.woff2 differ
diff --git a/membership/static/font-awesome/less/animated.less b/membership/static/font-awesome/less/animated.less
new file mode 100755
index 0000000..66ad52a
--- /dev/null
+++ b/membership/static/font-awesome/less/animated.less
@@ -0,0 +1,34 @@
+// Animated Icons
+// --------------------------
+
+.@{fa-css-prefix}-spin {
+ -webkit-animation: fa-spin 2s infinite linear;
+ animation: fa-spin 2s infinite linear;
+}
+
+.@{fa-css-prefix}-pulse {
+ -webkit-animation: fa-spin 1s infinite steps(8);
+ animation: fa-spin 1s infinite steps(8);
+}
+
+@-webkit-keyframes fa-spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+}
+
+@keyframes fa-spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+}
diff --git a/membership/static/font-awesome/less/bordered-pulled.less b/membership/static/font-awesome/less/bordered-pulled.less
new file mode 100755
index 0000000..f1c8ad7
--- /dev/null
+++ b/membership/static/font-awesome/less/bordered-pulled.less
@@ -0,0 +1,25 @@
+// Bordered & Pulled
+// -------------------------
+
+.@{fa-css-prefix}-border {
+ padding: .2em .25em .15em;
+ border: solid .08em @fa-border-color;
+ border-radius: .1em;
+}
+
+.@{fa-css-prefix}-pull-left { float: left; }
+.@{fa-css-prefix}-pull-right { float: right; }
+
+.@{fa-css-prefix} {
+ &.@{fa-css-prefix}-pull-left { margin-right: .3em; }
+ &.@{fa-css-prefix}-pull-right { margin-left: .3em; }
+}
+
+/* Deprecated as of 4.4.0 */
+.pull-right { float: right; }
+.pull-left { float: left; }
+
+.@{fa-css-prefix} {
+ &.pull-left { margin-right: .3em; }
+ &.pull-right { margin-left: .3em; }
+}
diff --git a/membership/static/font-awesome/less/core.less b/membership/static/font-awesome/less/core.less
new file mode 100755
index 0000000..c577ac8
--- /dev/null
+++ b/membership/static/font-awesome/less/core.less
@@ -0,0 +1,12 @@
+// Base Class Definition
+// -------------------------
+
+.@{fa-css-prefix} {
+ display: inline-block;
+ font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
+ font-size: inherit; // can't have font-size inherit on line above, so need to override
+ text-rendering: auto; // optimizelegibility throws things off #1094
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+
+}
diff --git a/membership/static/font-awesome/less/fixed-width.less b/membership/static/font-awesome/less/fixed-width.less
new file mode 100755
index 0000000..110289f
--- /dev/null
+++ b/membership/static/font-awesome/less/fixed-width.less
@@ -0,0 +1,6 @@
+// Fixed Width Icons
+// -------------------------
+.@{fa-css-prefix}-fw {
+ width: (18em / 14);
+ text-align: center;
+}
diff --git a/membership/static/font-awesome/less/font-awesome.less b/membership/static/font-awesome/less/font-awesome.less
new file mode 100755
index 0000000..7670960
--- /dev/null
+++ b/membership/static/font-awesome/less/font-awesome.less
@@ -0,0 +1,18 @@
+/*!
+ * Font Awesome 4.6.1 by @davegandy - http://fontawesome.io - @fontawesome
+ * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+
+@import "variables.less";
+@import "mixins.less";
+@import "path.less";
+@import "core.less";
+@import "larger.less";
+@import "fixed-width.less";
+@import "list.less";
+@import "bordered-pulled.less";
+@import "animated.less";
+@import "rotated-flipped.less";
+@import "stacked.less";
+@import "icons.less";
+@import "screen-reader.less";
diff --git a/membership/static/font-awesome/less/icons.less b/membership/static/font-awesome/less/icons.less
new file mode 100755
index 0000000..c5e6430
--- /dev/null
+++ b/membership/static/font-awesome/less/icons.less
@@ -0,0 +1,724 @@
+/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+ readers do not read off random characters that represent icons */
+
+.@{fa-css-prefix}-glass:before { content: @fa-var-glass; }
+.@{fa-css-prefix}-music:before { content: @fa-var-music; }
+.@{fa-css-prefix}-search:before { content: @fa-var-search; }
+.@{fa-css-prefix}-envelope-o:before { content: @fa-var-envelope-o; }
+.@{fa-css-prefix}-heart:before { content: @fa-var-heart; }
+.@{fa-css-prefix}-star:before { content: @fa-var-star; }
+.@{fa-css-prefix}-star-o:before { content: @fa-var-star-o; }
+.@{fa-css-prefix}-user:before { content: @fa-var-user; }
+.@{fa-css-prefix}-film:before { content: @fa-var-film; }
+.@{fa-css-prefix}-th-large:before { content: @fa-var-th-large; }
+.@{fa-css-prefix}-th:before { content: @fa-var-th; }
+.@{fa-css-prefix}-th-list:before { content: @fa-var-th-list; }
+.@{fa-css-prefix}-check:before { content: @fa-var-check; }
+.@{fa-css-prefix}-remove:before,
+.@{fa-css-prefix}-close:before,
+.@{fa-css-prefix}-times:before { content: @fa-var-times; }
+.@{fa-css-prefix}-search-plus:before { content: @fa-var-search-plus; }
+.@{fa-css-prefix}-search-minus:before { content: @fa-var-search-minus; }
+.@{fa-css-prefix}-power-off:before { content: @fa-var-power-off; }
+.@{fa-css-prefix}-signal:before { content: @fa-var-signal; }
+.@{fa-css-prefix}-gear:before,
+.@{fa-css-prefix}-cog:before { content: @fa-var-cog; }
+.@{fa-css-prefix}-trash-o:before { content: @fa-var-trash-o; }
+.@{fa-css-prefix}-home:before { content: @fa-var-home; }
+.@{fa-css-prefix}-file-o:before { content: @fa-var-file-o; }
+.@{fa-css-prefix}-clock-o:before { content: @fa-var-clock-o; }
+.@{fa-css-prefix}-road:before { content: @fa-var-road; }
+.@{fa-css-prefix}-download:before { content: @fa-var-download; }
+.@{fa-css-prefix}-arrow-circle-o-down:before { content: @fa-var-arrow-circle-o-down; }
+.@{fa-css-prefix}-arrow-circle-o-up:before { content: @fa-var-arrow-circle-o-up; }
+.@{fa-css-prefix}-inbox:before { content: @fa-var-inbox; }
+.@{fa-css-prefix}-play-circle-o:before { content: @fa-var-play-circle-o; }
+.@{fa-css-prefix}-rotate-right:before,
+.@{fa-css-prefix}-repeat:before { content: @fa-var-repeat; }
+.@{fa-css-prefix}-refresh:before { content: @fa-var-refresh; }
+.@{fa-css-prefix}-list-alt:before { content: @fa-var-list-alt; }
+.@{fa-css-prefix}-lock:before { content: @fa-var-lock; }
+.@{fa-css-prefix}-flag:before { content: @fa-var-flag; }
+.@{fa-css-prefix}-headphones:before { content: @fa-var-headphones; }
+.@{fa-css-prefix}-volume-off:before { content: @fa-var-volume-off; }
+.@{fa-css-prefix}-volume-down:before { content: @fa-var-volume-down; }
+.@{fa-css-prefix}-volume-up:before { content: @fa-var-volume-up; }
+.@{fa-css-prefix}-qrcode:before { content: @fa-var-qrcode; }
+.@{fa-css-prefix}-barcode:before { content: @fa-var-barcode; }
+.@{fa-css-prefix}-tag:before { content: @fa-var-tag; }
+.@{fa-css-prefix}-tags:before { content: @fa-var-tags; }
+.@{fa-css-prefix}-book:before { content: @fa-var-book; }
+.@{fa-css-prefix}-bookmark:before { content: @fa-var-bookmark; }
+.@{fa-css-prefix}-print:before { content: @fa-var-print; }
+.@{fa-css-prefix}-camera:before { content: @fa-var-camera; }
+.@{fa-css-prefix}-font:before { content: @fa-var-font; }
+.@{fa-css-prefix}-bold:before { content: @fa-var-bold; }
+.@{fa-css-prefix}-italic:before { content: @fa-var-italic; }
+.@{fa-css-prefix}-text-height:before { content: @fa-var-text-height; }
+.@{fa-css-prefix}-text-width:before { content: @fa-var-text-width; }
+.@{fa-css-prefix}-align-left:before { content: @fa-var-align-left; }
+.@{fa-css-prefix}-align-center:before { content: @fa-var-align-center; }
+.@{fa-css-prefix}-align-right:before { content: @fa-var-align-right; }
+.@{fa-css-prefix}-align-justify:before { content: @fa-var-align-justify; }
+.@{fa-css-prefix}-list:before { content: @fa-var-list; }
+.@{fa-css-prefix}-dedent:before,
+.@{fa-css-prefix}-outdent:before { content: @fa-var-outdent; }
+.@{fa-css-prefix}-indent:before { content: @fa-var-indent; }
+.@{fa-css-prefix}-video-camera:before { content: @fa-var-video-camera; }
+.@{fa-css-prefix}-photo:before,
+.@{fa-css-prefix}-image:before,
+.@{fa-css-prefix}-picture-o:before { content: @fa-var-picture-o; }
+.@{fa-css-prefix}-pencil:before { content: @fa-var-pencil; }
+.@{fa-css-prefix}-map-marker:before { content: @fa-var-map-marker; }
+.@{fa-css-prefix}-adjust:before { content: @fa-var-adjust; }
+.@{fa-css-prefix}-tint:before { content: @fa-var-tint; }
+.@{fa-css-prefix}-edit:before,
+.@{fa-css-prefix}-pencil-square-o:before { content: @fa-var-pencil-square-o; }
+.@{fa-css-prefix}-share-square-o:before { content: @fa-var-share-square-o; }
+.@{fa-css-prefix}-check-square-o:before { content: @fa-var-check-square-o; }
+.@{fa-css-prefix}-arrows:before { content: @fa-var-arrows; }
+.@{fa-css-prefix}-step-backward:before { content: @fa-var-step-backward; }
+.@{fa-css-prefix}-fast-backward:before { content: @fa-var-fast-backward; }
+.@{fa-css-prefix}-backward:before { content: @fa-var-backward; }
+.@{fa-css-prefix}-play:before { content: @fa-var-play; }
+.@{fa-css-prefix}-pause:before { content: @fa-var-pause; }
+.@{fa-css-prefix}-stop:before { content: @fa-var-stop; }
+.@{fa-css-prefix}-forward:before { content: @fa-var-forward; }
+.@{fa-css-prefix}-fast-forward:before { content: @fa-var-fast-forward; }
+.@{fa-css-prefix}-step-forward:before { content: @fa-var-step-forward; }
+.@{fa-css-prefix}-eject:before { content: @fa-var-eject; }
+.@{fa-css-prefix}-chevron-left:before { content: @fa-var-chevron-left; }
+.@{fa-css-prefix}-chevron-right:before { content: @fa-var-chevron-right; }
+.@{fa-css-prefix}-plus-circle:before { content: @fa-var-plus-circle; }
+.@{fa-css-prefix}-minus-circle:before { content: @fa-var-minus-circle; }
+.@{fa-css-prefix}-times-circle:before { content: @fa-var-times-circle; }
+.@{fa-css-prefix}-check-circle:before { content: @fa-var-check-circle; }
+.@{fa-css-prefix}-question-circle:before { content: @fa-var-question-circle; }
+.@{fa-css-prefix}-info-circle:before { content: @fa-var-info-circle; }
+.@{fa-css-prefix}-crosshairs:before { content: @fa-var-crosshairs; }
+.@{fa-css-prefix}-times-circle-o:before { content: @fa-var-times-circle-o; }
+.@{fa-css-prefix}-check-circle-o:before { content: @fa-var-check-circle-o; }
+.@{fa-css-prefix}-ban:before { content: @fa-var-ban; }
+.@{fa-css-prefix}-arrow-left:before { content: @fa-var-arrow-left; }
+.@{fa-css-prefix}-arrow-right:before { content: @fa-var-arrow-right; }
+.@{fa-css-prefix}-arrow-up:before { content: @fa-var-arrow-up; }
+.@{fa-css-prefix}-arrow-down:before { content: @fa-var-arrow-down; }
+.@{fa-css-prefix}-mail-forward:before,
+.@{fa-css-prefix}-share:before { content: @fa-var-share; }
+.@{fa-css-prefix}-expand:before { content: @fa-var-expand; }
+.@{fa-css-prefix}-compress:before { content: @fa-var-compress; }
+.@{fa-css-prefix}-plus:before { content: @fa-var-plus; }
+.@{fa-css-prefix}-minus:before { content: @fa-var-minus; }
+.@{fa-css-prefix}-asterisk:before { content: @fa-var-asterisk; }
+.@{fa-css-prefix}-exclamation-circle:before { content: @fa-var-exclamation-circle; }
+.@{fa-css-prefix}-gift:before { content: @fa-var-gift; }
+.@{fa-css-prefix}-leaf:before { content: @fa-var-leaf; }
+.@{fa-css-prefix}-fire:before { content: @fa-var-fire; }
+.@{fa-css-prefix}-eye:before { content: @fa-var-eye; }
+.@{fa-css-prefix}-eye-slash:before { content: @fa-var-eye-slash; }
+.@{fa-css-prefix}-warning:before,
+.@{fa-css-prefix}-exclamation-triangle:before { content: @fa-var-exclamation-triangle; }
+.@{fa-css-prefix}-plane:before { content: @fa-var-plane; }
+.@{fa-css-prefix}-calendar:before { content: @fa-var-calendar; }
+.@{fa-css-prefix}-random:before { content: @fa-var-random; }
+.@{fa-css-prefix}-comment:before { content: @fa-var-comment; }
+.@{fa-css-prefix}-magnet:before { content: @fa-var-magnet; }
+.@{fa-css-prefix}-chevron-up:before { content: @fa-var-chevron-up; }
+.@{fa-css-prefix}-chevron-down:before { content: @fa-var-chevron-down; }
+.@{fa-css-prefix}-retweet:before { content: @fa-var-retweet; }
+.@{fa-css-prefix}-shopping-cart:before { content: @fa-var-shopping-cart; }
+.@{fa-css-prefix}-folder:before { content: @fa-var-folder; }
+.@{fa-css-prefix}-folder-open:before { content: @fa-var-folder-open; }
+.@{fa-css-prefix}-arrows-v:before { content: @fa-var-arrows-v; }
+.@{fa-css-prefix}-arrows-h:before { content: @fa-var-arrows-h; }
+.@{fa-css-prefix}-bar-chart-o:before,
+.@{fa-css-prefix}-bar-chart:before { content: @fa-var-bar-chart; }
+.@{fa-css-prefix}-twitter-square:before { content: @fa-var-twitter-square; }
+.@{fa-css-prefix}-facebook-square:before { content: @fa-var-facebook-square; }
+.@{fa-css-prefix}-camera-retro:before { content: @fa-var-camera-retro; }
+.@{fa-css-prefix}-key:before { content: @fa-var-key; }
+.@{fa-css-prefix}-gears:before,
+.@{fa-css-prefix}-cogs:before { content: @fa-var-cogs; }
+.@{fa-css-prefix}-comments:before { content: @fa-var-comments; }
+.@{fa-css-prefix}-thumbs-o-up:before { content: @fa-var-thumbs-o-up; }
+.@{fa-css-prefix}-thumbs-o-down:before { content: @fa-var-thumbs-o-down; }
+.@{fa-css-prefix}-star-half:before { content: @fa-var-star-half; }
+.@{fa-css-prefix}-heart-o:before { content: @fa-var-heart-o; }
+.@{fa-css-prefix}-sign-out:before { content: @fa-var-sign-out; }
+.@{fa-css-prefix}-linkedin-square:before { content: @fa-var-linkedin-square; }
+.@{fa-css-prefix}-thumb-tack:before { content: @fa-var-thumb-tack; }
+.@{fa-css-prefix}-external-link:before { content: @fa-var-external-link; }
+.@{fa-css-prefix}-sign-in:before { content: @fa-var-sign-in; }
+.@{fa-css-prefix}-trophy:before { content: @fa-var-trophy; }
+.@{fa-css-prefix}-github-square:before { content: @fa-var-github-square; }
+.@{fa-css-prefix}-upload:before { content: @fa-var-upload; }
+.@{fa-css-prefix}-lemon-o:before { content: @fa-var-lemon-o; }
+.@{fa-css-prefix}-phone:before { content: @fa-var-phone; }
+.@{fa-css-prefix}-square-o:before { content: @fa-var-square-o; }
+.@{fa-css-prefix}-bookmark-o:before { content: @fa-var-bookmark-o; }
+.@{fa-css-prefix}-phone-square:before { content: @fa-var-phone-square; }
+.@{fa-css-prefix}-twitter:before { content: @fa-var-twitter; }
+.@{fa-css-prefix}-facebook-f:before,
+.@{fa-css-prefix}-facebook:before { content: @fa-var-facebook; }
+.@{fa-css-prefix}-github:before { content: @fa-var-github; }
+.@{fa-css-prefix}-unlock:before { content: @fa-var-unlock; }
+.@{fa-css-prefix}-credit-card:before { content: @fa-var-credit-card; }
+.@{fa-css-prefix}-feed:before,
+.@{fa-css-prefix}-rss:before { content: @fa-var-rss; }
+.@{fa-css-prefix}-hdd-o:before { content: @fa-var-hdd-o; }
+.@{fa-css-prefix}-bullhorn:before { content: @fa-var-bullhorn; }
+.@{fa-css-prefix}-bell:before { content: @fa-var-bell; }
+.@{fa-css-prefix}-certificate:before { content: @fa-var-certificate; }
+.@{fa-css-prefix}-hand-o-right:before { content: @fa-var-hand-o-right; }
+.@{fa-css-prefix}-hand-o-left:before { content: @fa-var-hand-o-left; }
+.@{fa-css-prefix}-hand-o-up:before { content: @fa-var-hand-o-up; }
+.@{fa-css-prefix}-hand-o-down:before { content: @fa-var-hand-o-down; }
+.@{fa-css-prefix}-arrow-circle-left:before { content: @fa-var-arrow-circle-left; }
+.@{fa-css-prefix}-arrow-circle-right:before { content: @fa-var-arrow-circle-right; }
+.@{fa-css-prefix}-arrow-circle-up:before { content: @fa-var-arrow-circle-up; }
+.@{fa-css-prefix}-arrow-circle-down:before { content: @fa-var-arrow-circle-down; }
+.@{fa-css-prefix}-globe:before { content: @fa-var-globe; }
+.@{fa-css-prefix}-wrench:before { content: @fa-var-wrench; }
+.@{fa-css-prefix}-tasks:before { content: @fa-var-tasks; }
+.@{fa-css-prefix}-filter:before { content: @fa-var-filter; }
+.@{fa-css-prefix}-briefcase:before { content: @fa-var-briefcase; }
+.@{fa-css-prefix}-arrows-alt:before { content: @fa-var-arrows-alt; }
+.@{fa-css-prefix}-group:before,
+.@{fa-css-prefix}-users:before { content: @fa-var-users; }
+.@{fa-css-prefix}-chain:before,
+.@{fa-css-prefix}-link:before { content: @fa-var-link; }
+.@{fa-css-prefix}-cloud:before { content: @fa-var-cloud; }
+.@{fa-css-prefix}-flask:before { content: @fa-var-flask; }
+.@{fa-css-prefix}-cut:before,
+.@{fa-css-prefix}-scissors:before { content: @fa-var-scissors; }
+.@{fa-css-prefix}-copy:before,
+.@{fa-css-prefix}-files-o:before { content: @fa-var-files-o; }
+.@{fa-css-prefix}-paperclip:before { content: @fa-var-paperclip; }
+.@{fa-css-prefix}-save:before,
+.@{fa-css-prefix}-floppy-o:before { content: @fa-var-floppy-o; }
+.@{fa-css-prefix}-square:before { content: @fa-var-square; }
+.@{fa-css-prefix}-navicon:before,
+.@{fa-css-prefix}-reorder:before,
+.@{fa-css-prefix}-bars:before { content: @fa-var-bars; }
+.@{fa-css-prefix}-list-ul:before { content: @fa-var-list-ul; }
+.@{fa-css-prefix}-list-ol:before { content: @fa-var-list-ol; }
+.@{fa-css-prefix}-strikethrough:before { content: @fa-var-strikethrough; }
+.@{fa-css-prefix}-underline:before { content: @fa-var-underline; }
+.@{fa-css-prefix}-table:before { content: @fa-var-table; }
+.@{fa-css-prefix}-magic:before { content: @fa-var-magic; }
+.@{fa-css-prefix}-truck:before { content: @fa-var-truck; }
+.@{fa-css-prefix}-pinterest:before { content: @fa-var-pinterest; }
+.@{fa-css-prefix}-pinterest-square:before { content: @fa-var-pinterest-square; }
+.@{fa-css-prefix}-google-plus-square:before { content: @fa-var-google-plus-square; }
+.@{fa-css-prefix}-google-plus:before { content: @fa-var-google-plus; }
+.@{fa-css-prefix}-money:before { content: @fa-var-money; }
+.@{fa-css-prefix}-caret-down:before { content: @fa-var-caret-down; }
+.@{fa-css-prefix}-caret-up:before { content: @fa-var-caret-up; }
+.@{fa-css-prefix}-caret-left:before { content: @fa-var-caret-left; }
+.@{fa-css-prefix}-caret-right:before { content: @fa-var-caret-right; }
+.@{fa-css-prefix}-columns:before { content: @fa-var-columns; }
+.@{fa-css-prefix}-unsorted:before,
+.@{fa-css-prefix}-sort:before { content: @fa-var-sort; }
+.@{fa-css-prefix}-sort-down:before,
+.@{fa-css-prefix}-sort-desc:before { content: @fa-var-sort-desc; }
+.@{fa-css-prefix}-sort-up:before,
+.@{fa-css-prefix}-sort-asc:before { content: @fa-var-sort-asc; }
+.@{fa-css-prefix}-envelope:before { content: @fa-var-envelope; }
+.@{fa-css-prefix}-linkedin:before { content: @fa-var-linkedin; }
+.@{fa-css-prefix}-rotate-left:before,
+.@{fa-css-prefix}-undo:before { content: @fa-var-undo; }
+.@{fa-css-prefix}-legal:before,
+.@{fa-css-prefix}-gavel:before { content: @fa-var-gavel; }
+.@{fa-css-prefix}-dashboard:before,
+.@{fa-css-prefix}-tachometer:before { content: @fa-var-tachometer; }
+.@{fa-css-prefix}-comment-o:before { content: @fa-var-comment-o; }
+.@{fa-css-prefix}-comments-o:before { content: @fa-var-comments-o; }
+.@{fa-css-prefix}-flash:before,
+.@{fa-css-prefix}-bolt:before { content: @fa-var-bolt; }
+.@{fa-css-prefix}-sitemap:before { content: @fa-var-sitemap; }
+.@{fa-css-prefix}-umbrella:before { content: @fa-var-umbrella; }
+.@{fa-css-prefix}-paste:before,
+.@{fa-css-prefix}-clipboard:before { content: @fa-var-clipboard; }
+.@{fa-css-prefix}-lightbulb-o:before { content: @fa-var-lightbulb-o; }
+.@{fa-css-prefix}-exchange:before { content: @fa-var-exchange; }
+.@{fa-css-prefix}-cloud-download:before { content: @fa-var-cloud-download; }
+.@{fa-css-prefix}-cloud-upload:before { content: @fa-var-cloud-upload; }
+.@{fa-css-prefix}-user-md:before { content: @fa-var-user-md; }
+.@{fa-css-prefix}-stethoscope:before { content: @fa-var-stethoscope; }
+.@{fa-css-prefix}-suitcase:before { content: @fa-var-suitcase; }
+.@{fa-css-prefix}-bell-o:before { content: @fa-var-bell-o; }
+.@{fa-css-prefix}-coffee:before { content: @fa-var-coffee; }
+.@{fa-css-prefix}-cutlery:before { content: @fa-var-cutlery; }
+.@{fa-css-prefix}-file-text-o:before { content: @fa-var-file-text-o; }
+.@{fa-css-prefix}-building-o:before { content: @fa-var-building-o; }
+.@{fa-css-prefix}-hospital-o:before { content: @fa-var-hospital-o; }
+.@{fa-css-prefix}-ambulance:before { content: @fa-var-ambulance; }
+.@{fa-css-prefix}-medkit:before { content: @fa-var-medkit; }
+.@{fa-css-prefix}-fighter-jet:before { content: @fa-var-fighter-jet; }
+.@{fa-css-prefix}-beer:before { content: @fa-var-beer; }
+.@{fa-css-prefix}-h-square:before { content: @fa-var-h-square; }
+.@{fa-css-prefix}-plus-square:before { content: @fa-var-plus-square; }
+.@{fa-css-prefix}-angle-double-left:before { content: @fa-var-angle-double-left; }
+.@{fa-css-prefix}-angle-double-right:before { content: @fa-var-angle-double-right; }
+.@{fa-css-prefix}-angle-double-up:before { content: @fa-var-angle-double-up; }
+.@{fa-css-prefix}-angle-double-down:before { content: @fa-var-angle-double-down; }
+.@{fa-css-prefix}-angle-left:before { content: @fa-var-angle-left; }
+.@{fa-css-prefix}-angle-right:before { content: @fa-var-angle-right; }
+.@{fa-css-prefix}-angle-up:before { content: @fa-var-angle-up; }
+.@{fa-css-prefix}-angle-down:before { content: @fa-var-angle-down; }
+.@{fa-css-prefix}-desktop:before { content: @fa-var-desktop; }
+.@{fa-css-prefix}-laptop:before { content: @fa-var-laptop; }
+.@{fa-css-prefix}-tablet:before { content: @fa-var-tablet; }
+.@{fa-css-prefix}-mobile-phone:before,
+.@{fa-css-prefix}-mobile:before { content: @fa-var-mobile; }
+.@{fa-css-prefix}-circle-o:before { content: @fa-var-circle-o; }
+.@{fa-css-prefix}-quote-left:before { content: @fa-var-quote-left; }
+.@{fa-css-prefix}-quote-right:before { content: @fa-var-quote-right; }
+.@{fa-css-prefix}-spinner:before { content: @fa-var-spinner; }
+.@{fa-css-prefix}-circle:before { content: @fa-var-circle; }
+.@{fa-css-prefix}-mail-reply:before,
+.@{fa-css-prefix}-reply:before { content: @fa-var-reply; }
+.@{fa-css-prefix}-github-alt:before { content: @fa-var-github-alt; }
+.@{fa-css-prefix}-folder-o:before { content: @fa-var-folder-o; }
+.@{fa-css-prefix}-folder-open-o:before { content: @fa-var-folder-open-o; }
+.@{fa-css-prefix}-smile-o:before { content: @fa-var-smile-o; }
+.@{fa-css-prefix}-frown-o:before { content: @fa-var-frown-o; }
+.@{fa-css-prefix}-meh-o:before { content: @fa-var-meh-o; }
+.@{fa-css-prefix}-gamepad:before { content: @fa-var-gamepad; }
+.@{fa-css-prefix}-keyboard-o:before { content: @fa-var-keyboard-o; }
+.@{fa-css-prefix}-flag-o:before { content: @fa-var-flag-o; }
+.@{fa-css-prefix}-flag-checkered:before { content: @fa-var-flag-checkered; }
+.@{fa-css-prefix}-terminal:before { content: @fa-var-terminal; }
+.@{fa-css-prefix}-code:before { content: @fa-var-code; }
+.@{fa-css-prefix}-mail-reply-all:before,
+.@{fa-css-prefix}-reply-all:before { content: @fa-var-reply-all; }
+.@{fa-css-prefix}-star-half-empty:before,
+.@{fa-css-prefix}-star-half-full:before,
+.@{fa-css-prefix}-star-half-o:before { content: @fa-var-star-half-o; }
+.@{fa-css-prefix}-location-arrow:before { content: @fa-var-location-arrow; }
+.@{fa-css-prefix}-crop:before { content: @fa-var-crop; }
+.@{fa-css-prefix}-code-fork:before { content: @fa-var-code-fork; }
+.@{fa-css-prefix}-unlink:before,
+.@{fa-css-prefix}-chain-broken:before { content: @fa-var-chain-broken; }
+.@{fa-css-prefix}-question:before { content: @fa-var-question; }
+.@{fa-css-prefix}-info:before { content: @fa-var-info; }
+.@{fa-css-prefix}-exclamation:before { content: @fa-var-exclamation; }
+.@{fa-css-prefix}-superscript:before { content: @fa-var-superscript; }
+.@{fa-css-prefix}-subscript:before { content: @fa-var-subscript; }
+.@{fa-css-prefix}-eraser:before { content: @fa-var-eraser; }
+.@{fa-css-prefix}-puzzle-piece:before { content: @fa-var-puzzle-piece; }
+.@{fa-css-prefix}-microphone:before { content: @fa-var-microphone; }
+.@{fa-css-prefix}-microphone-slash:before { content: @fa-var-microphone-slash; }
+.@{fa-css-prefix}-shield:before { content: @fa-var-shield; }
+.@{fa-css-prefix}-calendar-o:before { content: @fa-var-calendar-o; }
+.@{fa-css-prefix}-fire-extinguisher:before { content: @fa-var-fire-extinguisher; }
+.@{fa-css-prefix}-rocket:before { content: @fa-var-rocket; }
+.@{fa-css-prefix}-maxcdn:before { content: @fa-var-maxcdn; }
+.@{fa-css-prefix}-chevron-circle-left:before { content: @fa-var-chevron-circle-left; }
+.@{fa-css-prefix}-chevron-circle-right:before { content: @fa-var-chevron-circle-right; }
+.@{fa-css-prefix}-chevron-circle-up:before { content: @fa-var-chevron-circle-up; }
+.@{fa-css-prefix}-chevron-circle-down:before { content: @fa-var-chevron-circle-down; }
+.@{fa-css-prefix}-html5:before { content: @fa-var-html5; }
+.@{fa-css-prefix}-css3:before { content: @fa-var-css3; }
+.@{fa-css-prefix}-anchor:before { content: @fa-var-anchor; }
+.@{fa-css-prefix}-unlock-alt:before { content: @fa-var-unlock-alt; }
+.@{fa-css-prefix}-bullseye:before { content: @fa-var-bullseye; }
+.@{fa-css-prefix}-ellipsis-h:before { content: @fa-var-ellipsis-h; }
+.@{fa-css-prefix}-ellipsis-v:before { content: @fa-var-ellipsis-v; }
+.@{fa-css-prefix}-rss-square:before { content: @fa-var-rss-square; }
+.@{fa-css-prefix}-play-circle:before { content: @fa-var-play-circle; }
+.@{fa-css-prefix}-ticket:before { content: @fa-var-ticket; }
+.@{fa-css-prefix}-minus-square:before { content: @fa-var-minus-square; }
+.@{fa-css-prefix}-minus-square-o:before { content: @fa-var-minus-square-o; }
+.@{fa-css-prefix}-level-up:before { content: @fa-var-level-up; }
+.@{fa-css-prefix}-level-down:before { content: @fa-var-level-down; }
+.@{fa-css-prefix}-check-square:before { content: @fa-var-check-square; }
+.@{fa-css-prefix}-pencil-square:before { content: @fa-var-pencil-square; }
+.@{fa-css-prefix}-external-link-square:before { content: @fa-var-external-link-square; }
+.@{fa-css-prefix}-share-square:before { content: @fa-var-share-square; }
+.@{fa-css-prefix}-compass:before { content: @fa-var-compass; }
+.@{fa-css-prefix}-toggle-down:before,
+.@{fa-css-prefix}-caret-square-o-down:before { content: @fa-var-caret-square-o-down; }
+.@{fa-css-prefix}-toggle-up:before,
+.@{fa-css-prefix}-caret-square-o-up:before { content: @fa-var-caret-square-o-up; }
+.@{fa-css-prefix}-toggle-right:before,
+.@{fa-css-prefix}-caret-square-o-right:before { content: @fa-var-caret-square-o-right; }
+.@{fa-css-prefix}-euro:before,
+.@{fa-css-prefix}-eur:before { content: @fa-var-eur; }
+.@{fa-css-prefix}-gbp:before { content: @fa-var-gbp; }
+.@{fa-css-prefix}-dollar:before,
+.@{fa-css-prefix}-usd:before { content: @fa-var-usd; }
+.@{fa-css-prefix}-rupee:before,
+.@{fa-css-prefix}-inr:before { content: @fa-var-inr; }
+.@{fa-css-prefix}-cny:before,
+.@{fa-css-prefix}-rmb:before,
+.@{fa-css-prefix}-yen:before,
+.@{fa-css-prefix}-jpy:before { content: @fa-var-jpy; }
+.@{fa-css-prefix}-ruble:before,
+.@{fa-css-prefix}-rouble:before,
+.@{fa-css-prefix}-rub:before { content: @fa-var-rub; }
+.@{fa-css-prefix}-won:before,
+.@{fa-css-prefix}-krw:before { content: @fa-var-krw; }
+.@{fa-css-prefix}-bitcoin:before,
+.@{fa-css-prefix}-btc:before { content: @fa-var-btc; }
+.@{fa-css-prefix}-file:before { content: @fa-var-file; }
+.@{fa-css-prefix}-file-text:before { content: @fa-var-file-text; }
+.@{fa-css-prefix}-sort-alpha-asc:before { content: @fa-var-sort-alpha-asc; }
+.@{fa-css-prefix}-sort-alpha-desc:before { content: @fa-var-sort-alpha-desc; }
+.@{fa-css-prefix}-sort-amount-asc:before { content: @fa-var-sort-amount-asc; }
+.@{fa-css-prefix}-sort-amount-desc:before { content: @fa-var-sort-amount-desc; }
+.@{fa-css-prefix}-sort-numeric-asc:before { content: @fa-var-sort-numeric-asc; }
+.@{fa-css-prefix}-sort-numeric-desc:before { content: @fa-var-sort-numeric-desc; }
+.@{fa-css-prefix}-thumbs-up:before { content: @fa-var-thumbs-up; }
+.@{fa-css-prefix}-thumbs-down:before { content: @fa-var-thumbs-down; }
+.@{fa-css-prefix}-youtube-square:before { content: @fa-var-youtube-square; }
+.@{fa-css-prefix}-youtube:before { content: @fa-var-youtube; }
+.@{fa-css-prefix}-xing:before { content: @fa-var-xing; }
+.@{fa-css-prefix}-xing-square:before { content: @fa-var-xing-square; }
+.@{fa-css-prefix}-youtube-play:before { content: @fa-var-youtube-play; }
+.@{fa-css-prefix}-dropbox:before { content: @fa-var-dropbox; }
+.@{fa-css-prefix}-stack-overflow:before { content: @fa-var-stack-overflow; }
+.@{fa-css-prefix}-instagram:before { content: @fa-var-instagram; }
+.@{fa-css-prefix}-flickr:before { content: @fa-var-flickr; }
+.@{fa-css-prefix}-adn:before { content: @fa-var-adn; }
+.@{fa-css-prefix}-bitbucket:before { content: @fa-var-bitbucket; }
+.@{fa-css-prefix}-bitbucket-square:before { content: @fa-var-bitbucket-square; }
+.@{fa-css-prefix}-tumblr:before { content: @fa-var-tumblr; }
+.@{fa-css-prefix}-tumblr-square:before { content: @fa-var-tumblr-square; }
+.@{fa-css-prefix}-long-arrow-down:before { content: @fa-var-long-arrow-down; }
+.@{fa-css-prefix}-long-arrow-up:before { content: @fa-var-long-arrow-up; }
+.@{fa-css-prefix}-long-arrow-left:before { content: @fa-var-long-arrow-left; }
+.@{fa-css-prefix}-long-arrow-right:before { content: @fa-var-long-arrow-right; }
+.@{fa-css-prefix}-apple:before { content: @fa-var-apple; }
+.@{fa-css-prefix}-windows:before { content: @fa-var-windows; }
+.@{fa-css-prefix}-android:before { content: @fa-var-android; }
+.@{fa-css-prefix}-linux:before { content: @fa-var-linux; }
+.@{fa-css-prefix}-dribbble:before { content: @fa-var-dribbble; }
+.@{fa-css-prefix}-skype:before { content: @fa-var-skype; }
+.@{fa-css-prefix}-foursquare:before { content: @fa-var-foursquare; }
+.@{fa-css-prefix}-trello:before { content: @fa-var-trello; }
+.@{fa-css-prefix}-female:before { content: @fa-var-female; }
+.@{fa-css-prefix}-male:before { content: @fa-var-male; }
+.@{fa-css-prefix}-gittip:before,
+.@{fa-css-prefix}-gratipay:before { content: @fa-var-gratipay; }
+.@{fa-css-prefix}-sun-o:before { content: @fa-var-sun-o; }
+.@{fa-css-prefix}-moon-o:before { content: @fa-var-moon-o; }
+.@{fa-css-prefix}-archive:before { content: @fa-var-archive; }
+.@{fa-css-prefix}-bug:before { content: @fa-var-bug; }
+.@{fa-css-prefix}-vk:before { content: @fa-var-vk; }
+.@{fa-css-prefix}-weibo:before { content: @fa-var-weibo; }
+.@{fa-css-prefix}-renren:before { content: @fa-var-renren; }
+.@{fa-css-prefix}-pagelines:before { content: @fa-var-pagelines; }
+.@{fa-css-prefix}-stack-exchange:before { content: @fa-var-stack-exchange; }
+.@{fa-css-prefix}-arrow-circle-o-right:before { content: @fa-var-arrow-circle-o-right; }
+.@{fa-css-prefix}-arrow-circle-o-left:before { content: @fa-var-arrow-circle-o-left; }
+.@{fa-css-prefix}-toggle-left:before,
+.@{fa-css-prefix}-caret-square-o-left:before { content: @fa-var-caret-square-o-left; }
+.@{fa-css-prefix}-dot-circle-o:before { content: @fa-var-dot-circle-o; }
+.@{fa-css-prefix}-wheelchair:before { content: @fa-var-wheelchair; }
+.@{fa-css-prefix}-vimeo-square:before { content: @fa-var-vimeo-square; }
+.@{fa-css-prefix}-turkish-lira:before,
+.@{fa-css-prefix}-try:before { content: @fa-var-try; }
+.@{fa-css-prefix}-plus-square-o:before { content: @fa-var-plus-square-o; }
+.@{fa-css-prefix}-space-shuttle:before { content: @fa-var-space-shuttle; }
+.@{fa-css-prefix}-slack:before { content: @fa-var-slack; }
+.@{fa-css-prefix}-envelope-square:before { content: @fa-var-envelope-square; }
+.@{fa-css-prefix}-wordpress:before { content: @fa-var-wordpress; }
+.@{fa-css-prefix}-openid:before { content: @fa-var-openid; }
+.@{fa-css-prefix}-institution:before,
+.@{fa-css-prefix}-bank:before,
+.@{fa-css-prefix}-university:before { content: @fa-var-university; }
+.@{fa-css-prefix}-mortar-board:before,
+.@{fa-css-prefix}-graduation-cap:before { content: @fa-var-graduation-cap; }
+.@{fa-css-prefix}-yahoo:before { content: @fa-var-yahoo; }
+.@{fa-css-prefix}-google:before { content: @fa-var-google; }
+.@{fa-css-prefix}-reddit:before { content: @fa-var-reddit; }
+.@{fa-css-prefix}-reddit-square:before { content: @fa-var-reddit-square; }
+.@{fa-css-prefix}-stumbleupon-circle:before { content: @fa-var-stumbleupon-circle; }
+.@{fa-css-prefix}-stumbleupon:before { content: @fa-var-stumbleupon; }
+.@{fa-css-prefix}-delicious:before { content: @fa-var-delicious; }
+.@{fa-css-prefix}-digg:before { content: @fa-var-digg; }
+.@{fa-css-prefix}-pied-piper:before { content: @fa-var-pied-piper; }
+.@{fa-css-prefix}-pied-piper-alt:before { content: @fa-var-pied-piper-alt; }
+.@{fa-css-prefix}-drupal:before { content: @fa-var-drupal; }
+.@{fa-css-prefix}-joomla:before { content: @fa-var-joomla; }
+.@{fa-css-prefix}-language:before { content: @fa-var-language; }
+.@{fa-css-prefix}-fax:before { content: @fa-var-fax; }
+.@{fa-css-prefix}-building:before { content: @fa-var-building; }
+.@{fa-css-prefix}-child:before { content: @fa-var-child; }
+.@{fa-css-prefix}-paw:before { content: @fa-var-paw; }
+.@{fa-css-prefix}-spoon:before { content: @fa-var-spoon; }
+.@{fa-css-prefix}-cube:before { content: @fa-var-cube; }
+.@{fa-css-prefix}-cubes:before { content: @fa-var-cubes; }
+.@{fa-css-prefix}-behance:before { content: @fa-var-behance; }
+.@{fa-css-prefix}-behance-square:before { content: @fa-var-behance-square; }
+.@{fa-css-prefix}-steam:before { content: @fa-var-steam; }
+.@{fa-css-prefix}-steam-square:before { content: @fa-var-steam-square; }
+.@{fa-css-prefix}-recycle:before { content: @fa-var-recycle; }
+.@{fa-css-prefix}-automobile:before,
+.@{fa-css-prefix}-car:before { content: @fa-var-car; }
+.@{fa-css-prefix}-cab:before,
+.@{fa-css-prefix}-taxi:before { content: @fa-var-taxi; }
+.@{fa-css-prefix}-tree:before { content: @fa-var-tree; }
+.@{fa-css-prefix}-spotify:before { content: @fa-var-spotify; }
+.@{fa-css-prefix}-deviantart:before { content: @fa-var-deviantart; }
+.@{fa-css-prefix}-soundcloud:before { content: @fa-var-soundcloud; }
+.@{fa-css-prefix}-database:before { content: @fa-var-database; }
+.@{fa-css-prefix}-file-pdf-o:before { content: @fa-var-file-pdf-o; }
+.@{fa-css-prefix}-file-word-o:before { content: @fa-var-file-word-o; }
+.@{fa-css-prefix}-file-excel-o:before { content: @fa-var-file-excel-o; }
+.@{fa-css-prefix}-file-powerpoint-o:before { content: @fa-var-file-powerpoint-o; }
+.@{fa-css-prefix}-file-photo-o:before,
+.@{fa-css-prefix}-file-picture-o:before,
+.@{fa-css-prefix}-file-image-o:before { content: @fa-var-file-image-o; }
+.@{fa-css-prefix}-file-zip-o:before,
+.@{fa-css-prefix}-file-archive-o:before { content: @fa-var-file-archive-o; }
+.@{fa-css-prefix}-file-sound-o:before,
+.@{fa-css-prefix}-file-audio-o:before { content: @fa-var-file-audio-o; }
+.@{fa-css-prefix}-file-movie-o:before,
+.@{fa-css-prefix}-file-video-o:before { content: @fa-var-file-video-o; }
+.@{fa-css-prefix}-file-code-o:before { content: @fa-var-file-code-o; }
+.@{fa-css-prefix}-vine:before { content: @fa-var-vine; }
+.@{fa-css-prefix}-codepen:before { content: @fa-var-codepen; }
+.@{fa-css-prefix}-jsfiddle:before { content: @fa-var-jsfiddle; }
+.@{fa-css-prefix}-life-bouy:before,
+.@{fa-css-prefix}-life-buoy:before,
+.@{fa-css-prefix}-life-saver:before,
+.@{fa-css-prefix}-support:before,
+.@{fa-css-prefix}-life-ring:before { content: @fa-var-life-ring; }
+.@{fa-css-prefix}-circle-o-notch:before { content: @fa-var-circle-o-notch; }
+.@{fa-css-prefix}-ra:before,
+.@{fa-css-prefix}-rebel:before { content: @fa-var-rebel; }
+.@{fa-css-prefix}-ge:before,
+.@{fa-css-prefix}-empire:before { content: @fa-var-empire; }
+.@{fa-css-prefix}-git-square:before { content: @fa-var-git-square; }
+.@{fa-css-prefix}-git:before { content: @fa-var-git; }
+.@{fa-css-prefix}-y-combinator-square:before,
+.@{fa-css-prefix}-yc-square:before,
+.@{fa-css-prefix}-hacker-news:before { content: @fa-var-hacker-news; }
+.@{fa-css-prefix}-tencent-weibo:before { content: @fa-var-tencent-weibo; }
+.@{fa-css-prefix}-qq:before { content: @fa-var-qq; }
+.@{fa-css-prefix}-wechat:before,
+.@{fa-css-prefix}-weixin:before { content: @fa-var-weixin; }
+.@{fa-css-prefix}-send:before,
+.@{fa-css-prefix}-paper-plane:before { content: @fa-var-paper-plane; }
+.@{fa-css-prefix}-send-o:before,
+.@{fa-css-prefix}-paper-plane-o:before { content: @fa-var-paper-plane-o; }
+.@{fa-css-prefix}-history:before { content: @fa-var-history; }
+.@{fa-css-prefix}-circle-thin:before { content: @fa-var-circle-thin; }
+.@{fa-css-prefix}-header:before { content: @fa-var-header; }
+.@{fa-css-prefix}-paragraph:before { content: @fa-var-paragraph; }
+.@{fa-css-prefix}-sliders:before { content: @fa-var-sliders; }
+.@{fa-css-prefix}-share-alt:before { content: @fa-var-share-alt; }
+.@{fa-css-prefix}-share-alt-square:before { content: @fa-var-share-alt-square; }
+.@{fa-css-prefix}-bomb:before { content: @fa-var-bomb; }
+.@{fa-css-prefix}-soccer-ball-o:before,
+.@{fa-css-prefix}-futbol-o:before { content: @fa-var-futbol-o; }
+.@{fa-css-prefix}-tty:before { content: @fa-var-tty; }
+.@{fa-css-prefix}-binoculars:before { content: @fa-var-binoculars; }
+.@{fa-css-prefix}-plug:before { content: @fa-var-plug; }
+.@{fa-css-prefix}-slideshare:before { content: @fa-var-slideshare; }
+.@{fa-css-prefix}-twitch:before { content: @fa-var-twitch; }
+.@{fa-css-prefix}-yelp:before { content: @fa-var-yelp; }
+.@{fa-css-prefix}-newspaper-o:before { content: @fa-var-newspaper-o; }
+.@{fa-css-prefix}-wifi:before { content: @fa-var-wifi; }
+.@{fa-css-prefix}-calculator:before { content: @fa-var-calculator; }
+.@{fa-css-prefix}-paypal:before { content: @fa-var-paypal; }
+.@{fa-css-prefix}-google-wallet:before { content: @fa-var-google-wallet; }
+.@{fa-css-prefix}-cc-visa:before { content: @fa-var-cc-visa; }
+.@{fa-css-prefix}-cc-mastercard:before { content: @fa-var-cc-mastercard; }
+.@{fa-css-prefix}-cc-discover:before { content: @fa-var-cc-discover; }
+.@{fa-css-prefix}-cc-amex:before { content: @fa-var-cc-amex; }
+.@{fa-css-prefix}-cc-paypal:before { content: @fa-var-cc-paypal; }
+.@{fa-css-prefix}-cc-stripe:before { content: @fa-var-cc-stripe; }
+.@{fa-css-prefix}-bell-slash:before { content: @fa-var-bell-slash; }
+.@{fa-css-prefix}-bell-slash-o:before { content: @fa-var-bell-slash-o; }
+.@{fa-css-prefix}-trash:before { content: @fa-var-trash; }
+.@{fa-css-prefix}-copyright:before { content: @fa-var-copyright; }
+.@{fa-css-prefix}-at:before { content: @fa-var-at; }
+.@{fa-css-prefix}-eyedropper:before { content: @fa-var-eyedropper; }
+.@{fa-css-prefix}-paint-brush:before { content: @fa-var-paint-brush; }
+.@{fa-css-prefix}-birthday-cake:before { content: @fa-var-birthday-cake; }
+.@{fa-css-prefix}-area-chart:before { content: @fa-var-area-chart; }
+.@{fa-css-prefix}-pie-chart:before { content: @fa-var-pie-chart; }
+.@{fa-css-prefix}-line-chart:before { content: @fa-var-line-chart; }
+.@{fa-css-prefix}-lastfm:before { content: @fa-var-lastfm; }
+.@{fa-css-prefix}-lastfm-square:before { content: @fa-var-lastfm-square; }
+.@{fa-css-prefix}-toggle-off:before { content: @fa-var-toggle-off; }
+.@{fa-css-prefix}-toggle-on:before { content: @fa-var-toggle-on; }
+.@{fa-css-prefix}-bicycle:before { content: @fa-var-bicycle; }
+.@{fa-css-prefix}-bus:before { content: @fa-var-bus; }
+.@{fa-css-prefix}-ioxhost:before { content: @fa-var-ioxhost; }
+.@{fa-css-prefix}-angellist:before { content: @fa-var-angellist; }
+.@{fa-css-prefix}-cc:before { content: @fa-var-cc; }
+.@{fa-css-prefix}-shekel:before,
+.@{fa-css-prefix}-sheqel:before,
+.@{fa-css-prefix}-ils:before { content: @fa-var-ils; }
+.@{fa-css-prefix}-meanpath:before { content: @fa-var-meanpath; }
+.@{fa-css-prefix}-buysellads:before { content: @fa-var-buysellads; }
+.@{fa-css-prefix}-connectdevelop:before { content: @fa-var-connectdevelop; }
+.@{fa-css-prefix}-dashcube:before { content: @fa-var-dashcube; }
+.@{fa-css-prefix}-forumbee:before { content: @fa-var-forumbee; }
+.@{fa-css-prefix}-leanpub:before { content: @fa-var-leanpub; }
+.@{fa-css-prefix}-sellsy:before { content: @fa-var-sellsy; }
+.@{fa-css-prefix}-shirtsinbulk:before { content: @fa-var-shirtsinbulk; }
+.@{fa-css-prefix}-simplybuilt:before { content: @fa-var-simplybuilt; }
+.@{fa-css-prefix}-skyatlas:before { content: @fa-var-skyatlas; }
+.@{fa-css-prefix}-cart-plus:before { content: @fa-var-cart-plus; }
+.@{fa-css-prefix}-cart-arrow-down:before { content: @fa-var-cart-arrow-down; }
+.@{fa-css-prefix}-diamond:before { content: @fa-var-diamond; }
+.@{fa-css-prefix}-ship:before { content: @fa-var-ship; }
+.@{fa-css-prefix}-user-secret:before { content: @fa-var-user-secret; }
+.@{fa-css-prefix}-motorcycle:before { content: @fa-var-motorcycle; }
+.@{fa-css-prefix}-street-view:before { content: @fa-var-street-view; }
+.@{fa-css-prefix}-heartbeat:before { content: @fa-var-heartbeat; }
+.@{fa-css-prefix}-venus:before { content: @fa-var-venus; }
+.@{fa-css-prefix}-mars:before { content: @fa-var-mars; }
+.@{fa-css-prefix}-mercury:before { content: @fa-var-mercury; }
+.@{fa-css-prefix}-intersex:before,
+.@{fa-css-prefix}-transgender:before { content: @fa-var-transgender; }
+.@{fa-css-prefix}-transgender-alt:before { content: @fa-var-transgender-alt; }
+.@{fa-css-prefix}-venus-double:before { content: @fa-var-venus-double; }
+.@{fa-css-prefix}-mars-double:before { content: @fa-var-mars-double; }
+.@{fa-css-prefix}-venus-mars:before { content: @fa-var-venus-mars; }
+.@{fa-css-prefix}-mars-stroke:before { content: @fa-var-mars-stroke; }
+.@{fa-css-prefix}-mars-stroke-v:before { content: @fa-var-mars-stroke-v; }
+.@{fa-css-prefix}-mars-stroke-h:before { content: @fa-var-mars-stroke-h; }
+.@{fa-css-prefix}-neuter:before { content: @fa-var-neuter; }
+.@{fa-css-prefix}-genderless:before { content: @fa-var-genderless; }
+.@{fa-css-prefix}-facebook-official:before { content: @fa-var-facebook-official; }
+.@{fa-css-prefix}-pinterest-p:before { content: @fa-var-pinterest-p; }
+.@{fa-css-prefix}-whatsapp:before { content: @fa-var-whatsapp; }
+.@{fa-css-prefix}-server:before { content: @fa-var-server; }
+.@{fa-css-prefix}-user-plus:before { content: @fa-var-user-plus; }
+.@{fa-css-prefix}-user-times:before { content: @fa-var-user-times; }
+.@{fa-css-prefix}-hotel:before,
+.@{fa-css-prefix}-bed:before { content: @fa-var-bed; }
+.@{fa-css-prefix}-viacoin:before { content: @fa-var-viacoin; }
+.@{fa-css-prefix}-train:before { content: @fa-var-train; }
+.@{fa-css-prefix}-subway:before { content: @fa-var-subway; }
+.@{fa-css-prefix}-medium:before { content: @fa-var-medium; }
+.@{fa-css-prefix}-yc:before,
+.@{fa-css-prefix}-y-combinator:before { content: @fa-var-y-combinator; }
+.@{fa-css-prefix}-optin-monster:before { content: @fa-var-optin-monster; }
+.@{fa-css-prefix}-opencart:before { content: @fa-var-opencart; }
+.@{fa-css-prefix}-expeditedssl:before { content: @fa-var-expeditedssl; }
+.@{fa-css-prefix}-battery-4:before,
+.@{fa-css-prefix}-battery-full:before { content: @fa-var-battery-full; }
+.@{fa-css-prefix}-battery-3:before,
+.@{fa-css-prefix}-battery-three-quarters:before { content: @fa-var-battery-three-quarters; }
+.@{fa-css-prefix}-battery-2:before,
+.@{fa-css-prefix}-battery-half:before { content: @fa-var-battery-half; }
+.@{fa-css-prefix}-battery-1:before,
+.@{fa-css-prefix}-battery-quarter:before { content: @fa-var-battery-quarter; }
+.@{fa-css-prefix}-battery-0:before,
+.@{fa-css-prefix}-battery-empty:before { content: @fa-var-battery-empty; }
+.@{fa-css-prefix}-mouse-pointer:before { content: @fa-var-mouse-pointer; }
+.@{fa-css-prefix}-i-cursor:before { content: @fa-var-i-cursor; }
+.@{fa-css-prefix}-object-group:before { content: @fa-var-object-group; }
+.@{fa-css-prefix}-object-ungroup:before { content: @fa-var-object-ungroup; }
+.@{fa-css-prefix}-sticky-note:before { content: @fa-var-sticky-note; }
+.@{fa-css-prefix}-sticky-note-o:before { content: @fa-var-sticky-note-o; }
+.@{fa-css-prefix}-cc-jcb:before { content: @fa-var-cc-jcb; }
+.@{fa-css-prefix}-cc-diners-club:before { content: @fa-var-cc-diners-club; }
+.@{fa-css-prefix}-clone:before { content: @fa-var-clone; }
+.@{fa-css-prefix}-balance-scale:before { content: @fa-var-balance-scale; }
+.@{fa-css-prefix}-hourglass-o:before { content: @fa-var-hourglass-o; }
+.@{fa-css-prefix}-hourglass-1:before,
+.@{fa-css-prefix}-hourglass-start:before { content: @fa-var-hourglass-start; }
+.@{fa-css-prefix}-hourglass-2:before,
+.@{fa-css-prefix}-hourglass-half:before { content: @fa-var-hourglass-half; }
+.@{fa-css-prefix}-hourglass-3:before,
+.@{fa-css-prefix}-hourglass-end:before { content: @fa-var-hourglass-end; }
+.@{fa-css-prefix}-hourglass:before { content: @fa-var-hourglass; }
+.@{fa-css-prefix}-hand-grab-o:before,
+.@{fa-css-prefix}-hand-rock-o:before { content: @fa-var-hand-rock-o; }
+.@{fa-css-prefix}-hand-stop-o:before,
+.@{fa-css-prefix}-hand-paper-o:before { content: @fa-var-hand-paper-o; }
+.@{fa-css-prefix}-hand-scissors-o:before { content: @fa-var-hand-scissors-o; }
+.@{fa-css-prefix}-hand-lizard-o:before { content: @fa-var-hand-lizard-o; }
+.@{fa-css-prefix}-hand-spock-o:before { content: @fa-var-hand-spock-o; }
+.@{fa-css-prefix}-hand-pointer-o:before { content: @fa-var-hand-pointer-o; }
+.@{fa-css-prefix}-hand-peace-o:before { content: @fa-var-hand-peace-o; }
+.@{fa-css-prefix}-trademark:before { content: @fa-var-trademark; }
+.@{fa-css-prefix}-registered:before { content: @fa-var-registered; }
+.@{fa-css-prefix}-creative-commons:before { content: @fa-var-creative-commons; }
+.@{fa-css-prefix}-gg:before { content: @fa-var-gg; }
+.@{fa-css-prefix}-gg-circle:before { content: @fa-var-gg-circle; }
+.@{fa-css-prefix}-tripadvisor:before { content: @fa-var-tripadvisor; }
+.@{fa-css-prefix}-odnoklassniki:before { content: @fa-var-odnoklassniki; }
+.@{fa-css-prefix}-odnoklassniki-square:before { content: @fa-var-odnoklassniki-square; }
+.@{fa-css-prefix}-get-pocket:before { content: @fa-var-get-pocket; }
+.@{fa-css-prefix}-wikipedia-w:before { content: @fa-var-wikipedia-w; }
+.@{fa-css-prefix}-safari:before { content: @fa-var-safari; }
+.@{fa-css-prefix}-chrome:before { content: @fa-var-chrome; }
+.@{fa-css-prefix}-firefox:before { content: @fa-var-firefox; }
+.@{fa-css-prefix}-opera:before { content: @fa-var-opera; }
+.@{fa-css-prefix}-internet-explorer:before { content: @fa-var-internet-explorer; }
+.@{fa-css-prefix}-tv:before,
+.@{fa-css-prefix}-television:before { content: @fa-var-television; }
+.@{fa-css-prefix}-contao:before { content: @fa-var-contao; }
+.@{fa-css-prefix}-500px:before { content: @fa-var-500px; }
+.@{fa-css-prefix}-amazon:before { content: @fa-var-amazon; }
+.@{fa-css-prefix}-calendar-plus-o:before { content: @fa-var-calendar-plus-o; }
+.@{fa-css-prefix}-calendar-minus-o:before { content: @fa-var-calendar-minus-o; }
+.@{fa-css-prefix}-calendar-times-o:before { content: @fa-var-calendar-times-o; }
+.@{fa-css-prefix}-calendar-check-o:before { content: @fa-var-calendar-check-o; }
+.@{fa-css-prefix}-industry:before { content: @fa-var-industry; }
+.@{fa-css-prefix}-map-pin:before { content: @fa-var-map-pin; }
+.@{fa-css-prefix}-map-signs:before { content: @fa-var-map-signs; }
+.@{fa-css-prefix}-map-o:before { content: @fa-var-map-o; }
+.@{fa-css-prefix}-map:before { content: @fa-var-map; }
+.@{fa-css-prefix}-commenting:before { content: @fa-var-commenting; }
+.@{fa-css-prefix}-commenting-o:before { content: @fa-var-commenting-o; }
+.@{fa-css-prefix}-houzz:before { content: @fa-var-houzz; }
+.@{fa-css-prefix}-vimeo:before { content: @fa-var-vimeo; }
+.@{fa-css-prefix}-black-tie:before { content: @fa-var-black-tie; }
+.@{fa-css-prefix}-fonticons:before { content: @fa-var-fonticons; }
+.@{fa-css-prefix}-reddit-alien:before { content: @fa-var-reddit-alien; }
+.@{fa-css-prefix}-edge:before { content: @fa-var-edge; }
+.@{fa-css-prefix}-credit-card-alt:before { content: @fa-var-credit-card-alt; }
+.@{fa-css-prefix}-codiepie:before { content: @fa-var-codiepie; }
+.@{fa-css-prefix}-modx:before { content: @fa-var-modx; }
+.@{fa-css-prefix}-fort-awesome:before { content: @fa-var-fort-awesome; }
+.@{fa-css-prefix}-usb:before { content: @fa-var-usb; }
+.@{fa-css-prefix}-product-hunt:before { content: @fa-var-product-hunt; }
+.@{fa-css-prefix}-mixcloud:before { content: @fa-var-mixcloud; }
+.@{fa-css-prefix}-scribd:before { content: @fa-var-scribd; }
+.@{fa-css-prefix}-pause-circle:before { content: @fa-var-pause-circle; }
+.@{fa-css-prefix}-pause-circle-o:before { content: @fa-var-pause-circle-o; }
+.@{fa-css-prefix}-stop-circle:before { content: @fa-var-stop-circle; }
+.@{fa-css-prefix}-stop-circle-o:before { content: @fa-var-stop-circle-o; }
+.@{fa-css-prefix}-shopping-bag:before { content: @fa-var-shopping-bag; }
+.@{fa-css-prefix}-shopping-basket:before { content: @fa-var-shopping-basket; }
+.@{fa-css-prefix}-hashtag:before { content: @fa-var-hashtag; }
+.@{fa-css-prefix}-bluetooth:before { content: @fa-var-bluetooth; }
+.@{fa-css-prefix}-bluetooth-b:before { content: @fa-var-bluetooth-b; }
+.@{fa-css-prefix}-percent:before { content: @fa-var-percent; }
+.@{fa-css-prefix}-gitlab:before { content: @fa-var-gitlab; }
+.@{fa-css-prefix}-wpbeginner:before { content: @fa-var-wpbeginner; }
+.@{fa-css-prefix}-wpforms:before { content: @fa-var-wpforms; }
+.@{fa-css-prefix}-envira:before { content: @fa-var-envira; }
+.@{fa-css-prefix}-universal-access:before { content: @fa-var-universal-access; }
+.@{fa-css-prefix}-wheelchair-alt:before { content: @fa-var-wheelchair-alt; }
+.@{fa-css-prefix}-question-circle-o:before { content: @fa-var-question-circle-o; }
+.@{fa-css-prefix}-blind:before { content: @fa-var-blind; }
+.@{fa-css-prefix}-audio-description:before { content: @fa-var-audio-description; }
+.@{fa-css-prefix}-volume-control-phone:before { content: @fa-var-volume-control-phone; }
+.@{fa-css-prefix}-braille:before { content: @fa-var-braille; }
+.@{fa-css-prefix}-assistive-listening-systems:before { content: @fa-var-assistive-listening-systems; }
+.@{fa-css-prefix}-asl-interpreting:before,
+.@{fa-css-prefix}-american-sign-language-interpreting:before { content: @fa-var-american-sign-language-interpreting; }
+.@{fa-css-prefix}-deafness:before,
+.@{fa-css-prefix}-hard-of-hearing:before,
+.@{fa-css-prefix}-deaf:before { content: @fa-var-deaf; }
+.@{fa-css-prefix}-glide:before { content: @fa-var-glide; }
+.@{fa-css-prefix}-glide-g:before { content: @fa-var-glide-g; }
+.@{fa-css-prefix}-signing:before,
+.@{fa-css-prefix}-sign-language:before { content: @fa-var-sign-language; }
+.@{fa-css-prefix}-low-vision:before { content: @fa-var-low-vision; }
+.@{fa-css-prefix}-viadeo:before { content: @fa-var-viadeo; }
+.@{fa-css-prefix}-viadeo-square:before { content: @fa-var-viadeo-square; }
+.@{fa-css-prefix}-snapchat:before { content: @fa-var-snapchat; }
+.@{fa-css-prefix}-snapchat-ghost:before { content: @fa-var-snapchat-ghost; }
+.@{fa-css-prefix}-snapchat-square:before { content: @fa-var-snapchat-square; }
diff --git a/membership/static/font-awesome/less/larger.less b/membership/static/font-awesome/less/larger.less
new file mode 100755
index 0000000..c9d6467
--- /dev/null
+++ b/membership/static/font-awesome/less/larger.less
@@ -0,0 +1,13 @@
+// Icon Sizes
+// -------------------------
+
+/* makes the font 33% larger relative to the icon container */
+.@{fa-css-prefix}-lg {
+ font-size: (4em / 3);
+ line-height: (3em / 4);
+ vertical-align: -15%;
+}
+.@{fa-css-prefix}-2x { font-size: 2em; }
+.@{fa-css-prefix}-3x { font-size: 3em; }
+.@{fa-css-prefix}-4x { font-size: 4em; }
+.@{fa-css-prefix}-5x { font-size: 5em; }
diff --git a/membership/static/font-awesome/less/list.less b/membership/static/font-awesome/less/list.less
new file mode 100755
index 0000000..0b44038
--- /dev/null
+++ b/membership/static/font-awesome/less/list.less
@@ -0,0 +1,19 @@
+// List Icons
+// -------------------------
+
+.@{fa-css-prefix}-ul {
+ padding-left: 0;
+ margin-left: @fa-li-width;
+ list-style-type: none;
+ > li { position: relative; }
+}
+.@{fa-css-prefix}-li {
+ position: absolute;
+ left: -@fa-li-width;
+ width: @fa-li-width;
+ top: (2em / 14);
+ text-align: center;
+ &.@{fa-css-prefix}-lg {
+ left: (-@fa-li-width + (4em / 14));
+ }
+}
diff --git a/membership/static/font-awesome/less/mixins.less b/membership/static/font-awesome/less/mixins.less
new file mode 100755
index 0000000..beef231
--- /dev/null
+++ b/membership/static/font-awesome/less/mixins.less
@@ -0,0 +1,60 @@
+// Mixins
+// --------------------------
+
+.fa-icon() {
+ display: inline-block;
+ font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
+ font-size: inherit; // can't have font-size inherit on line above, so need to override
+ text-rendering: auto; // optimizelegibility throws things off #1094
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+
+}
+
+.fa-icon-rotate(@degrees, @rotation) {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})";
+ -webkit-transform: rotate(@degrees);
+ -ms-transform: rotate(@degrees);
+ transform: rotate(@degrees);
+}
+
+.fa-icon-flip(@horiz, @vert, @rotation) {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)";
+ -webkit-transform: scale(@horiz, @vert);
+ -ms-transform: scale(@horiz, @vert);
+ transform: scale(@horiz, @vert);
+}
+
+
+// Only display content to screen readers. A la Bootstrap 4.
+//
+// See: http://a11yproject.com/posts/how-to-hide-content/
+
+.sr-only() {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0,0,0,0);
+ border: 0;
+}
+
+// Use in conjunction with .sr-only to only display content when it's focused.
+//
+// Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
+//
+// Credit: HTML5 Boilerplate
+
+.sr-only-focusable() {
+ &:active,
+ &:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+ }
+}
diff --git a/membership/static/font-awesome/less/path.less b/membership/static/font-awesome/less/path.less
new file mode 100755
index 0000000..835be41
--- /dev/null
+++ b/membership/static/font-awesome/less/path.less
@@ -0,0 +1,15 @@
+/* FONT PATH
+ * -------------------------- */
+
+@font-face {
+ font-family: 'FontAwesome';
+ src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');
+ src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),
+ url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),
+ url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),
+ url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),
+ url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');
+ // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
+ font-weight: normal;
+ font-style: normal;
+}
diff --git a/membership/static/font-awesome/less/rotated-flipped.less b/membership/static/font-awesome/less/rotated-flipped.less
new file mode 100755
index 0000000..f6ba814
--- /dev/null
+++ b/membership/static/font-awesome/less/rotated-flipped.less
@@ -0,0 +1,20 @@
+// Rotated & Flipped Icons
+// -------------------------
+
+.@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); }
+.@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
+.@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
+
+.@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
+.@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); }
+
+// Hook for IE8-9
+// -------------------------
+
+:root .@{fa-css-prefix}-rotate-90,
+:root .@{fa-css-prefix}-rotate-180,
+:root .@{fa-css-prefix}-rotate-270,
+:root .@{fa-css-prefix}-flip-horizontal,
+:root .@{fa-css-prefix}-flip-vertical {
+ filter: none;
+}
diff --git a/membership/static/font-awesome/less/screen-reader.less b/membership/static/font-awesome/less/screen-reader.less
new file mode 100755
index 0000000..11c1881
--- /dev/null
+++ b/membership/static/font-awesome/less/screen-reader.less
@@ -0,0 +1,5 @@
+// Screen Readers
+// -------------------------
+
+.sr-only { .sr-only(); }
+.sr-only-focusable { .sr-only-focusable(); }
diff --git a/membership/static/font-awesome/less/stacked.less b/membership/static/font-awesome/less/stacked.less
new file mode 100755
index 0000000..fc53fb0
--- /dev/null
+++ b/membership/static/font-awesome/less/stacked.less
@@ -0,0 +1,20 @@
+// Stacked Icons
+// -------------------------
+
+.@{fa-css-prefix}-stack {
+ position: relative;
+ display: inline-block;
+ width: 2em;
+ height: 2em;
+ line-height: 2em;
+ vertical-align: middle;
+}
+.@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
+ position: absolute;
+ left: 0;
+ width: 100%;
+ text-align: center;
+}
+.@{fa-css-prefix}-stack-1x { line-height: inherit; }
+.@{fa-css-prefix}-stack-2x { font-size: 2em; }
+.@{fa-css-prefix}-inverse { color: @fa-inverse; }
diff --git a/membership/static/font-awesome/less/variables.less b/membership/static/font-awesome/less/variables.less
new file mode 100755
index 0000000..8118e8f
--- /dev/null
+++ b/membership/static/font-awesome/less/variables.less
@@ -0,0 +1,735 @@
+// Variables
+// --------------------------
+
+@fa-font-path: "../fonts";
+@fa-font-size-base: 14px;
+@fa-line-height-base: 1;
+//@fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.6.1/fonts"; // for referencing Bootstrap CDN font files directly
+@fa-css-prefix: fa;
+@fa-version: "4.6.1";
+@fa-border-color: #eee;
+@fa-inverse: #fff;
+@fa-li-width: (30em / 14);
+
+@fa-var-500px: "\f26e";
+@fa-var-adjust: "\f042";
+@fa-var-adn: "\f170";
+@fa-var-align-center: "\f037";
+@fa-var-align-justify: "\f039";
+@fa-var-align-left: "\f036";
+@fa-var-align-right: "\f038";
+@fa-var-amazon: "\f270";
+@fa-var-ambulance: "\f0f9";
+@fa-var-american-sign-language-interpreting: "\f2a3";
+@fa-var-anchor: "\f13d";
+@fa-var-android: "\f17b";
+@fa-var-angellist: "\f209";
+@fa-var-angle-double-down: "\f103";
+@fa-var-angle-double-left: "\f100";
+@fa-var-angle-double-right: "\f101";
+@fa-var-angle-double-up: "\f102";
+@fa-var-angle-down: "\f107";
+@fa-var-angle-left: "\f104";
+@fa-var-angle-right: "\f105";
+@fa-var-angle-up: "\f106";
+@fa-var-apple: "\f179";
+@fa-var-archive: "\f187";
+@fa-var-area-chart: "\f1fe";
+@fa-var-arrow-circle-down: "\f0ab";
+@fa-var-arrow-circle-left: "\f0a8";
+@fa-var-arrow-circle-o-down: "\f01a";
+@fa-var-arrow-circle-o-left: "\f190";
+@fa-var-arrow-circle-o-right: "\f18e";
+@fa-var-arrow-circle-o-up: "\f01b";
+@fa-var-arrow-circle-right: "\f0a9";
+@fa-var-arrow-circle-up: "\f0aa";
+@fa-var-arrow-down: "\f063";
+@fa-var-arrow-left: "\f060";
+@fa-var-arrow-right: "\f061";
+@fa-var-arrow-up: "\f062";
+@fa-var-arrows: "\f047";
+@fa-var-arrows-alt: "\f0b2";
+@fa-var-arrows-h: "\f07e";
+@fa-var-arrows-v: "\f07d";
+@fa-var-asl-interpreting: "\f2a3";
+@fa-var-assistive-listening-systems: "\f2a2";
+@fa-var-asterisk: "\f069";
+@fa-var-at: "\f1fa";
+@fa-var-audio-description: "\f29e";
+@fa-var-automobile: "\f1b9";
+@fa-var-backward: "\f04a";
+@fa-var-balance-scale: "\f24e";
+@fa-var-ban: "\f05e";
+@fa-var-bank: "\f19c";
+@fa-var-bar-chart: "\f080";
+@fa-var-bar-chart-o: "\f080";
+@fa-var-barcode: "\f02a";
+@fa-var-bars: "\f0c9";
+@fa-var-battery-0: "\f244";
+@fa-var-battery-1: "\f243";
+@fa-var-battery-2: "\f242";
+@fa-var-battery-3: "\f241";
+@fa-var-battery-4: "\f240";
+@fa-var-battery-empty: "\f244";
+@fa-var-battery-full: "\f240";
+@fa-var-battery-half: "\f242";
+@fa-var-battery-quarter: "\f243";
+@fa-var-battery-three-quarters: "\f241";
+@fa-var-bed: "\f236";
+@fa-var-beer: "\f0fc";
+@fa-var-behance: "\f1b4";
+@fa-var-behance-square: "\f1b5";
+@fa-var-bell: "\f0f3";
+@fa-var-bell-o: "\f0a2";
+@fa-var-bell-slash: "\f1f6";
+@fa-var-bell-slash-o: "\f1f7";
+@fa-var-bicycle: "\f206";
+@fa-var-binoculars: "\f1e5";
+@fa-var-birthday-cake: "\f1fd";
+@fa-var-bitbucket: "\f171";
+@fa-var-bitbucket-square: "\f172";
+@fa-var-bitcoin: "\f15a";
+@fa-var-black-tie: "\f27e";
+@fa-var-blind: "\f29d";
+@fa-var-bluetooth: "\f293";
+@fa-var-bluetooth-b: "\f294";
+@fa-var-bold: "\f032";
+@fa-var-bolt: "\f0e7";
+@fa-var-bomb: "\f1e2";
+@fa-var-book: "\f02d";
+@fa-var-bookmark: "\f02e";
+@fa-var-bookmark-o: "\f097";
+@fa-var-braille: "\f2a1";
+@fa-var-briefcase: "\f0b1";
+@fa-var-btc: "\f15a";
+@fa-var-bug: "\f188";
+@fa-var-building: "\f1ad";
+@fa-var-building-o: "\f0f7";
+@fa-var-bullhorn: "\f0a1";
+@fa-var-bullseye: "\f140";
+@fa-var-bus: "\f207";
+@fa-var-buysellads: "\f20d";
+@fa-var-cab: "\f1ba";
+@fa-var-calculator: "\f1ec";
+@fa-var-calendar: "\f073";
+@fa-var-calendar-check-o: "\f274";
+@fa-var-calendar-minus-o: "\f272";
+@fa-var-calendar-o: "\f133";
+@fa-var-calendar-plus-o: "\f271";
+@fa-var-calendar-times-o: "\f273";
+@fa-var-camera: "\f030";
+@fa-var-camera-retro: "\f083";
+@fa-var-car: "\f1b9";
+@fa-var-caret-down: "\f0d7";
+@fa-var-caret-left: "\f0d9";
+@fa-var-caret-right: "\f0da";
+@fa-var-caret-square-o-down: "\f150";
+@fa-var-caret-square-o-left: "\f191";
+@fa-var-caret-square-o-right: "\f152";
+@fa-var-caret-square-o-up: "\f151";
+@fa-var-caret-up: "\f0d8";
+@fa-var-cart-arrow-down: "\f218";
+@fa-var-cart-plus: "\f217";
+@fa-var-cc: "\f20a";
+@fa-var-cc-amex: "\f1f3";
+@fa-var-cc-diners-club: "\f24c";
+@fa-var-cc-discover: "\f1f2";
+@fa-var-cc-jcb: "\f24b";
+@fa-var-cc-mastercard: "\f1f1";
+@fa-var-cc-paypal: "\f1f4";
+@fa-var-cc-stripe: "\f1f5";
+@fa-var-cc-visa: "\f1f0";
+@fa-var-certificate: "\f0a3";
+@fa-var-chain: "\f0c1";
+@fa-var-chain-broken: "\f127";
+@fa-var-check: "\f00c";
+@fa-var-check-circle: "\f058";
+@fa-var-check-circle-o: "\f05d";
+@fa-var-check-square: "\f14a";
+@fa-var-check-square-o: "\f046";
+@fa-var-chevron-circle-down: "\f13a";
+@fa-var-chevron-circle-left: "\f137";
+@fa-var-chevron-circle-right: "\f138";
+@fa-var-chevron-circle-up: "\f139";
+@fa-var-chevron-down: "\f078";
+@fa-var-chevron-left: "\f053";
+@fa-var-chevron-right: "\f054";
+@fa-var-chevron-up: "\f077";
+@fa-var-child: "\f1ae";
+@fa-var-chrome: "\f268";
+@fa-var-circle: "\f111";
+@fa-var-circle-o: "\f10c";
+@fa-var-circle-o-notch: "\f1ce";
+@fa-var-circle-thin: "\f1db";
+@fa-var-clipboard: "\f0ea";
+@fa-var-clock-o: "\f017";
+@fa-var-clone: "\f24d";
+@fa-var-close: "\f00d";
+@fa-var-cloud: "\f0c2";
+@fa-var-cloud-download: "\f0ed";
+@fa-var-cloud-upload: "\f0ee";
+@fa-var-cny: "\f157";
+@fa-var-code: "\f121";
+@fa-var-code-fork: "\f126";
+@fa-var-codepen: "\f1cb";
+@fa-var-codiepie: "\f284";
+@fa-var-coffee: "\f0f4";
+@fa-var-cog: "\f013";
+@fa-var-cogs: "\f085";
+@fa-var-columns: "\f0db";
+@fa-var-comment: "\f075";
+@fa-var-comment-o: "\f0e5";
+@fa-var-commenting: "\f27a";
+@fa-var-commenting-o: "\f27b";
+@fa-var-comments: "\f086";
+@fa-var-comments-o: "\f0e6";
+@fa-var-compass: "\f14e";
+@fa-var-compress: "\f066";
+@fa-var-connectdevelop: "\f20e";
+@fa-var-contao: "\f26d";
+@fa-var-copy: "\f0c5";
+@fa-var-copyright: "\f1f9";
+@fa-var-creative-commons: "\f25e";
+@fa-var-credit-card: "\f09d";
+@fa-var-credit-card-alt: "\f283";
+@fa-var-crop: "\f125";
+@fa-var-crosshairs: "\f05b";
+@fa-var-css3: "\f13c";
+@fa-var-cube: "\f1b2";
+@fa-var-cubes: "\f1b3";
+@fa-var-cut: "\f0c4";
+@fa-var-cutlery: "\f0f5";
+@fa-var-dashboard: "\f0e4";
+@fa-var-dashcube: "\f210";
+@fa-var-database: "\f1c0";
+@fa-var-deaf: "\f2a4";
+@fa-var-deafness: "\f2a4";
+@fa-var-dedent: "\f03b";
+@fa-var-delicious: "\f1a5";
+@fa-var-desktop: "\f108";
+@fa-var-deviantart: "\f1bd";
+@fa-var-diamond: "\f219";
+@fa-var-digg: "\f1a6";
+@fa-var-dollar: "\f155";
+@fa-var-dot-circle-o: "\f192";
+@fa-var-download: "\f019";
+@fa-var-dribbble: "\f17d";
+@fa-var-dropbox: "\f16b";
+@fa-var-drupal: "\f1a9";
+@fa-var-edge: "\f282";
+@fa-var-edit: "\f044";
+@fa-var-eject: "\f052";
+@fa-var-ellipsis-h: "\f141";
+@fa-var-ellipsis-v: "\f142";
+@fa-var-empire: "\f1d1";
+@fa-var-envelope: "\f0e0";
+@fa-var-envelope-o: "\f003";
+@fa-var-envelope-square: "\f199";
+@fa-var-envira: "\f299";
+@fa-var-eraser: "\f12d";
+@fa-var-eur: "\f153";
+@fa-var-euro: "\f153";
+@fa-var-exchange: "\f0ec";
+@fa-var-exclamation: "\f12a";
+@fa-var-exclamation-circle: "\f06a";
+@fa-var-exclamation-triangle: "\f071";
+@fa-var-expand: "\f065";
+@fa-var-expeditedssl: "\f23e";
+@fa-var-external-link: "\f08e";
+@fa-var-external-link-square: "\f14c";
+@fa-var-eye: "\f06e";
+@fa-var-eye-slash: "\f070";
+@fa-var-eyedropper: "\f1fb";
+@fa-var-facebook: "\f09a";
+@fa-var-facebook-f: "\f09a";
+@fa-var-facebook-official: "\f230";
+@fa-var-facebook-square: "\f082";
+@fa-var-fast-backward: "\f049";
+@fa-var-fast-forward: "\f050";
+@fa-var-fax: "\f1ac";
+@fa-var-feed: "\f09e";
+@fa-var-female: "\f182";
+@fa-var-fighter-jet: "\f0fb";
+@fa-var-file: "\f15b";
+@fa-var-file-archive-o: "\f1c6";
+@fa-var-file-audio-o: "\f1c7";
+@fa-var-file-code-o: "\f1c9";
+@fa-var-file-excel-o: "\f1c3";
+@fa-var-file-image-o: "\f1c5";
+@fa-var-file-movie-o: "\f1c8";
+@fa-var-file-o: "\f016";
+@fa-var-file-pdf-o: "\f1c1";
+@fa-var-file-photo-o: "\f1c5";
+@fa-var-file-picture-o: "\f1c5";
+@fa-var-file-powerpoint-o: "\f1c4";
+@fa-var-file-sound-o: "\f1c7";
+@fa-var-file-text: "\f15c";
+@fa-var-file-text-o: "\f0f6";
+@fa-var-file-video-o: "\f1c8";
+@fa-var-file-word-o: "\f1c2";
+@fa-var-file-zip-o: "\f1c6";
+@fa-var-files-o: "\f0c5";
+@fa-var-film: "\f008";
+@fa-var-filter: "\f0b0";
+@fa-var-fire: "\f06d";
+@fa-var-fire-extinguisher: "\f134";
+@fa-var-firefox: "\f269";
+@fa-var-flag: "\f024";
+@fa-var-flag-checkered: "\f11e";
+@fa-var-flag-o: "\f11d";
+@fa-var-flash: "\f0e7";
+@fa-var-flask: "\f0c3";
+@fa-var-flickr: "\f16e";
+@fa-var-floppy-o: "\f0c7";
+@fa-var-folder: "\f07b";
+@fa-var-folder-o: "\f114";
+@fa-var-folder-open: "\f07c";
+@fa-var-folder-open-o: "\f115";
+@fa-var-font: "\f031";
+@fa-var-fonticons: "\f280";
+@fa-var-fort-awesome: "\f286";
+@fa-var-forumbee: "\f211";
+@fa-var-forward: "\f04e";
+@fa-var-foursquare: "\f180";
+@fa-var-frown-o: "\f119";
+@fa-var-futbol-o: "\f1e3";
+@fa-var-gamepad: "\f11b";
+@fa-var-gavel: "\f0e3";
+@fa-var-gbp: "\f154";
+@fa-var-ge: "\f1d1";
+@fa-var-gear: "\f013";
+@fa-var-gears: "\f085";
+@fa-var-genderless: "\f22d";
+@fa-var-get-pocket: "\f265";
+@fa-var-gg: "\f260";
+@fa-var-gg-circle: "\f261";
+@fa-var-gift: "\f06b";
+@fa-var-git: "\f1d3";
+@fa-var-git-square: "\f1d2";
+@fa-var-github: "\f09b";
+@fa-var-github-alt: "\f113";
+@fa-var-github-square: "\f092";
+@fa-var-gitlab: "\f296";
+@fa-var-gittip: "\f184";
+@fa-var-glass: "\f000";
+@fa-var-glide: "\f2a5";
+@fa-var-glide-g: "\f2a6";
+@fa-var-globe: "\f0ac";
+@fa-var-google: "\f1a0";
+@fa-var-google-plus: "\f0d5";
+@fa-var-google-plus-square: "\f0d4";
+@fa-var-google-wallet: "\f1ee";
+@fa-var-graduation-cap: "\f19d";
+@fa-var-gratipay: "\f184";
+@fa-var-group: "\f0c0";
+@fa-var-h-square: "\f0fd";
+@fa-var-hacker-news: "\f1d4";
+@fa-var-hand-grab-o: "\f255";
+@fa-var-hand-lizard-o: "\f258";
+@fa-var-hand-o-down: "\f0a7";
+@fa-var-hand-o-left: "\f0a5";
+@fa-var-hand-o-right: "\f0a4";
+@fa-var-hand-o-up: "\f0a6";
+@fa-var-hand-paper-o: "\f256";
+@fa-var-hand-peace-o: "\f25b";
+@fa-var-hand-pointer-o: "\f25a";
+@fa-var-hand-rock-o: "\f255";
+@fa-var-hand-scissors-o: "\f257";
+@fa-var-hand-spock-o: "\f259";
+@fa-var-hand-stop-o: "\f256";
+@fa-var-hard-of-hearing: "\f2a4";
+@fa-var-hashtag: "\f292";
+@fa-var-hdd-o: "\f0a0";
+@fa-var-header: "\f1dc";
+@fa-var-headphones: "\f025";
+@fa-var-heart: "\f004";
+@fa-var-heart-o: "\f08a";
+@fa-var-heartbeat: "\f21e";
+@fa-var-history: "\f1da";
+@fa-var-home: "\f015";
+@fa-var-hospital-o: "\f0f8";
+@fa-var-hotel: "\f236";
+@fa-var-hourglass: "\f254";
+@fa-var-hourglass-1: "\f251";
+@fa-var-hourglass-2: "\f252";
+@fa-var-hourglass-3: "\f253";
+@fa-var-hourglass-end: "\f253";
+@fa-var-hourglass-half: "\f252";
+@fa-var-hourglass-o: "\f250";
+@fa-var-hourglass-start: "\f251";
+@fa-var-houzz: "\f27c";
+@fa-var-html5: "\f13b";
+@fa-var-i-cursor: "\f246";
+@fa-var-ils: "\f20b";
+@fa-var-image: "\f03e";
+@fa-var-inbox: "\f01c";
+@fa-var-indent: "\f03c";
+@fa-var-industry: "\f275";
+@fa-var-info: "\f129";
+@fa-var-info-circle: "\f05a";
+@fa-var-inr: "\f156";
+@fa-var-instagram: "\f16d";
+@fa-var-institution: "\f19c";
+@fa-var-internet-explorer: "\f26b";
+@fa-var-intersex: "\f224";
+@fa-var-ioxhost: "\f208";
+@fa-var-italic: "\f033";
+@fa-var-joomla: "\f1aa";
+@fa-var-jpy: "\f157";
+@fa-var-jsfiddle: "\f1cc";
+@fa-var-key: "\f084";
+@fa-var-keyboard-o: "\f11c";
+@fa-var-krw: "\f159";
+@fa-var-language: "\f1ab";
+@fa-var-laptop: "\f109";
+@fa-var-lastfm: "\f202";
+@fa-var-lastfm-square: "\f203";
+@fa-var-leaf: "\f06c";
+@fa-var-leanpub: "\f212";
+@fa-var-legal: "\f0e3";
+@fa-var-lemon-o: "\f094";
+@fa-var-level-down: "\f149";
+@fa-var-level-up: "\f148";
+@fa-var-life-bouy: "\f1cd";
+@fa-var-life-buoy: "\f1cd";
+@fa-var-life-ring: "\f1cd";
+@fa-var-life-saver: "\f1cd";
+@fa-var-lightbulb-o: "\f0eb";
+@fa-var-line-chart: "\f201";
+@fa-var-link: "\f0c1";
+@fa-var-linkedin: "\f0e1";
+@fa-var-linkedin-square: "\f08c";
+@fa-var-linux: "\f17c";
+@fa-var-list: "\f03a";
+@fa-var-list-alt: "\f022";
+@fa-var-list-ol: "\f0cb";
+@fa-var-list-ul: "\f0ca";
+@fa-var-location-arrow: "\f124";
+@fa-var-lock: "\f023";
+@fa-var-long-arrow-down: "\f175";
+@fa-var-long-arrow-left: "\f177";
+@fa-var-long-arrow-right: "\f178";
+@fa-var-long-arrow-up: "\f176";
+@fa-var-low-vision: "\f2a8";
+@fa-var-magic: "\f0d0";
+@fa-var-magnet: "\f076";
+@fa-var-mail-forward: "\f064";
+@fa-var-mail-reply: "\f112";
+@fa-var-mail-reply-all: "\f122";
+@fa-var-male: "\f183";
+@fa-var-map: "\f279";
+@fa-var-map-marker: "\f041";
+@fa-var-map-o: "\f278";
+@fa-var-map-pin: "\f276";
+@fa-var-map-signs: "\f277";
+@fa-var-mars: "\f222";
+@fa-var-mars-double: "\f227";
+@fa-var-mars-stroke: "\f229";
+@fa-var-mars-stroke-h: "\f22b";
+@fa-var-mars-stroke-v: "\f22a";
+@fa-var-maxcdn: "\f136";
+@fa-var-meanpath: "\f20c";
+@fa-var-medium: "\f23a";
+@fa-var-medkit: "\f0fa";
+@fa-var-meh-o: "\f11a";
+@fa-var-mercury: "\f223";
+@fa-var-microphone: "\f130";
+@fa-var-microphone-slash: "\f131";
+@fa-var-minus: "\f068";
+@fa-var-minus-circle: "\f056";
+@fa-var-minus-square: "\f146";
+@fa-var-minus-square-o: "\f147";
+@fa-var-mixcloud: "\f289";
+@fa-var-mobile: "\f10b";
+@fa-var-mobile-phone: "\f10b";
+@fa-var-modx: "\f285";
+@fa-var-money: "\f0d6";
+@fa-var-moon-o: "\f186";
+@fa-var-mortar-board: "\f19d";
+@fa-var-motorcycle: "\f21c";
+@fa-var-mouse-pointer: "\f245";
+@fa-var-music: "\f001";
+@fa-var-navicon: "\f0c9";
+@fa-var-neuter: "\f22c";
+@fa-var-newspaper-o: "\f1ea";
+@fa-var-object-group: "\f247";
+@fa-var-object-ungroup: "\f248";
+@fa-var-odnoklassniki: "\f263";
+@fa-var-odnoklassniki-square: "\f264";
+@fa-var-opencart: "\f23d";
+@fa-var-openid: "\f19b";
+@fa-var-opera: "\f26a";
+@fa-var-optin-monster: "\f23c";
+@fa-var-outdent: "\f03b";
+@fa-var-pagelines: "\f18c";
+@fa-var-paint-brush: "\f1fc";
+@fa-var-paper-plane: "\f1d8";
+@fa-var-paper-plane-o: "\f1d9";
+@fa-var-paperclip: "\f0c6";
+@fa-var-paragraph: "\f1dd";
+@fa-var-paste: "\f0ea";
+@fa-var-pause: "\f04c";
+@fa-var-pause-circle: "\f28b";
+@fa-var-pause-circle-o: "\f28c";
+@fa-var-paw: "\f1b0";
+@fa-var-paypal: "\f1ed";
+@fa-var-pencil: "\f040";
+@fa-var-pencil-square: "\f14b";
+@fa-var-pencil-square-o: "\f044";
+@fa-var-percent: "\f295";
+@fa-var-phone: "\f095";
+@fa-var-phone-square: "\f098";
+@fa-var-photo: "\f03e";
+@fa-var-picture-o: "\f03e";
+@fa-var-pie-chart: "\f200";
+@fa-var-pied-piper: "\f1a7";
+@fa-var-pied-piper-alt: "\f1a8";
+@fa-var-pinterest: "\f0d2";
+@fa-var-pinterest-p: "\f231";
+@fa-var-pinterest-square: "\f0d3";
+@fa-var-plane: "\f072";
+@fa-var-play: "\f04b";
+@fa-var-play-circle: "\f144";
+@fa-var-play-circle-o: "\f01d";
+@fa-var-plug: "\f1e6";
+@fa-var-plus: "\f067";
+@fa-var-plus-circle: "\f055";
+@fa-var-plus-square: "\f0fe";
+@fa-var-plus-square-o: "\f196";
+@fa-var-power-off: "\f011";
+@fa-var-print: "\f02f";
+@fa-var-product-hunt: "\f288";
+@fa-var-puzzle-piece: "\f12e";
+@fa-var-qq: "\f1d6";
+@fa-var-qrcode: "\f029";
+@fa-var-question: "\f128";
+@fa-var-question-circle: "\f059";
+@fa-var-question-circle-o: "\f29c";
+@fa-var-quote-left: "\f10d";
+@fa-var-quote-right: "\f10e";
+@fa-var-ra: "\f1d0";
+@fa-var-random: "\f074";
+@fa-var-rebel: "\f1d0";
+@fa-var-recycle: "\f1b8";
+@fa-var-reddit: "\f1a1";
+@fa-var-reddit-alien: "\f281";
+@fa-var-reddit-square: "\f1a2";
+@fa-var-refresh: "\f021";
+@fa-var-registered: "\f25d";
+@fa-var-remove: "\f00d";
+@fa-var-renren: "\f18b";
+@fa-var-reorder: "\f0c9";
+@fa-var-repeat: "\f01e";
+@fa-var-reply: "\f112";
+@fa-var-reply-all: "\f122";
+@fa-var-retweet: "\f079";
+@fa-var-rmb: "\f157";
+@fa-var-road: "\f018";
+@fa-var-rocket: "\f135";
+@fa-var-rotate-left: "\f0e2";
+@fa-var-rotate-right: "\f01e";
+@fa-var-rouble: "\f158";
+@fa-var-rss: "\f09e";
+@fa-var-rss-square: "\f143";
+@fa-var-rub: "\f158";
+@fa-var-ruble: "\f158";
+@fa-var-rupee: "\f156";
+@fa-var-safari: "\f267";
+@fa-var-save: "\f0c7";
+@fa-var-scissors: "\f0c4";
+@fa-var-scribd: "\f28a";
+@fa-var-search: "\f002";
+@fa-var-search-minus: "\f010";
+@fa-var-search-plus: "\f00e";
+@fa-var-sellsy: "\f213";
+@fa-var-send: "\f1d8";
+@fa-var-send-o: "\f1d9";
+@fa-var-server: "\f233";
+@fa-var-share: "\f064";
+@fa-var-share-alt: "\f1e0";
+@fa-var-share-alt-square: "\f1e1";
+@fa-var-share-square: "\f14d";
+@fa-var-share-square-o: "\f045";
+@fa-var-shekel: "\f20b";
+@fa-var-sheqel: "\f20b";
+@fa-var-shield: "\f132";
+@fa-var-ship: "\f21a";
+@fa-var-shirtsinbulk: "\f214";
+@fa-var-shopping-bag: "\f290";
+@fa-var-shopping-basket: "\f291";
+@fa-var-shopping-cart: "\f07a";
+@fa-var-sign-in: "\f090";
+@fa-var-sign-language: "\f2a7";
+@fa-var-sign-out: "\f08b";
+@fa-var-signal: "\f012";
+@fa-var-signing: "\f2a7";
+@fa-var-simplybuilt: "\f215";
+@fa-var-sitemap: "\f0e8";
+@fa-var-skyatlas: "\f216";
+@fa-var-skype: "\f17e";
+@fa-var-slack: "\f198";
+@fa-var-sliders: "\f1de";
+@fa-var-slideshare: "\f1e7";
+@fa-var-smile-o: "\f118";
+@fa-var-snapchat: "\f2ab";
+@fa-var-snapchat-ghost: "\f2ac";
+@fa-var-snapchat-square: "\f2ad";
+@fa-var-soccer-ball-o: "\f1e3";
+@fa-var-sort: "\f0dc";
+@fa-var-sort-alpha-asc: "\f15d";
+@fa-var-sort-alpha-desc: "\f15e";
+@fa-var-sort-amount-asc: "\f160";
+@fa-var-sort-amount-desc: "\f161";
+@fa-var-sort-asc: "\f0de";
+@fa-var-sort-desc: "\f0dd";
+@fa-var-sort-down: "\f0dd";
+@fa-var-sort-numeric-asc: "\f162";
+@fa-var-sort-numeric-desc: "\f163";
+@fa-var-sort-up: "\f0de";
+@fa-var-soundcloud: "\f1be";
+@fa-var-space-shuttle: "\f197";
+@fa-var-spinner: "\f110";
+@fa-var-spoon: "\f1b1";
+@fa-var-spotify: "\f1bc";
+@fa-var-square: "\f0c8";
+@fa-var-square-o: "\f096";
+@fa-var-stack-exchange: "\f18d";
+@fa-var-stack-overflow: "\f16c";
+@fa-var-star: "\f005";
+@fa-var-star-half: "\f089";
+@fa-var-star-half-empty: "\f123";
+@fa-var-star-half-full: "\f123";
+@fa-var-star-half-o: "\f123";
+@fa-var-star-o: "\f006";
+@fa-var-steam: "\f1b6";
+@fa-var-steam-square: "\f1b7";
+@fa-var-step-backward: "\f048";
+@fa-var-step-forward: "\f051";
+@fa-var-stethoscope: "\f0f1";
+@fa-var-sticky-note: "\f249";
+@fa-var-sticky-note-o: "\f24a";
+@fa-var-stop: "\f04d";
+@fa-var-stop-circle: "\f28d";
+@fa-var-stop-circle-o: "\f28e";
+@fa-var-street-view: "\f21d";
+@fa-var-strikethrough: "\f0cc";
+@fa-var-stumbleupon: "\f1a4";
+@fa-var-stumbleupon-circle: "\f1a3";
+@fa-var-subscript: "\f12c";
+@fa-var-subway: "\f239";
+@fa-var-suitcase: "\f0f2";
+@fa-var-sun-o: "\f185";
+@fa-var-superscript: "\f12b";
+@fa-var-support: "\f1cd";
+@fa-var-table: "\f0ce";
+@fa-var-tablet: "\f10a";
+@fa-var-tachometer: "\f0e4";
+@fa-var-tag: "\f02b";
+@fa-var-tags: "\f02c";
+@fa-var-tasks: "\f0ae";
+@fa-var-taxi: "\f1ba";
+@fa-var-television: "\f26c";
+@fa-var-tencent-weibo: "\f1d5";
+@fa-var-terminal: "\f120";
+@fa-var-text-height: "\f034";
+@fa-var-text-width: "\f035";
+@fa-var-th: "\f00a";
+@fa-var-th-large: "\f009";
+@fa-var-th-list: "\f00b";
+@fa-var-thumb-tack: "\f08d";
+@fa-var-thumbs-down: "\f165";
+@fa-var-thumbs-o-down: "\f088";
+@fa-var-thumbs-o-up: "\f087";
+@fa-var-thumbs-up: "\f164";
+@fa-var-ticket: "\f145";
+@fa-var-times: "\f00d";
+@fa-var-times-circle: "\f057";
+@fa-var-times-circle-o: "\f05c";
+@fa-var-tint: "\f043";
+@fa-var-toggle-down: "\f150";
+@fa-var-toggle-left: "\f191";
+@fa-var-toggle-off: "\f204";
+@fa-var-toggle-on: "\f205";
+@fa-var-toggle-right: "\f152";
+@fa-var-toggle-up: "\f151";
+@fa-var-trademark: "\f25c";
+@fa-var-train: "\f238";
+@fa-var-transgender: "\f224";
+@fa-var-transgender-alt: "\f225";
+@fa-var-trash: "\f1f8";
+@fa-var-trash-o: "\f014";
+@fa-var-tree: "\f1bb";
+@fa-var-trello: "\f181";
+@fa-var-tripadvisor: "\f262";
+@fa-var-trophy: "\f091";
+@fa-var-truck: "\f0d1";
+@fa-var-try: "\f195";
+@fa-var-tty: "\f1e4";
+@fa-var-tumblr: "\f173";
+@fa-var-tumblr-square: "\f174";
+@fa-var-turkish-lira: "\f195";
+@fa-var-tv: "\f26c";
+@fa-var-twitch: "\f1e8";
+@fa-var-twitter: "\f099";
+@fa-var-twitter-square: "\f081";
+@fa-var-umbrella: "\f0e9";
+@fa-var-underline: "\f0cd";
+@fa-var-undo: "\f0e2";
+@fa-var-universal-access: "\f29a";
+@fa-var-university: "\f19c";
+@fa-var-unlink: "\f127";
+@fa-var-unlock: "\f09c";
+@fa-var-unlock-alt: "\f13e";
+@fa-var-unsorted: "\f0dc";
+@fa-var-upload: "\f093";
+@fa-var-usb: "\f287";
+@fa-var-usd: "\f155";
+@fa-var-user: "\f007";
+@fa-var-user-md: "\f0f0";
+@fa-var-user-plus: "\f234";
+@fa-var-user-secret: "\f21b";
+@fa-var-user-times: "\f235";
+@fa-var-users: "\f0c0";
+@fa-var-venus: "\f221";
+@fa-var-venus-double: "\f226";
+@fa-var-venus-mars: "\f228";
+@fa-var-viacoin: "\f237";
+@fa-var-viadeo: "\f2a9";
+@fa-var-viadeo-square: "\f2aa";
+@fa-var-video-camera: "\f03d";
+@fa-var-vimeo: "\f27d";
+@fa-var-vimeo-square: "\f194";
+@fa-var-vine: "\f1ca";
+@fa-var-vk: "\f189";
+@fa-var-volume-control-phone: "\f2a0";
+@fa-var-volume-down: "\f027";
+@fa-var-volume-off: "\f026";
+@fa-var-volume-up: "\f028";
+@fa-var-warning: "\f071";
+@fa-var-wechat: "\f1d7";
+@fa-var-weibo: "\f18a";
+@fa-var-weixin: "\f1d7";
+@fa-var-whatsapp: "\f232";
+@fa-var-wheelchair: "\f193";
+@fa-var-wheelchair-alt: "\f29b";
+@fa-var-wifi: "\f1eb";
+@fa-var-wikipedia-w: "\f266";
+@fa-var-windows: "\f17a";
+@fa-var-won: "\f159";
+@fa-var-wordpress: "\f19a";
+@fa-var-wpbeginner: "\f297";
+@fa-var-wpforms: "\f298";
+@fa-var-wrench: "\f0ad";
+@fa-var-xing: "\f168";
+@fa-var-xing-square: "\f169";
+@fa-var-y-combinator: "\f23b";
+@fa-var-y-combinator-square: "\f1d4";
+@fa-var-yahoo: "\f19e";
+@fa-var-yc: "\f23b";
+@fa-var-yc-square: "\f1d4";
+@fa-var-yelp: "\f1e9";
+@fa-var-yen: "\f157";
+@fa-var-youtube: "\f167";
+@fa-var-youtube-play: "\f16a";
+@fa-var-youtube-square: "\f166";
+
diff --git a/membership/static/font-awesome/scss/_animated.scss b/membership/static/font-awesome/scss/_animated.scss
new file mode 100755
index 0000000..8a020db
--- /dev/null
+++ b/membership/static/font-awesome/scss/_animated.scss
@@ -0,0 +1,34 @@
+// Spinning Icons
+// --------------------------
+
+.#{$fa-css-prefix}-spin {
+ -webkit-animation: fa-spin 2s infinite linear;
+ animation: fa-spin 2s infinite linear;
+}
+
+.#{$fa-css-prefix}-pulse {
+ -webkit-animation: fa-spin 1s infinite steps(8);
+ animation: fa-spin 1s infinite steps(8);
+}
+
+@-webkit-keyframes fa-spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+}
+
+@keyframes fa-spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+}
diff --git a/membership/static/font-awesome/scss/_bordered-pulled.scss b/membership/static/font-awesome/scss/_bordered-pulled.scss
new file mode 100755
index 0000000..d4b85a0
--- /dev/null
+++ b/membership/static/font-awesome/scss/_bordered-pulled.scss
@@ -0,0 +1,25 @@
+// Bordered & Pulled
+// -------------------------
+
+.#{$fa-css-prefix}-border {
+ padding: .2em .25em .15em;
+ border: solid .08em $fa-border-color;
+ border-radius: .1em;
+}
+
+.#{$fa-css-prefix}-pull-left { float: left; }
+.#{$fa-css-prefix}-pull-right { float: right; }
+
+.#{$fa-css-prefix} {
+ &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }
+ &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }
+}
+
+/* Deprecated as of 4.4.0 */
+.pull-right { float: right; }
+.pull-left { float: left; }
+
+.#{$fa-css-prefix} {
+ &.pull-left { margin-right: .3em; }
+ &.pull-right { margin-left: .3em; }
+}
diff --git a/membership/static/font-awesome/scss/_core.scss b/membership/static/font-awesome/scss/_core.scss
new file mode 100755
index 0000000..7425ef8
--- /dev/null
+++ b/membership/static/font-awesome/scss/_core.scss
@@ -0,0 +1,12 @@
+// Base Class Definition
+// -------------------------
+
+.#{$fa-css-prefix} {
+ display: inline-block;
+ font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
+ font-size: inherit; // can't have font-size inherit on line above, so need to override
+ text-rendering: auto; // optimizelegibility throws things off #1094
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+
+}
diff --git a/membership/static/font-awesome/scss/_fixed-width.scss b/membership/static/font-awesome/scss/_fixed-width.scss
new file mode 100755
index 0000000..b221c98
--- /dev/null
+++ b/membership/static/font-awesome/scss/_fixed-width.scss
@@ -0,0 +1,6 @@
+// Fixed Width Icons
+// -------------------------
+.#{$fa-css-prefix}-fw {
+ width: (18em / 14);
+ text-align: center;
+}
diff --git a/membership/static/font-awesome/scss/_icons.scss b/membership/static/font-awesome/scss/_icons.scss
new file mode 100755
index 0000000..b64017a
--- /dev/null
+++ b/membership/static/font-awesome/scss/_icons.scss
@@ -0,0 +1,724 @@
+/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+ readers do not read off random characters that represent icons */
+
+.#{$fa-css-prefix}-glass:before { content: $fa-var-glass; }
+.#{$fa-css-prefix}-music:before { content: $fa-var-music; }
+.#{$fa-css-prefix}-search:before { content: $fa-var-search; }
+.#{$fa-css-prefix}-envelope-o:before { content: $fa-var-envelope-o; }
+.#{$fa-css-prefix}-heart:before { content: $fa-var-heart; }
+.#{$fa-css-prefix}-star:before { content: $fa-var-star; }
+.#{$fa-css-prefix}-star-o:before { content: $fa-var-star-o; }
+.#{$fa-css-prefix}-user:before { content: $fa-var-user; }
+.#{$fa-css-prefix}-film:before { content: $fa-var-film; }
+.#{$fa-css-prefix}-th-large:before { content: $fa-var-th-large; }
+.#{$fa-css-prefix}-th:before { content: $fa-var-th; }
+.#{$fa-css-prefix}-th-list:before { content: $fa-var-th-list; }
+.#{$fa-css-prefix}-check:before { content: $fa-var-check; }
+.#{$fa-css-prefix}-remove:before,
+.#{$fa-css-prefix}-close:before,
+.#{$fa-css-prefix}-times:before { content: $fa-var-times; }
+.#{$fa-css-prefix}-search-plus:before { content: $fa-var-search-plus; }
+.#{$fa-css-prefix}-search-minus:before { content: $fa-var-search-minus; }
+.#{$fa-css-prefix}-power-off:before { content: $fa-var-power-off; }
+.#{$fa-css-prefix}-signal:before { content: $fa-var-signal; }
+.#{$fa-css-prefix}-gear:before,
+.#{$fa-css-prefix}-cog:before { content: $fa-var-cog; }
+.#{$fa-css-prefix}-trash-o:before { content: $fa-var-trash-o; }
+.#{$fa-css-prefix}-home:before { content: $fa-var-home; }
+.#{$fa-css-prefix}-file-o:before { content: $fa-var-file-o; }
+.#{$fa-css-prefix}-clock-o:before { content: $fa-var-clock-o; }
+.#{$fa-css-prefix}-road:before { content: $fa-var-road; }
+.#{$fa-css-prefix}-download:before { content: $fa-var-download; }
+.#{$fa-css-prefix}-arrow-circle-o-down:before { content: $fa-var-arrow-circle-o-down; }
+.#{$fa-css-prefix}-arrow-circle-o-up:before { content: $fa-var-arrow-circle-o-up; }
+.#{$fa-css-prefix}-inbox:before { content: $fa-var-inbox; }
+.#{$fa-css-prefix}-play-circle-o:before { content: $fa-var-play-circle-o; }
+.#{$fa-css-prefix}-rotate-right:before,
+.#{$fa-css-prefix}-repeat:before { content: $fa-var-repeat; }
+.#{$fa-css-prefix}-refresh:before { content: $fa-var-refresh; }
+.#{$fa-css-prefix}-list-alt:before { content: $fa-var-list-alt; }
+.#{$fa-css-prefix}-lock:before { content: $fa-var-lock; }
+.#{$fa-css-prefix}-flag:before { content: $fa-var-flag; }
+.#{$fa-css-prefix}-headphones:before { content: $fa-var-headphones; }
+.#{$fa-css-prefix}-volume-off:before { content: $fa-var-volume-off; }
+.#{$fa-css-prefix}-volume-down:before { content: $fa-var-volume-down; }
+.#{$fa-css-prefix}-volume-up:before { content: $fa-var-volume-up; }
+.#{$fa-css-prefix}-qrcode:before { content: $fa-var-qrcode; }
+.#{$fa-css-prefix}-barcode:before { content: $fa-var-barcode; }
+.#{$fa-css-prefix}-tag:before { content: $fa-var-tag; }
+.#{$fa-css-prefix}-tags:before { content: $fa-var-tags; }
+.#{$fa-css-prefix}-book:before { content: $fa-var-book; }
+.#{$fa-css-prefix}-bookmark:before { content: $fa-var-bookmark; }
+.#{$fa-css-prefix}-print:before { content: $fa-var-print; }
+.#{$fa-css-prefix}-camera:before { content: $fa-var-camera; }
+.#{$fa-css-prefix}-font:before { content: $fa-var-font; }
+.#{$fa-css-prefix}-bold:before { content: $fa-var-bold; }
+.#{$fa-css-prefix}-italic:before { content: $fa-var-italic; }
+.#{$fa-css-prefix}-text-height:before { content: $fa-var-text-height; }
+.#{$fa-css-prefix}-text-width:before { content: $fa-var-text-width; }
+.#{$fa-css-prefix}-align-left:before { content: $fa-var-align-left; }
+.#{$fa-css-prefix}-align-center:before { content: $fa-var-align-center; }
+.#{$fa-css-prefix}-align-right:before { content: $fa-var-align-right; }
+.#{$fa-css-prefix}-align-justify:before { content: $fa-var-align-justify; }
+.#{$fa-css-prefix}-list:before { content: $fa-var-list; }
+.#{$fa-css-prefix}-dedent:before,
+.#{$fa-css-prefix}-outdent:before { content: $fa-var-outdent; }
+.#{$fa-css-prefix}-indent:before { content: $fa-var-indent; }
+.#{$fa-css-prefix}-video-camera:before { content: $fa-var-video-camera; }
+.#{$fa-css-prefix}-photo:before,
+.#{$fa-css-prefix}-image:before,
+.#{$fa-css-prefix}-picture-o:before { content: $fa-var-picture-o; }
+.#{$fa-css-prefix}-pencil:before { content: $fa-var-pencil; }
+.#{$fa-css-prefix}-map-marker:before { content: $fa-var-map-marker; }
+.#{$fa-css-prefix}-adjust:before { content: $fa-var-adjust; }
+.#{$fa-css-prefix}-tint:before { content: $fa-var-tint; }
+.#{$fa-css-prefix}-edit:before,
+.#{$fa-css-prefix}-pencil-square-o:before { content: $fa-var-pencil-square-o; }
+.#{$fa-css-prefix}-share-square-o:before { content: $fa-var-share-square-o; }
+.#{$fa-css-prefix}-check-square-o:before { content: $fa-var-check-square-o; }
+.#{$fa-css-prefix}-arrows:before { content: $fa-var-arrows; }
+.#{$fa-css-prefix}-step-backward:before { content: $fa-var-step-backward; }
+.#{$fa-css-prefix}-fast-backward:before { content: $fa-var-fast-backward; }
+.#{$fa-css-prefix}-backward:before { content: $fa-var-backward; }
+.#{$fa-css-prefix}-play:before { content: $fa-var-play; }
+.#{$fa-css-prefix}-pause:before { content: $fa-var-pause; }
+.#{$fa-css-prefix}-stop:before { content: $fa-var-stop; }
+.#{$fa-css-prefix}-forward:before { content: $fa-var-forward; }
+.#{$fa-css-prefix}-fast-forward:before { content: $fa-var-fast-forward; }
+.#{$fa-css-prefix}-step-forward:before { content: $fa-var-step-forward; }
+.#{$fa-css-prefix}-eject:before { content: $fa-var-eject; }
+.#{$fa-css-prefix}-chevron-left:before { content: $fa-var-chevron-left; }
+.#{$fa-css-prefix}-chevron-right:before { content: $fa-var-chevron-right; }
+.#{$fa-css-prefix}-plus-circle:before { content: $fa-var-plus-circle; }
+.#{$fa-css-prefix}-minus-circle:before { content: $fa-var-minus-circle; }
+.#{$fa-css-prefix}-times-circle:before { content: $fa-var-times-circle; }
+.#{$fa-css-prefix}-check-circle:before { content: $fa-var-check-circle; }
+.#{$fa-css-prefix}-question-circle:before { content: $fa-var-question-circle; }
+.#{$fa-css-prefix}-info-circle:before { content: $fa-var-info-circle; }
+.#{$fa-css-prefix}-crosshairs:before { content: $fa-var-crosshairs; }
+.#{$fa-css-prefix}-times-circle-o:before { content: $fa-var-times-circle-o; }
+.#{$fa-css-prefix}-check-circle-o:before { content: $fa-var-check-circle-o; }
+.#{$fa-css-prefix}-ban:before { content: $fa-var-ban; }
+.#{$fa-css-prefix}-arrow-left:before { content: $fa-var-arrow-left; }
+.#{$fa-css-prefix}-arrow-right:before { content: $fa-var-arrow-right; }
+.#{$fa-css-prefix}-arrow-up:before { content: $fa-var-arrow-up; }
+.#{$fa-css-prefix}-arrow-down:before { content: $fa-var-arrow-down; }
+.#{$fa-css-prefix}-mail-forward:before,
+.#{$fa-css-prefix}-share:before { content: $fa-var-share; }
+.#{$fa-css-prefix}-expand:before { content: $fa-var-expand; }
+.#{$fa-css-prefix}-compress:before { content: $fa-var-compress; }
+.#{$fa-css-prefix}-plus:before { content: $fa-var-plus; }
+.#{$fa-css-prefix}-minus:before { content: $fa-var-minus; }
+.#{$fa-css-prefix}-asterisk:before { content: $fa-var-asterisk; }
+.#{$fa-css-prefix}-exclamation-circle:before { content: $fa-var-exclamation-circle; }
+.#{$fa-css-prefix}-gift:before { content: $fa-var-gift; }
+.#{$fa-css-prefix}-leaf:before { content: $fa-var-leaf; }
+.#{$fa-css-prefix}-fire:before { content: $fa-var-fire; }
+.#{$fa-css-prefix}-eye:before { content: $fa-var-eye; }
+.#{$fa-css-prefix}-eye-slash:before { content: $fa-var-eye-slash; }
+.#{$fa-css-prefix}-warning:before,
+.#{$fa-css-prefix}-exclamation-triangle:before { content: $fa-var-exclamation-triangle; }
+.#{$fa-css-prefix}-plane:before { content: $fa-var-plane; }
+.#{$fa-css-prefix}-calendar:before { content: $fa-var-calendar; }
+.#{$fa-css-prefix}-random:before { content: $fa-var-random; }
+.#{$fa-css-prefix}-comment:before { content: $fa-var-comment; }
+.#{$fa-css-prefix}-magnet:before { content: $fa-var-magnet; }
+.#{$fa-css-prefix}-chevron-up:before { content: $fa-var-chevron-up; }
+.#{$fa-css-prefix}-chevron-down:before { content: $fa-var-chevron-down; }
+.#{$fa-css-prefix}-retweet:before { content: $fa-var-retweet; }
+.#{$fa-css-prefix}-shopping-cart:before { content: $fa-var-shopping-cart; }
+.#{$fa-css-prefix}-folder:before { content: $fa-var-folder; }
+.#{$fa-css-prefix}-folder-open:before { content: $fa-var-folder-open; }
+.#{$fa-css-prefix}-arrows-v:before { content: $fa-var-arrows-v; }
+.#{$fa-css-prefix}-arrows-h:before { content: $fa-var-arrows-h; }
+.#{$fa-css-prefix}-bar-chart-o:before,
+.#{$fa-css-prefix}-bar-chart:before { content: $fa-var-bar-chart; }
+.#{$fa-css-prefix}-twitter-square:before { content: $fa-var-twitter-square; }
+.#{$fa-css-prefix}-facebook-square:before { content: $fa-var-facebook-square; }
+.#{$fa-css-prefix}-camera-retro:before { content: $fa-var-camera-retro; }
+.#{$fa-css-prefix}-key:before { content: $fa-var-key; }
+.#{$fa-css-prefix}-gears:before,
+.#{$fa-css-prefix}-cogs:before { content: $fa-var-cogs; }
+.#{$fa-css-prefix}-comments:before { content: $fa-var-comments; }
+.#{$fa-css-prefix}-thumbs-o-up:before { content: $fa-var-thumbs-o-up; }
+.#{$fa-css-prefix}-thumbs-o-down:before { content: $fa-var-thumbs-o-down; }
+.#{$fa-css-prefix}-star-half:before { content: $fa-var-star-half; }
+.#{$fa-css-prefix}-heart-o:before { content: $fa-var-heart-o; }
+.#{$fa-css-prefix}-sign-out:before { content: $fa-var-sign-out; }
+.#{$fa-css-prefix}-linkedin-square:before { content: $fa-var-linkedin-square; }
+.#{$fa-css-prefix}-thumb-tack:before { content: $fa-var-thumb-tack; }
+.#{$fa-css-prefix}-external-link:before { content: $fa-var-external-link; }
+.#{$fa-css-prefix}-sign-in:before { content: $fa-var-sign-in; }
+.#{$fa-css-prefix}-trophy:before { content: $fa-var-trophy; }
+.#{$fa-css-prefix}-github-square:before { content: $fa-var-github-square; }
+.#{$fa-css-prefix}-upload:before { content: $fa-var-upload; }
+.#{$fa-css-prefix}-lemon-o:before { content: $fa-var-lemon-o; }
+.#{$fa-css-prefix}-phone:before { content: $fa-var-phone; }
+.#{$fa-css-prefix}-square-o:before { content: $fa-var-square-o; }
+.#{$fa-css-prefix}-bookmark-o:before { content: $fa-var-bookmark-o; }
+.#{$fa-css-prefix}-phone-square:before { content: $fa-var-phone-square; }
+.#{$fa-css-prefix}-twitter:before { content: $fa-var-twitter; }
+.#{$fa-css-prefix}-facebook-f:before,
+.#{$fa-css-prefix}-facebook:before { content: $fa-var-facebook; }
+.#{$fa-css-prefix}-github:before { content: $fa-var-github; }
+.#{$fa-css-prefix}-unlock:before { content: $fa-var-unlock; }
+.#{$fa-css-prefix}-credit-card:before { content: $fa-var-credit-card; }
+.#{$fa-css-prefix}-feed:before,
+.#{$fa-css-prefix}-rss:before { content: $fa-var-rss; }
+.#{$fa-css-prefix}-hdd-o:before { content: $fa-var-hdd-o; }
+.#{$fa-css-prefix}-bullhorn:before { content: $fa-var-bullhorn; }
+.#{$fa-css-prefix}-bell:before { content: $fa-var-bell; }
+.#{$fa-css-prefix}-certificate:before { content: $fa-var-certificate; }
+.#{$fa-css-prefix}-hand-o-right:before { content: $fa-var-hand-o-right; }
+.#{$fa-css-prefix}-hand-o-left:before { content: $fa-var-hand-o-left; }
+.#{$fa-css-prefix}-hand-o-up:before { content: $fa-var-hand-o-up; }
+.#{$fa-css-prefix}-hand-o-down:before { content: $fa-var-hand-o-down; }
+.#{$fa-css-prefix}-arrow-circle-left:before { content: $fa-var-arrow-circle-left; }
+.#{$fa-css-prefix}-arrow-circle-right:before { content: $fa-var-arrow-circle-right; }
+.#{$fa-css-prefix}-arrow-circle-up:before { content: $fa-var-arrow-circle-up; }
+.#{$fa-css-prefix}-arrow-circle-down:before { content: $fa-var-arrow-circle-down; }
+.#{$fa-css-prefix}-globe:before { content: $fa-var-globe; }
+.#{$fa-css-prefix}-wrench:before { content: $fa-var-wrench; }
+.#{$fa-css-prefix}-tasks:before { content: $fa-var-tasks; }
+.#{$fa-css-prefix}-filter:before { content: $fa-var-filter; }
+.#{$fa-css-prefix}-briefcase:before { content: $fa-var-briefcase; }
+.#{$fa-css-prefix}-arrows-alt:before { content: $fa-var-arrows-alt; }
+.#{$fa-css-prefix}-group:before,
+.#{$fa-css-prefix}-users:before { content: $fa-var-users; }
+.#{$fa-css-prefix}-chain:before,
+.#{$fa-css-prefix}-link:before { content: $fa-var-link; }
+.#{$fa-css-prefix}-cloud:before { content: $fa-var-cloud; }
+.#{$fa-css-prefix}-flask:before { content: $fa-var-flask; }
+.#{$fa-css-prefix}-cut:before,
+.#{$fa-css-prefix}-scissors:before { content: $fa-var-scissors; }
+.#{$fa-css-prefix}-copy:before,
+.#{$fa-css-prefix}-files-o:before { content: $fa-var-files-o; }
+.#{$fa-css-prefix}-paperclip:before { content: $fa-var-paperclip; }
+.#{$fa-css-prefix}-save:before,
+.#{$fa-css-prefix}-floppy-o:before { content: $fa-var-floppy-o; }
+.#{$fa-css-prefix}-square:before { content: $fa-var-square; }
+.#{$fa-css-prefix}-navicon:before,
+.#{$fa-css-prefix}-reorder:before,
+.#{$fa-css-prefix}-bars:before { content: $fa-var-bars; }
+.#{$fa-css-prefix}-list-ul:before { content: $fa-var-list-ul; }
+.#{$fa-css-prefix}-list-ol:before { content: $fa-var-list-ol; }
+.#{$fa-css-prefix}-strikethrough:before { content: $fa-var-strikethrough; }
+.#{$fa-css-prefix}-underline:before { content: $fa-var-underline; }
+.#{$fa-css-prefix}-table:before { content: $fa-var-table; }
+.#{$fa-css-prefix}-magic:before { content: $fa-var-magic; }
+.#{$fa-css-prefix}-truck:before { content: $fa-var-truck; }
+.#{$fa-css-prefix}-pinterest:before { content: $fa-var-pinterest; }
+.#{$fa-css-prefix}-pinterest-square:before { content: $fa-var-pinterest-square; }
+.#{$fa-css-prefix}-google-plus-square:before { content: $fa-var-google-plus-square; }
+.#{$fa-css-prefix}-google-plus:before { content: $fa-var-google-plus; }
+.#{$fa-css-prefix}-money:before { content: $fa-var-money; }
+.#{$fa-css-prefix}-caret-down:before { content: $fa-var-caret-down; }
+.#{$fa-css-prefix}-caret-up:before { content: $fa-var-caret-up; }
+.#{$fa-css-prefix}-caret-left:before { content: $fa-var-caret-left; }
+.#{$fa-css-prefix}-caret-right:before { content: $fa-var-caret-right; }
+.#{$fa-css-prefix}-columns:before { content: $fa-var-columns; }
+.#{$fa-css-prefix}-unsorted:before,
+.#{$fa-css-prefix}-sort:before { content: $fa-var-sort; }
+.#{$fa-css-prefix}-sort-down:before,
+.#{$fa-css-prefix}-sort-desc:before { content: $fa-var-sort-desc; }
+.#{$fa-css-prefix}-sort-up:before,
+.#{$fa-css-prefix}-sort-asc:before { content: $fa-var-sort-asc; }
+.#{$fa-css-prefix}-envelope:before { content: $fa-var-envelope; }
+.#{$fa-css-prefix}-linkedin:before { content: $fa-var-linkedin; }
+.#{$fa-css-prefix}-rotate-left:before,
+.#{$fa-css-prefix}-undo:before { content: $fa-var-undo; }
+.#{$fa-css-prefix}-legal:before,
+.#{$fa-css-prefix}-gavel:before { content: $fa-var-gavel; }
+.#{$fa-css-prefix}-dashboard:before,
+.#{$fa-css-prefix}-tachometer:before { content: $fa-var-tachometer; }
+.#{$fa-css-prefix}-comment-o:before { content: $fa-var-comment-o; }
+.#{$fa-css-prefix}-comments-o:before { content: $fa-var-comments-o; }
+.#{$fa-css-prefix}-flash:before,
+.#{$fa-css-prefix}-bolt:before { content: $fa-var-bolt; }
+.#{$fa-css-prefix}-sitemap:before { content: $fa-var-sitemap; }
+.#{$fa-css-prefix}-umbrella:before { content: $fa-var-umbrella; }
+.#{$fa-css-prefix}-paste:before,
+.#{$fa-css-prefix}-clipboard:before { content: $fa-var-clipboard; }
+.#{$fa-css-prefix}-lightbulb-o:before { content: $fa-var-lightbulb-o; }
+.#{$fa-css-prefix}-exchange:before { content: $fa-var-exchange; }
+.#{$fa-css-prefix}-cloud-download:before { content: $fa-var-cloud-download; }
+.#{$fa-css-prefix}-cloud-upload:before { content: $fa-var-cloud-upload; }
+.#{$fa-css-prefix}-user-md:before { content: $fa-var-user-md; }
+.#{$fa-css-prefix}-stethoscope:before { content: $fa-var-stethoscope; }
+.#{$fa-css-prefix}-suitcase:before { content: $fa-var-suitcase; }
+.#{$fa-css-prefix}-bell-o:before { content: $fa-var-bell-o; }
+.#{$fa-css-prefix}-coffee:before { content: $fa-var-coffee; }
+.#{$fa-css-prefix}-cutlery:before { content: $fa-var-cutlery; }
+.#{$fa-css-prefix}-file-text-o:before { content: $fa-var-file-text-o; }
+.#{$fa-css-prefix}-building-o:before { content: $fa-var-building-o; }
+.#{$fa-css-prefix}-hospital-o:before { content: $fa-var-hospital-o; }
+.#{$fa-css-prefix}-ambulance:before { content: $fa-var-ambulance; }
+.#{$fa-css-prefix}-medkit:before { content: $fa-var-medkit; }
+.#{$fa-css-prefix}-fighter-jet:before { content: $fa-var-fighter-jet; }
+.#{$fa-css-prefix}-beer:before { content: $fa-var-beer; }
+.#{$fa-css-prefix}-h-square:before { content: $fa-var-h-square; }
+.#{$fa-css-prefix}-plus-square:before { content: $fa-var-plus-square; }
+.#{$fa-css-prefix}-angle-double-left:before { content: $fa-var-angle-double-left; }
+.#{$fa-css-prefix}-angle-double-right:before { content: $fa-var-angle-double-right; }
+.#{$fa-css-prefix}-angle-double-up:before { content: $fa-var-angle-double-up; }
+.#{$fa-css-prefix}-angle-double-down:before { content: $fa-var-angle-double-down; }
+.#{$fa-css-prefix}-angle-left:before { content: $fa-var-angle-left; }
+.#{$fa-css-prefix}-angle-right:before { content: $fa-var-angle-right; }
+.#{$fa-css-prefix}-angle-up:before { content: $fa-var-angle-up; }
+.#{$fa-css-prefix}-angle-down:before { content: $fa-var-angle-down; }
+.#{$fa-css-prefix}-desktop:before { content: $fa-var-desktop; }
+.#{$fa-css-prefix}-laptop:before { content: $fa-var-laptop; }
+.#{$fa-css-prefix}-tablet:before { content: $fa-var-tablet; }
+.#{$fa-css-prefix}-mobile-phone:before,
+.#{$fa-css-prefix}-mobile:before { content: $fa-var-mobile; }
+.#{$fa-css-prefix}-circle-o:before { content: $fa-var-circle-o; }
+.#{$fa-css-prefix}-quote-left:before { content: $fa-var-quote-left; }
+.#{$fa-css-prefix}-quote-right:before { content: $fa-var-quote-right; }
+.#{$fa-css-prefix}-spinner:before { content: $fa-var-spinner; }
+.#{$fa-css-prefix}-circle:before { content: $fa-var-circle; }
+.#{$fa-css-prefix}-mail-reply:before,
+.#{$fa-css-prefix}-reply:before { content: $fa-var-reply; }
+.#{$fa-css-prefix}-github-alt:before { content: $fa-var-github-alt; }
+.#{$fa-css-prefix}-folder-o:before { content: $fa-var-folder-o; }
+.#{$fa-css-prefix}-folder-open-o:before { content: $fa-var-folder-open-o; }
+.#{$fa-css-prefix}-smile-o:before { content: $fa-var-smile-o; }
+.#{$fa-css-prefix}-frown-o:before { content: $fa-var-frown-o; }
+.#{$fa-css-prefix}-meh-o:before { content: $fa-var-meh-o; }
+.#{$fa-css-prefix}-gamepad:before { content: $fa-var-gamepad; }
+.#{$fa-css-prefix}-keyboard-o:before { content: $fa-var-keyboard-o; }
+.#{$fa-css-prefix}-flag-o:before { content: $fa-var-flag-o; }
+.#{$fa-css-prefix}-flag-checkered:before { content: $fa-var-flag-checkered; }
+.#{$fa-css-prefix}-terminal:before { content: $fa-var-terminal; }
+.#{$fa-css-prefix}-code:before { content: $fa-var-code; }
+.#{$fa-css-prefix}-mail-reply-all:before,
+.#{$fa-css-prefix}-reply-all:before { content: $fa-var-reply-all; }
+.#{$fa-css-prefix}-star-half-empty:before,
+.#{$fa-css-prefix}-star-half-full:before,
+.#{$fa-css-prefix}-star-half-o:before { content: $fa-var-star-half-o; }
+.#{$fa-css-prefix}-location-arrow:before { content: $fa-var-location-arrow; }
+.#{$fa-css-prefix}-crop:before { content: $fa-var-crop; }
+.#{$fa-css-prefix}-code-fork:before { content: $fa-var-code-fork; }
+.#{$fa-css-prefix}-unlink:before,
+.#{$fa-css-prefix}-chain-broken:before { content: $fa-var-chain-broken; }
+.#{$fa-css-prefix}-question:before { content: $fa-var-question; }
+.#{$fa-css-prefix}-info:before { content: $fa-var-info; }
+.#{$fa-css-prefix}-exclamation:before { content: $fa-var-exclamation; }
+.#{$fa-css-prefix}-superscript:before { content: $fa-var-superscript; }
+.#{$fa-css-prefix}-subscript:before { content: $fa-var-subscript; }
+.#{$fa-css-prefix}-eraser:before { content: $fa-var-eraser; }
+.#{$fa-css-prefix}-puzzle-piece:before { content: $fa-var-puzzle-piece; }
+.#{$fa-css-prefix}-microphone:before { content: $fa-var-microphone; }
+.#{$fa-css-prefix}-microphone-slash:before { content: $fa-var-microphone-slash; }
+.#{$fa-css-prefix}-shield:before { content: $fa-var-shield; }
+.#{$fa-css-prefix}-calendar-o:before { content: $fa-var-calendar-o; }
+.#{$fa-css-prefix}-fire-extinguisher:before { content: $fa-var-fire-extinguisher; }
+.#{$fa-css-prefix}-rocket:before { content: $fa-var-rocket; }
+.#{$fa-css-prefix}-maxcdn:before { content: $fa-var-maxcdn; }
+.#{$fa-css-prefix}-chevron-circle-left:before { content: $fa-var-chevron-circle-left; }
+.#{$fa-css-prefix}-chevron-circle-right:before { content: $fa-var-chevron-circle-right; }
+.#{$fa-css-prefix}-chevron-circle-up:before { content: $fa-var-chevron-circle-up; }
+.#{$fa-css-prefix}-chevron-circle-down:before { content: $fa-var-chevron-circle-down; }
+.#{$fa-css-prefix}-html5:before { content: $fa-var-html5; }
+.#{$fa-css-prefix}-css3:before { content: $fa-var-css3; }
+.#{$fa-css-prefix}-anchor:before { content: $fa-var-anchor; }
+.#{$fa-css-prefix}-unlock-alt:before { content: $fa-var-unlock-alt; }
+.#{$fa-css-prefix}-bullseye:before { content: $fa-var-bullseye; }
+.#{$fa-css-prefix}-ellipsis-h:before { content: $fa-var-ellipsis-h; }
+.#{$fa-css-prefix}-ellipsis-v:before { content: $fa-var-ellipsis-v; }
+.#{$fa-css-prefix}-rss-square:before { content: $fa-var-rss-square; }
+.#{$fa-css-prefix}-play-circle:before { content: $fa-var-play-circle; }
+.#{$fa-css-prefix}-ticket:before { content: $fa-var-ticket; }
+.#{$fa-css-prefix}-minus-square:before { content: $fa-var-minus-square; }
+.#{$fa-css-prefix}-minus-square-o:before { content: $fa-var-minus-square-o; }
+.#{$fa-css-prefix}-level-up:before { content: $fa-var-level-up; }
+.#{$fa-css-prefix}-level-down:before { content: $fa-var-level-down; }
+.#{$fa-css-prefix}-check-square:before { content: $fa-var-check-square; }
+.#{$fa-css-prefix}-pencil-square:before { content: $fa-var-pencil-square; }
+.#{$fa-css-prefix}-external-link-square:before { content: $fa-var-external-link-square; }
+.#{$fa-css-prefix}-share-square:before { content: $fa-var-share-square; }
+.#{$fa-css-prefix}-compass:before { content: $fa-var-compass; }
+.#{$fa-css-prefix}-toggle-down:before,
+.#{$fa-css-prefix}-caret-square-o-down:before { content: $fa-var-caret-square-o-down; }
+.#{$fa-css-prefix}-toggle-up:before,
+.#{$fa-css-prefix}-caret-square-o-up:before { content: $fa-var-caret-square-o-up; }
+.#{$fa-css-prefix}-toggle-right:before,
+.#{$fa-css-prefix}-caret-square-o-right:before { content: $fa-var-caret-square-o-right; }
+.#{$fa-css-prefix}-euro:before,
+.#{$fa-css-prefix}-eur:before { content: $fa-var-eur; }
+.#{$fa-css-prefix}-gbp:before { content: $fa-var-gbp; }
+.#{$fa-css-prefix}-dollar:before,
+.#{$fa-css-prefix}-usd:before { content: $fa-var-usd; }
+.#{$fa-css-prefix}-rupee:before,
+.#{$fa-css-prefix}-inr:before { content: $fa-var-inr; }
+.#{$fa-css-prefix}-cny:before,
+.#{$fa-css-prefix}-rmb:before,
+.#{$fa-css-prefix}-yen:before,
+.#{$fa-css-prefix}-jpy:before { content: $fa-var-jpy; }
+.#{$fa-css-prefix}-ruble:before,
+.#{$fa-css-prefix}-rouble:before,
+.#{$fa-css-prefix}-rub:before { content: $fa-var-rub; }
+.#{$fa-css-prefix}-won:before,
+.#{$fa-css-prefix}-krw:before { content: $fa-var-krw; }
+.#{$fa-css-prefix}-bitcoin:before,
+.#{$fa-css-prefix}-btc:before { content: $fa-var-btc; }
+.#{$fa-css-prefix}-file:before { content: $fa-var-file; }
+.#{$fa-css-prefix}-file-text:before { content: $fa-var-file-text; }
+.#{$fa-css-prefix}-sort-alpha-asc:before { content: $fa-var-sort-alpha-asc; }
+.#{$fa-css-prefix}-sort-alpha-desc:before { content: $fa-var-sort-alpha-desc; }
+.#{$fa-css-prefix}-sort-amount-asc:before { content: $fa-var-sort-amount-asc; }
+.#{$fa-css-prefix}-sort-amount-desc:before { content: $fa-var-sort-amount-desc; }
+.#{$fa-css-prefix}-sort-numeric-asc:before { content: $fa-var-sort-numeric-asc; }
+.#{$fa-css-prefix}-sort-numeric-desc:before { content: $fa-var-sort-numeric-desc; }
+.#{$fa-css-prefix}-thumbs-up:before { content: $fa-var-thumbs-up; }
+.#{$fa-css-prefix}-thumbs-down:before { content: $fa-var-thumbs-down; }
+.#{$fa-css-prefix}-youtube-square:before { content: $fa-var-youtube-square; }
+.#{$fa-css-prefix}-youtube:before { content: $fa-var-youtube; }
+.#{$fa-css-prefix}-xing:before { content: $fa-var-xing; }
+.#{$fa-css-prefix}-xing-square:before { content: $fa-var-xing-square; }
+.#{$fa-css-prefix}-youtube-play:before { content: $fa-var-youtube-play; }
+.#{$fa-css-prefix}-dropbox:before { content: $fa-var-dropbox; }
+.#{$fa-css-prefix}-stack-overflow:before { content: $fa-var-stack-overflow; }
+.#{$fa-css-prefix}-instagram:before { content: $fa-var-instagram; }
+.#{$fa-css-prefix}-flickr:before { content: $fa-var-flickr; }
+.#{$fa-css-prefix}-adn:before { content: $fa-var-adn; }
+.#{$fa-css-prefix}-bitbucket:before { content: $fa-var-bitbucket; }
+.#{$fa-css-prefix}-bitbucket-square:before { content: $fa-var-bitbucket-square; }
+.#{$fa-css-prefix}-tumblr:before { content: $fa-var-tumblr; }
+.#{$fa-css-prefix}-tumblr-square:before { content: $fa-var-tumblr-square; }
+.#{$fa-css-prefix}-long-arrow-down:before { content: $fa-var-long-arrow-down; }
+.#{$fa-css-prefix}-long-arrow-up:before { content: $fa-var-long-arrow-up; }
+.#{$fa-css-prefix}-long-arrow-left:before { content: $fa-var-long-arrow-left; }
+.#{$fa-css-prefix}-long-arrow-right:before { content: $fa-var-long-arrow-right; }
+.#{$fa-css-prefix}-apple:before { content: $fa-var-apple; }
+.#{$fa-css-prefix}-windows:before { content: $fa-var-windows; }
+.#{$fa-css-prefix}-android:before { content: $fa-var-android; }
+.#{$fa-css-prefix}-linux:before { content: $fa-var-linux; }
+.#{$fa-css-prefix}-dribbble:before { content: $fa-var-dribbble; }
+.#{$fa-css-prefix}-skype:before { content: $fa-var-skype; }
+.#{$fa-css-prefix}-foursquare:before { content: $fa-var-foursquare; }
+.#{$fa-css-prefix}-trello:before { content: $fa-var-trello; }
+.#{$fa-css-prefix}-female:before { content: $fa-var-female; }
+.#{$fa-css-prefix}-male:before { content: $fa-var-male; }
+.#{$fa-css-prefix}-gittip:before,
+.#{$fa-css-prefix}-gratipay:before { content: $fa-var-gratipay; }
+.#{$fa-css-prefix}-sun-o:before { content: $fa-var-sun-o; }
+.#{$fa-css-prefix}-moon-o:before { content: $fa-var-moon-o; }
+.#{$fa-css-prefix}-archive:before { content: $fa-var-archive; }
+.#{$fa-css-prefix}-bug:before { content: $fa-var-bug; }
+.#{$fa-css-prefix}-vk:before { content: $fa-var-vk; }
+.#{$fa-css-prefix}-weibo:before { content: $fa-var-weibo; }
+.#{$fa-css-prefix}-renren:before { content: $fa-var-renren; }
+.#{$fa-css-prefix}-pagelines:before { content: $fa-var-pagelines; }
+.#{$fa-css-prefix}-stack-exchange:before { content: $fa-var-stack-exchange; }
+.#{$fa-css-prefix}-arrow-circle-o-right:before { content: $fa-var-arrow-circle-o-right; }
+.#{$fa-css-prefix}-arrow-circle-o-left:before { content: $fa-var-arrow-circle-o-left; }
+.#{$fa-css-prefix}-toggle-left:before,
+.#{$fa-css-prefix}-caret-square-o-left:before { content: $fa-var-caret-square-o-left; }
+.#{$fa-css-prefix}-dot-circle-o:before { content: $fa-var-dot-circle-o; }
+.#{$fa-css-prefix}-wheelchair:before { content: $fa-var-wheelchair; }
+.#{$fa-css-prefix}-vimeo-square:before { content: $fa-var-vimeo-square; }
+.#{$fa-css-prefix}-turkish-lira:before,
+.#{$fa-css-prefix}-try:before { content: $fa-var-try; }
+.#{$fa-css-prefix}-plus-square-o:before { content: $fa-var-plus-square-o; }
+.#{$fa-css-prefix}-space-shuttle:before { content: $fa-var-space-shuttle; }
+.#{$fa-css-prefix}-slack:before { content: $fa-var-slack; }
+.#{$fa-css-prefix}-envelope-square:before { content: $fa-var-envelope-square; }
+.#{$fa-css-prefix}-wordpress:before { content: $fa-var-wordpress; }
+.#{$fa-css-prefix}-openid:before { content: $fa-var-openid; }
+.#{$fa-css-prefix}-institution:before,
+.#{$fa-css-prefix}-bank:before,
+.#{$fa-css-prefix}-university:before { content: $fa-var-university; }
+.#{$fa-css-prefix}-mortar-board:before,
+.#{$fa-css-prefix}-graduation-cap:before { content: $fa-var-graduation-cap; }
+.#{$fa-css-prefix}-yahoo:before { content: $fa-var-yahoo; }
+.#{$fa-css-prefix}-google:before { content: $fa-var-google; }
+.#{$fa-css-prefix}-reddit:before { content: $fa-var-reddit; }
+.#{$fa-css-prefix}-reddit-square:before { content: $fa-var-reddit-square; }
+.#{$fa-css-prefix}-stumbleupon-circle:before { content: $fa-var-stumbleupon-circle; }
+.#{$fa-css-prefix}-stumbleupon:before { content: $fa-var-stumbleupon; }
+.#{$fa-css-prefix}-delicious:before { content: $fa-var-delicious; }
+.#{$fa-css-prefix}-digg:before { content: $fa-var-digg; }
+.#{$fa-css-prefix}-pied-piper:before { content: $fa-var-pied-piper; }
+.#{$fa-css-prefix}-pied-piper-alt:before { content: $fa-var-pied-piper-alt; }
+.#{$fa-css-prefix}-drupal:before { content: $fa-var-drupal; }
+.#{$fa-css-prefix}-joomla:before { content: $fa-var-joomla; }
+.#{$fa-css-prefix}-language:before { content: $fa-var-language; }
+.#{$fa-css-prefix}-fax:before { content: $fa-var-fax; }
+.#{$fa-css-prefix}-building:before { content: $fa-var-building; }
+.#{$fa-css-prefix}-child:before { content: $fa-var-child; }
+.#{$fa-css-prefix}-paw:before { content: $fa-var-paw; }
+.#{$fa-css-prefix}-spoon:before { content: $fa-var-spoon; }
+.#{$fa-css-prefix}-cube:before { content: $fa-var-cube; }
+.#{$fa-css-prefix}-cubes:before { content: $fa-var-cubes; }
+.#{$fa-css-prefix}-behance:before { content: $fa-var-behance; }
+.#{$fa-css-prefix}-behance-square:before { content: $fa-var-behance-square; }
+.#{$fa-css-prefix}-steam:before { content: $fa-var-steam; }
+.#{$fa-css-prefix}-steam-square:before { content: $fa-var-steam-square; }
+.#{$fa-css-prefix}-recycle:before { content: $fa-var-recycle; }
+.#{$fa-css-prefix}-automobile:before,
+.#{$fa-css-prefix}-car:before { content: $fa-var-car; }
+.#{$fa-css-prefix}-cab:before,
+.#{$fa-css-prefix}-taxi:before { content: $fa-var-taxi; }
+.#{$fa-css-prefix}-tree:before { content: $fa-var-tree; }
+.#{$fa-css-prefix}-spotify:before { content: $fa-var-spotify; }
+.#{$fa-css-prefix}-deviantart:before { content: $fa-var-deviantart; }
+.#{$fa-css-prefix}-soundcloud:before { content: $fa-var-soundcloud; }
+.#{$fa-css-prefix}-database:before { content: $fa-var-database; }
+.#{$fa-css-prefix}-file-pdf-o:before { content: $fa-var-file-pdf-o; }
+.#{$fa-css-prefix}-file-word-o:before { content: $fa-var-file-word-o; }
+.#{$fa-css-prefix}-file-excel-o:before { content: $fa-var-file-excel-o; }
+.#{$fa-css-prefix}-file-powerpoint-o:before { content: $fa-var-file-powerpoint-o; }
+.#{$fa-css-prefix}-file-photo-o:before,
+.#{$fa-css-prefix}-file-picture-o:before,
+.#{$fa-css-prefix}-file-image-o:before { content: $fa-var-file-image-o; }
+.#{$fa-css-prefix}-file-zip-o:before,
+.#{$fa-css-prefix}-file-archive-o:before { content: $fa-var-file-archive-o; }
+.#{$fa-css-prefix}-file-sound-o:before,
+.#{$fa-css-prefix}-file-audio-o:before { content: $fa-var-file-audio-o; }
+.#{$fa-css-prefix}-file-movie-o:before,
+.#{$fa-css-prefix}-file-video-o:before { content: $fa-var-file-video-o; }
+.#{$fa-css-prefix}-file-code-o:before { content: $fa-var-file-code-o; }
+.#{$fa-css-prefix}-vine:before { content: $fa-var-vine; }
+.#{$fa-css-prefix}-codepen:before { content: $fa-var-codepen; }
+.#{$fa-css-prefix}-jsfiddle:before { content: $fa-var-jsfiddle; }
+.#{$fa-css-prefix}-life-bouy:before,
+.#{$fa-css-prefix}-life-buoy:before,
+.#{$fa-css-prefix}-life-saver:before,
+.#{$fa-css-prefix}-support:before,
+.#{$fa-css-prefix}-life-ring:before { content: $fa-var-life-ring; }
+.#{$fa-css-prefix}-circle-o-notch:before { content: $fa-var-circle-o-notch; }
+.#{$fa-css-prefix}-ra:before,
+.#{$fa-css-prefix}-rebel:before { content: $fa-var-rebel; }
+.#{$fa-css-prefix}-ge:before,
+.#{$fa-css-prefix}-empire:before { content: $fa-var-empire; }
+.#{$fa-css-prefix}-git-square:before { content: $fa-var-git-square; }
+.#{$fa-css-prefix}-git:before { content: $fa-var-git; }
+.#{$fa-css-prefix}-y-combinator-square:before,
+.#{$fa-css-prefix}-yc-square:before,
+.#{$fa-css-prefix}-hacker-news:before { content: $fa-var-hacker-news; }
+.#{$fa-css-prefix}-tencent-weibo:before { content: $fa-var-tencent-weibo; }
+.#{$fa-css-prefix}-qq:before { content: $fa-var-qq; }
+.#{$fa-css-prefix}-wechat:before,
+.#{$fa-css-prefix}-weixin:before { content: $fa-var-weixin; }
+.#{$fa-css-prefix}-send:before,
+.#{$fa-css-prefix}-paper-plane:before { content: $fa-var-paper-plane; }
+.#{$fa-css-prefix}-send-o:before,
+.#{$fa-css-prefix}-paper-plane-o:before { content: $fa-var-paper-plane-o; }
+.#{$fa-css-prefix}-history:before { content: $fa-var-history; }
+.#{$fa-css-prefix}-circle-thin:before { content: $fa-var-circle-thin; }
+.#{$fa-css-prefix}-header:before { content: $fa-var-header; }
+.#{$fa-css-prefix}-paragraph:before { content: $fa-var-paragraph; }
+.#{$fa-css-prefix}-sliders:before { content: $fa-var-sliders; }
+.#{$fa-css-prefix}-share-alt:before { content: $fa-var-share-alt; }
+.#{$fa-css-prefix}-share-alt-square:before { content: $fa-var-share-alt-square; }
+.#{$fa-css-prefix}-bomb:before { content: $fa-var-bomb; }
+.#{$fa-css-prefix}-soccer-ball-o:before,
+.#{$fa-css-prefix}-futbol-o:before { content: $fa-var-futbol-o; }
+.#{$fa-css-prefix}-tty:before { content: $fa-var-tty; }
+.#{$fa-css-prefix}-binoculars:before { content: $fa-var-binoculars; }
+.#{$fa-css-prefix}-plug:before { content: $fa-var-plug; }
+.#{$fa-css-prefix}-slideshare:before { content: $fa-var-slideshare; }
+.#{$fa-css-prefix}-twitch:before { content: $fa-var-twitch; }
+.#{$fa-css-prefix}-yelp:before { content: $fa-var-yelp; }
+.#{$fa-css-prefix}-newspaper-o:before { content: $fa-var-newspaper-o; }
+.#{$fa-css-prefix}-wifi:before { content: $fa-var-wifi; }
+.#{$fa-css-prefix}-calculator:before { content: $fa-var-calculator; }
+.#{$fa-css-prefix}-paypal:before { content: $fa-var-paypal; }
+.#{$fa-css-prefix}-google-wallet:before { content: $fa-var-google-wallet; }
+.#{$fa-css-prefix}-cc-visa:before { content: $fa-var-cc-visa; }
+.#{$fa-css-prefix}-cc-mastercard:before { content: $fa-var-cc-mastercard; }
+.#{$fa-css-prefix}-cc-discover:before { content: $fa-var-cc-discover; }
+.#{$fa-css-prefix}-cc-amex:before { content: $fa-var-cc-amex; }
+.#{$fa-css-prefix}-cc-paypal:before { content: $fa-var-cc-paypal; }
+.#{$fa-css-prefix}-cc-stripe:before { content: $fa-var-cc-stripe; }
+.#{$fa-css-prefix}-bell-slash:before { content: $fa-var-bell-slash; }
+.#{$fa-css-prefix}-bell-slash-o:before { content: $fa-var-bell-slash-o; }
+.#{$fa-css-prefix}-trash:before { content: $fa-var-trash; }
+.#{$fa-css-prefix}-copyright:before { content: $fa-var-copyright; }
+.#{$fa-css-prefix}-at:before { content: $fa-var-at; }
+.#{$fa-css-prefix}-eyedropper:before { content: $fa-var-eyedropper; }
+.#{$fa-css-prefix}-paint-brush:before { content: $fa-var-paint-brush; }
+.#{$fa-css-prefix}-birthday-cake:before { content: $fa-var-birthday-cake; }
+.#{$fa-css-prefix}-area-chart:before { content: $fa-var-area-chart; }
+.#{$fa-css-prefix}-pie-chart:before { content: $fa-var-pie-chart; }
+.#{$fa-css-prefix}-line-chart:before { content: $fa-var-line-chart; }
+.#{$fa-css-prefix}-lastfm:before { content: $fa-var-lastfm; }
+.#{$fa-css-prefix}-lastfm-square:before { content: $fa-var-lastfm-square; }
+.#{$fa-css-prefix}-toggle-off:before { content: $fa-var-toggle-off; }
+.#{$fa-css-prefix}-toggle-on:before { content: $fa-var-toggle-on; }
+.#{$fa-css-prefix}-bicycle:before { content: $fa-var-bicycle; }
+.#{$fa-css-prefix}-bus:before { content: $fa-var-bus; }
+.#{$fa-css-prefix}-ioxhost:before { content: $fa-var-ioxhost; }
+.#{$fa-css-prefix}-angellist:before { content: $fa-var-angellist; }
+.#{$fa-css-prefix}-cc:before { content: $fa-var-cc; }
+.#{$fa-css-prefix}-shekel:before,
+.#{$fa-css-prefix}-sheqel:before,
+.#{$fa-css-prefix}-ils:before { content: $fa-var-ils; }
+.#{$fa-css-prefix}-meanpath:before { content: $fa-var-meanpath; }
+.#{$fa-css-prefix}-buysellads:before { content: $fa-var-buysellads; }
+.#{$fa-css-prefix}-connectdevelop:before { content: $fa-var-connectdevelop; }
+.#{$fa-css-prefix}-dashcube:before { content: $fa-var-dashcube; }
+.#{$fa-css-prefix}-forumbee:before { content: $fa-var-forumbee; }
+.#{$fa-css-prefix}-leanpub:before { content: $fa-var-leanpub; }
+.#{$fa-css-prefix}-sellsy:before { content: $fa-var-sellsy; }
+.#{$fa-css-prefix}-shirtsinbulk:before { content: $fa-var-shirtsinbulk; }
+.#{$fa-css-prefix}-simplybuilt:before { content: $fa-var-simplybuilt; }
+.#{$fa-css-prefix}-skyatlas:before { content: $fa-var-skyatlas; }
+.#{$fa-css-prefix}-cart-plus:before { content: $fa-var-cart-plus; }
+.#{$fa-css-prefix}-cart-arrow-down:before { content: $fa-var-cart-arrow-down; }
+.#{$fa-css-prefix}-diamond:before { content: $fa-var-diamond; }
+.#{$fa-css-prefix}-ship:before { content: $fa-var-ship; }
+.#{$fa-css-prefix}-user-secret:before { content: $fa-var-user-secret; }
+.#{$fa-css-prefix}-motorcycle:before { content: $fa-var-motorcycle; }
+.#{$fa-css-prefix}-street-view:before { content: $fa-var-street-view; }
+.#{$fa-css-prefix}-heartbeat:before { content: $fa-var-heartbeat; }
+.#{$fa-css-prefix}-venus:before { content: $fa-var-venus; }
+.#{$fa-css-prefix}-mars:before { content: $fa-var-mars; }
+.#{$fa-css-prefix}-mercury:before { content: $fa-var-mercury; }
+.#{$fa-css-prefix}-intersex:before,
+.#{$fa-css-prefix}-transgender:before { content: $fa-var-transgender; }
+.#{$fa-css-prefix}-transgender-alt:before { content: $fa-var-transgender-alt; }
+.#{$fa-css-prefix}-venus-double:before { content: $fa-var-venus-double; }
+.#{$fa-css-prefix}-mars-double:before { content: $fa-var-mars-double; }
+.#{$fa-css-prefix}-venus-mars:before { content: $fa-var-venus-mars; }
+.#{$fa-css-prefix}-mars-stroke:before { content: $fa-var-mars-stroke; }
+.#{$fa-css-prefix}-mars-stroke-v:before { content: $fa-var-mars-stroke-v; }
+.#{$fa-css-prefix}-mars-stroke-h:before { content: $fa-var-mars-stroke-h; }
+.#{$fa-css-prefix}-neuter:before { content: $fa-var-neuter; }
+.#{$fa-css-prefix}-genderless:before { content: $fa-var-genderless; }
+.#{$fa-css-prefix}-facebook-official:before { content: $fa-var-facebook-official; }
+.#{$fa-css-prefix}-pinterest-p:before { content: $fa-var-pinterest-p; }
+.#{$fa-css-prefix}-whatsapp:before { content: $fa-var-whatsapp; }
+.#{$fa-css-prefix}-server:before { content: $fa-var-server; }
+.#{$fa-css-prefix}-user-plus:before { content: $fa-var-user-plus; }
+.#{$fa-css-prefix}-user-times:before { content: $fa-var-user-times; }
+.#{$fa-css-prefix}-hotel:before,
+.#{$fa-css-prefix}-bed:before { content: $fa-var-bed; }
+.#{$fa-css-prefix}-viacoin:before { content: $fa-var-viacoin; }
+.#{$fa-css-prefix}-train:before { content: $fa-var-train; }
+.#{$fa-css-prefix}-subway:before { content: $fa-var-subway; }
+.#{$fa-css-prefix}-medium:before { content: $fa-var-medium; }
+.#{$fa-css-prefix}-yc:before,
+.#{$fa-css-prefix}-y-combinator:before { content: $fa-var-y-combinator; }
+.#{$fa-css-prefix}-optin-monster:before { content: $fa-var-optin-monster; }
+.#{$fa-css-prefix}-opencart:before { content: $fa-var-opencart; }
+.#{$fa-css-prefix}-expeditedssl:before { content: $fa-var-expeditedssl; }
+.#{$fa-css-prefix}-battery-4:before,
+.#{$fa-css-prefix}-battery-full:before { content: $fa-var-battery-full; }
+.#{$fa-css-prefix}-battery-3:before,
+.#{$fa-css-prefix}-battery-three-quarters:before { content: $fa-var-battery-three-quarters; }
+.#{$fa-css-prefix}-battery-2:before,
+.#{$fa-css-prefix}-battery-half:before { content: $fa-var-battery-half; }
+.#{$fa-css-prefix}-battery-1:before,
+.#{$fa-css-prefix}-battery-quarter:before { content: $fa-var-battery-quarter; }
+.#{$fa-css-prefix}-battery-0:before,
+.#{$fa-css-prefix}-battery-empty:before { content: $fa-var-battery-empty; }
+.#{$fa-css-prefix}-mouse-pointer:before { content: $fa-var-mouse-pointer; }
+.#{$fa-css-prefix}-i-cursor:before { content: $fa-var-i-cursor; }
+.#{$fa-css-prefix}-object-group:before { content: $fa-var-object-group; }
+.#{$fa-css-prefix}-object-ungroup:before { content: $fa-var-object-ungroup; }
+.#{$fa-css-prefix}-sticky-note:before { content: $fa-var-sticky-note; }
+.#{$fa-css-prefix}-sticky-note-o:before { content: $fa-var-sticky-note-o; }
+.#{$fa-css-prefix}-cc-jcb:before { content: $fa-var-cc-jcb; }
+.#{$fa-css-prefix}-cc-diners-club:before { content: $fa-var-cc-diners-club; }
+.#{$fa-css-prefix}-clone:before { content: $fa-var-clone; }
+.#{$fa-css-prefix}-balance-scale:before { content: $fa-var-balance-scale; }
+.#{$fa-css-prefix}-hourglass-o:before { content: $fa-var-hourglass-o; }
+.#{$fa-css-prefix}-hourglass-1:before,
+.#{$fa-css-prefix}-hourglass-start:before { content: $fa-var-hourglass-start; }
+.#{$fa-css-prefix}-hourglass-2:before,
+.#{$fa-css-prefix}-hourglass-half:before { content: $fa-var-hourglass-half; }
+.#{$fa-css-prefix}-hourglass-3:before,
+.#{$fa-css-prefix}-hourglass-end:before { content: $fa-var-hourglass-end; }
+.#{$fa-css-prefix}-hourglass:before { content: $fa-var-hourglass; }
+.#{$fa-css-prefix}-hand-grab-o:before,
+.#{$fa-css-prefix}-hand-rock-o:before { content: $fa-var-hand-rock-o; }
+.#{$fa-css-prefix}-hand-stop-o:before,
+.#{$fa-css-prefix}-hand-paper-o:before { content: $fa-var-hand-paper-o; }
+.#{$fa-css-prefix}-hand-scissors-o:before { content: $fa-var-hand-scissors-o; }
+.#{$fa-css-prefix}-hand-lizard-o:before { content: $fa-var-hand-lizard-o; }
+.#{$fa-css-prefix}-hand-spock-o:before { content: $fa-var-hand-spock-o; }
+.#{$fa-css-prefix}-hand-pointer-o:before { content: $fa-var-hand-pointer-o; }
+.#{$fa-css-prefix}-hand-peace-o:before { content: $fa-var-hand-peace-o; }
+.#{$fa-css-prefix}-trademark:before { content: $fa-var-trademark; }
+.#{$fa-css-prefix}-registered:before { content: $fa-var-registered; }
+.#{$fa-css-prefix}-creative-commons:before { content: $fa-var-creative-commons; }
+.#{$fa-css-prefix}-gg:before { content: $fa-var-gg; }
+.#{$fa-css-prefix}-gg-circle:before { content: $fa-var-gg-circle; }
+.#{$fa-css-prefix}-tripadvisor:before { content: $fa-var-tripadvisor; }
+.#{$fa-css-prefix}-odnoklassniki:before { content: $fa-var-odnoklassniki; }
+.#{$fa-css-prefix}-odnoklassniki-square:before { content: $fa-var-odnoklassniki-square; }
+.#{$fa-css-prefix}-get-pocket:before { content: $fa-var-get-pocket; }
+.#{$fa-css-prefix}-wikipedia-w:before { content: $fa-var-wikipedia-w; }
+.#{$fa-css-prefix}-safari:before { content: $fa-var-safari; }
+.#{$fa-css-prefix}-chrome:before { content: $fa-var-chrome; }
+.#{$fa-css-prefix}-firefox:before { content: $fa-var-firefox; }
+.#{$fa-css-prefix}-opera:before { content: $fa-var-opera; }
+.#{$fa-css-prefix}-internet-explorer:before { content: $fa-var-internet-explorer; }
+.#{$fa-css-prefix}-tv:before,
+.#{$fa-css-prefix}-television:before { content: $fa-var-television; }
+.#{$fa-css-prefix}-contao:before { content: $fa-var-contao; }
+.#{$fa-css-prefix}-500px:before { content: $fa-var-500px; }
+.#{$fa-css-prefix}-amazon:before { content: $fa-var-amazon; }
+.#{$fa-css-prefix}-calendar-plus-o:before { content: $fa-var-calendar-plus-o; }
+.#{$fa-css-prefix}-calendar-minus-o:before { content: $fa-var-calendar-minus-o; }
+.#{$fa-css-prefix}-calendar-times-o:before { content: $fa-var-calendar-times-o; }
+.#{$fa-css-prefix}-calendar-check-o:before { content: $fa-var-calendar-check-o; }
+.#{$fa-css-prefix}-industry:before { content: $fa-var-industry; }
+.#{$fa-css-prefix}-map-pin:before { content: $fa-var-map-pin; }
+.#{$fa-css-prefix}-map-signs:before { content: $fa-var-map-signs; }
+.#{$fa-css-prefix}-map-o:before { content: $fa-var-map-o; }
+.#{$fa-css-prefix}-map:before { content: $fa-var-map; }
+.#{$fa-css-prefix}-commenting:before { content: $fa-var-commenting; }
+.#{$fa-css-prefix}-commenting-o:before { content: $fa-var-commenting-o; }
+.#{$fa-css-prefix}-houzz:before { content: $fa-var-houzz; }
+.#{$fa-css-prefix}-vimeo:before { content: $fa-var-vimeo; }
+.#{$fa-css-prefix}-black-tie:before { content: $fa-var-black-tie; }
+.#{$fa-css-prefix}-fonticons:before { content: $fa-var-fonticons; }
+.#{$fa-css-prefix}-reddit-alien:before { content: $fa-var-reddit-alien; }
+.#{$fa-css-prefix}-edge:before { content: $fa-var-edge; }
+.#{$fa-css-prefix}-credit-card-alt:before { content: $fa-var-credit-card-alt; }
+.#{$fa-css-prefix}-codiepie:before { content: $fa-var-codiepie; }
+.#{$fa-css-prefix}-modx:before { content: $fa-var-modx; }
+.#{$fa-css-prefix}-fort-awesome:before { content: $fa-var-fort-awesome; }
+.#{$fa-css-prefix}-usb:before { content: $fa-var-usb; }
+.#{$fa-css-prefix}-product-hunt:before { content: $fa-var-product-hunt; }
+.#{$fa-css-prefix}-mixcloud:before { content: $fa-var-mixcloud; }
+.#{$fa-css-prefix}-scribd:before { content: $fa-var-scribd; }
+.#{$fa-css-prefix}-pause-circle:before { content: $fa-var-pause-circle; }
+.#{$fa-css-prefix}-pause-circle-o:before { content: $fa-var-pause-circle-o; }
+.#{$fa-css-prefix}-stop-circle:before { content: $fa-var-stop-circle; }
+.#{$fa-css-prefix}-stop-circle-o:before { content: $fa-var-stop-circle-o; }
+.#{$fa-css-prefix}-shopping-bag:before { content: $fa-var-shopping-bag; }
+.#{$fa-css-prefix}-shopping-basket:before { content: $fa-var-shopping-basket; }
+.#{$fa-css-prefix}-hashtag:before { content: $fa-var-hashtag; }
+.#{$fa-css-prefix}-bluetooth:before { content: $fa-var-bluetooth; }
+.#{$fa-css-prefix}-bluetooth-b:before { content: $fa-var-bluetooth-b; }
+.#{$fa-css-prefix}-percent:before { content: $fa-var-percent; }
+.#{$fa-css-prefix}-gitlab:before { content: $fa-var-gitlab; }
+.#{$fa-css-prefix}-wpbeginner:before { content: $fa-var-wpbeginner; }
+.#{$fa-css-prefix}-wpforms:before { content: $fa-var-wpforms; }
+.#{$fa-css-prefix}-envira:before { content: $fa-var-envira; }
+.#{$fa-css-prefix}-universal-access:before { content: $fa-var-universal-access; }
+.#{$fa-css-prefix}-wheelchair-alt:before { content: $fa-var-wheelchair-alt; }
+.#{$fa-css-prefix}-question-circle-o:before { content: $fa-var-question-circle-o; }
+.#{$fa-css-prefix}-blind:before { content: $fa-var-blind; }
+.#{$fa-css-prefix}-audio-description:before { content: $fa-var-audio-description; }
+.#{$fa-css-prefix}-volume-control-phone:before { content: $fa-var-volume-control-phone; }
+.#{$fa-css-prefix}-braille:before { content: $fa-var-braille; }
+.#{$fa-css-prefix}-assistive-listening-systems:before { content: $fa-var-assistive-listening-systems; }
+.#{$fa-css-prefix}-asl-interpreting:before,
+.#{$fa-css-prefix}-american-sign-language-interpreting:before { content: $fa-var-american-sign-language-interpreting; }
+.#{$fa-css-prefix}-deafness:before,
+.#{$fa-css-prefix}-hard-of-hearing:before,
+.#{$fa-css-prefix}-deaf:before { content: $fa-var-deaf; }
+.#{$fa-css-prefix}-glide:before { content: $fa-var-glide; }
+.#{$fa-css-prefix}-glide-g:before { content: $fa-var-glide-g; }
+.#{$fa-css-prefix}-signing:before,
+.#{$fa-css-prefix}-sign-language:before { content: $fa-var-sign-language; }
+.#{$fa-css-prefix}-low-vision:before { content: $fa-var-low-vision; }
+.#{$fa-css-prefix}-viadeo:before { content: $fa-var-viadeo; }
+.#{$fa-css-prefix}-viadeo-square:before { content: $fa-var-viadeo-square; }
+.#{$fa-css-prefix}-snapchat:before { content: $fa-var-snapchat; }
+.#{$fa-css-prefix}-snapchat-ghost:before { content: $fa-var-snapchat-ghost; }
+.#{$fa-css-prefix}-snapchat-square:before { content: $fa-var-snapchat-square; }
diff --git a/membership/static/font-awesome/scss/_larger.scss b/membership/static/font-awesome/scss/_larger.scss
new file mode 100755
index 0000000..41e9a81
--- /dev/null
+++ b/membership/static/font-awesome/scss/_larger.scss
@@ -0,0 +1,13 @@
+// Icon Sizes
+// -------------------------
+
+/* makes the font 33% larger relative to the icon container */
+.#{$fa-css-prefix}-lg {
+ font-size: (4em / 3);
+ line-height: (3em / 4);
+ vertical-align: -15%;
+}
+.#{$fa-css-prefix}-2x { font-size: 2em; }
+.#{$fa-css-prefix}-3x { font-size: 3em; }
+.#{$fa-css-prefix}-4x { font-size: 4em; }
+.#{$fa-css-prefix}-5x { font-size: 5em; }
diff --git a/membership/static/font-awesome/scss/_list.scss b/membership/static/font-awesome/scss/_list.scss
new file mode 100755
index 0000000..7d1e4d5
--- /dev/null
+++ b/membership/static/font-awesome/scss/_list.scss
@@ -0,0 +1,19 @@
+// List Icons
+// -------------------------
+
+.#{$fa-css-prefix}-ul {
+ padding-left: 0;
+ margin-left: $fa-li-width;
+ list-style-type: none;
+ > li { position: relative; }
+}
+.#{$fa-css-prefix}-li {
+ position: absolute;
+ left: -$fa-li-width;
+ width: $fa-li-width;
+ top: (2em / 14);
+ text-align: center;
+ &.#{$fa-css-prefix}-lg {
+ left: -$fa-li-width + (4em / 14);
+ }
+}
diff --git a/membership/static/font-awesome/scss/_mixins.scss b/membership/static/font-awesome/scss/_mixins.scss
new file mode 100755
index 0000000..c3bbd57
--- /dev/null
+++ b/membership/static/font-awesome/scss/_mixins.scss
@@ -0,0 +1,60 @@
+// Mixins
+// --------------------------
+
+@mixin fa-icon() {
+ display: inline-block;
+ font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
+ font-size: inherit; // can't have font-size inherit on line above, so need to override
+ text-rendering: auto; // optimizelegibility throws things off #1094
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+
+}
+
+@mixin fa-icon-rotate($degrees, $rotation) {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})";
+ -webkit-transform: rotate($degrees);
+ -ms-transform: rotate($degrees);
+ transform: rotate($degrees);
+}
+
+@mixin fa-icon-flip($horiz, $vert, $rotation) {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)";
+ -webkit-transform: scale($horiz, $vert);
+ -ms-transform: scale($horiz, $vert);
+ transform: scale($horiz, $vert);
+}
+
+
+// Only display content to screen readers. A la Bootstrap 4.
+//
+// See: http://a11yproject.com/posts/how-to-hide-content/
+
+@mixin sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0,0,0,0);
+ border: 0;
+}
+
+// Use in conjunction with .sr-only to only display content when it's focused.
+//
+// Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
+//
+// Credit: HTML5 Boilerplate
+
+@mixin sr-only-focusable {
+ &:active,
+ &:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+ }
+}
diff --git a/membership/static/font-awesome/scss/_path.scss b/membership/static/font-awesome/scss/_path.scss
new file mode 100755
index 0000000..bb457c2
--- /dev/null
+++ b/membership/static/font-awesome/scss/_path.scss
@@ -0,0 +1,15 @@
+/* FONT PATH
+ * -------------------------- */
+
+@font-face {
+ font-family: 'FontAwesome';
+ src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
+ src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
+ url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
+ url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
+ url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
+ url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
+// src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
+ font-weight: normal;
+ font-style: normal;
+}
diff --git a/membership/static/font-awesome/scss/_rotated-flipped.scss b/membership/static/font-awesome/scss/_rotated-flipped.scss
new file mode 100755
index 0000000..a3558fd
--- /dev/null
+++ b/membership/static/font-awesome/scss/_rotated-flipped.scss
@@ -0,0 +1,20 @@
+// Rotated & Flipped Icons
+// -------------------------
+
+.#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); }
+.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
+.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
+
+.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
+.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
+
+// Hook for IE8-9
+// -------------------------
+
+:root .#{$fa-css-prefix}-rotate-90,
+:root .#{$fa-css-prefix}-rotate-180,
+:root .#{$fa-css-prefix}-rotate-270,
+:root .#{$fa-css-prefix}-flip-horizontal,
+:root .#{$fa-css-prefix}-flip-vertical {
+ filter: none;
+}
diff --git a/membership/static/font-awesome/scss/_screen-reader.scss b/membership/static/font-awesome/scss/_screen-reader.scss
new file mode 100755
index 0000000..637426f
--- /dev/null
+++ b/membership/static/font-awesome/scss/_screen-reader.scss
@@ -0,0 +1,5 @@
+// Screen Readers
+// -------------------------
+
+.sr-only { @include sr-only(); }
+.sr-only-focusable { @include sr-only-focusable(); }
diff --git a/membership/static/font-awesome/scss/_stacked.scss b/membership/static/font-awesome/scss/_stacked.scss
new file mode 100755
index 0000000..aef7403
--- /dev/null
+++ b/membership/static/font-awesome/scss/_stacked.scss
@@ -0,0 +1,20 @@
+// Stacked Icons
+// -------------------------
+
+.#{$fa-css-prefix}-stack {
+ position: relative;
+ display: inline-block;
+ width: 2em;
+ height: 2em;
+ line-height: 2em;
+ vertical-align: middle;
+}
+.#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {
+ position: absolute;
+ left: 0;
+ width: 100%;
+ text-align: center;
+}
+.#{$fa-css-prefix}-stack-1x { line-height: inherit; }
+.#{$fa-css-prefix}-stack-2x { font-size: 2em; }
+.#{$fa-css-prefix}-inverse { color: $fa-inverse; }
diff --git a/membership/static/font-awesome/scss/_variables.scss b/membership/static/font-awesome/scss/_variables.scss
new file mode 100755
index 0000000..1f374d6
--- /dev/null
+++ b/membership/static/font-awesome/scss/_variables.scss
@@ -0,0 +1,735 @@
+// Variables
+// --------------------------
+
+$fa-font-path: "../fonts" !default;
+$fa-font-size-base: 14px !default;
+$fa-line-height-base: 1 !default;
+//$fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.6.1/fonts" !default; // for referencing Bootstrap CDN font files directly
+$fa-css-prefix: fa !default;
+$fa-version: "4.6.1" !default;
+$fa-border-color: #eee !default;
+$fa-inverse: #fff !default;
+$fa-li-width: (30em / 14) !default;
+
+$fa-var-500px: "\f26e";
+$fa-var-adjust: "\f042";
+$fa-var-adn: "\f170";
+$fa-var-align-center: "\f037";
+$fa-var-align-justify: "\f039";
+$fa-var-align-left: "\f036";
+$fa-var-align-right: "\f038";
+$fa-var-amazon: "\f270";
+$fa-var-ambulance: "\f0f9";
+$fa-var-american-sign-language-interpreting: "\f2a3";
+$fa-var-anchor: "\f13d";
+$fa-var-android: "\f17b";
+$fa-var-angellist: "\f209";
+$fa-var-angle-double-down: "\f103";
+$fa-var-angle-double-left: "\f100";
+$fa-var-angle-double-right: "\f101";
+$fa-var-angle-double-up: "\f102";
+$fa-var-angle-down: "\f107";
+$fa-var-angle-left: "\f104";
+$fa-var-angle-right: "\f105";
+$fa-var-angle-up: "\f106";
+$fa-var-apple: "\f179";
+$fa-var-archive: "\f187";
+$fa-var-area-chart: "\f1fe";
+$fa-var-arrow-circle-down: "\f0ab";
+$fa-var-arrow-circle-left: "\f0a8";
+$fa-var-arrow-circle-o-down: "\f01a";
+$fa-var-arrow-circle-o-left: "\f190";
+$fa-var-arrow-circle-o-right: "\f18e";
+$fa-var-arrow-circle-o-up: "\f01b";
+$fa-var-arrow-circle-right: "\f0a9";
+$fa-var-arrow-circle-up: "\f0aa";
+$fa-var-arrow-down: "\f063";
+$fa-var-arrow-left: "\f060";
+$fa-var-arrow-right: "\f061";
+$fa-var-arrow-up: "\f062";
+$fa-var-arrows: "\f047";
+$fa-var-arrows-alt: "\f0b2";
+$fa-var-arrows-h: "\f07e";
+$fa-var-arrows-v: "\f07d";
+$fa-var-asl-interpreting: "\f2a3";
+$fa-var-assistive-listening-systems: "\f2a2";
+$fa-var-asterisk: "\f069";
+$fa-var-at: "\f1fa";
+$fa-var-audio-description: "\f29e";
+$fa-var-automobile: "\f1b9";
+$fa-var-backward: "\f04a";
+$fa-var-balance-scale: "\f24e";
+$fa-var-ban: "\f05e";
+$fa-var-bank: "\f19c";
+$fa-var-bar-chart: "\f080";
+$fa-var-bar-chart-o: "\f080";
+$fa-var-barcode: "\f02a";
+$fa-var-bars: "\f0c9";
+$fa-var-battery-0: "\f244";
+$fa-var-battery-1: "\f243";
+$fa-var-battery-2: "\f242";
+$fa-var-battery-3: "\f241";
+$fa-var-battery-4: "\f240";
+$fa-var-battery-empty: "\f244";
+$fa-var-battery-full: "\f240";
+$fa-var-battery-half: "\f242";
+$fa-var-battery-quarter: "\f243";
+$fa-var-battery-three-quarters: "\f241";
+$fa-var-bed: "\f236";
+$fa-var-beer: "\f0fc";
+$fa-var-behance: "\f1b4";
+$fa-var-behance-square: "\f1b5";
+$fa-var-bell: "\f0f3";
+$fa-var-bell-o: "\f0a2";
+$fa-var-bell-slash: "\f1f6";
+$fa-var-bell-slash-o: "\f1f7";
+$fa-var-bicycle: "\f206";
+$fa-var-binoculars: "\f1e5";
+$fa-var-birthday-cake: "\f1fd";
+$fa-var-bitbucket: "\f171";
+$fa-var-bitbucket-square: "\f172";
+$fa-var-bitcoin: "\f15a";
+$fa-var-black-tie: "\f27e";
+$fa-var-blind: "\f29d";
+$fa-var-bluetooth: "\f293";
+$fa-var-bluetooth-b: "\f294";
+$fa-var-bold: "\f032";
+$fa-var-bolt: "\f0e7";
+$fa-var-bomb: "\f1e2";
+$fa-var-book: "\f02d";
+$fa-var-bookmark: "\f02e";
+$fa-var-bookmark-o: "\f097";
+$fa-var-braille: "\f2a1";
+$fa-var-briefcase: "\f0b1";
+$fa-var-btc: "\f15a";
+$fa-var-bug: "\f188";
+$fa-var-building: "\f1ad";
+$fa-var-building-o: "\f0f7";
+$fa-var-bullhorn: "\f0a1";
+$fa-var-bullseye: "\f140";
+$fa-var-bus: "\f207";
+$fa-var-buysellads: "\f20d";
+$fa-var-cab: "\f1ba";
+$fa-var-calculator: "\f1ec";
+$fa-var-calendar: "\f073";
+$fa-var-calendar-check-o: "\f274";
+$fa-var-calendar-minus-o: "\f272";
+$fa-var-calendar-o: "\f133";
+$fa-var-calendar-plus-o: "\f271";
+$fa-var-calendar-times-o: "\f273";
+$fa-var-camera: "\f030";
+$fa-var-camera-retro: "\f083";
+$fa-var-car: "\f1b9";
+$fa-var-caret-down: "\f0d7";
+$fa-var-caret-left: "\f0d9";
+$fa-var-caret-right: "\f0da";
+$fa-var-caret-square-o-down: "\f150";
+$fa-var-caret-square-o-left: "\f191";
+$fa-var-caret-square-o-right: "\f152";
+$fa-var-caret-square-o-up: "\f151";
+$fa-var-caret-up: "\f0d8";
+$fa-var-cart-arrow-down: "\f218";
+$fa-var-cart-plus: "\f217";
+$fa-var-cc: "\f20a";
+$fa-var-cc-amex: "\f1f3";
+$fa-var-cc-diners-club: "\f24c";
+$fa-var-cc-discover: "\f1f2";
+$fa-var-cc-jcb: "\f24b";
+$fa-var-cc-mastercard: "\f1f1";
+$fa-var-cc-paypal: "\f1f4";
+$fa-var-cc-stripe: "\f1f5";
+$fa-var-cc-visa: "\f1f0";
+$fa-var-certificate: "\f0a3";
+$fa-var-chain: "\f0c1";
+$fa-var-chain-broken: "\f127";
+$fa-var-check: "\f00c";
+$fa-var-check-circle: "\f058";
+$fa-var-check-circle-o: "\f05d";
+$fa-var-check-square: "\f14a";
+$fa-var-check-square-o: "\f046";
+$fa-var-chevron-circle-down: "\f13a";
+$fa-var-chevron-circle-left: "\f137";
+$fa-var-chevron-circle-right: "\f138";
+$fa-var-chevron-circle-up: "\f139";
+$fa-var-chevron-down: "\f078";
+$fa-var-chevron-left: "\f053";
+$fa-var-chevron-right: "\f054";
+$fa-var-chevron-up: "\f077";
+$fa-var-child: "\f1ae";
+$fa-var-chrome: "\f268";
+$fa-var-circle: "\f111";
+$fa-var-circle-o: "\f10c";
+$fa-var-circle-o-notch: "\f1ce";
+$fa-var-circle-thin: "\f1db";
+$fa-var-clipboard: "\f0ea";
+$fa-var-clock-o: "\f017";
+$fa-var-clone: "\f24d";
+$fa-var-close: "\f00d";
+$fa-var-cloud: "\f0c2";
+$fa-var-cloud-download: "\f0ed";
+$fa-var-cloud-upload: "\f0ee";
+$fa-var-cny: "\f157";
+$fa-var-code: "\f121";
+$fa-var-code-fork: "\f126";
+$fa-var-codepen: "\f1cb";
+$fa-var-codiepie: "\f284";
+$fa-var-coffee: "\f0f4";
+$fa-var-cog: "\f013";
+$fa-var-cogs: "\f085";
+$fa-var-columns: "\f0db";
+$fa-var-comment: "\f075";
+$fa-var-comment-o: "\f0e5";
+$fa-var-commenting: "\f27a";
+$fa-var-commenting-o: "\f27b";
+$fa-var-comments: "\f086";
+$fa-var-comments-o: "\f0e6";
+$fa-var-compass: "\f14e";
+$fa-var-compress: "\f066";
+$fa-var-connectdevelop: "\f20e";
+$fa-var-contao: "\f26d";
+$fa-var-copy: "\f0c5";
+$fa-var-copyright: "\f1f9";
+$fa-var-creative-commons: "\f25e";
+$fa-var-credit-card: "\f09d";
+$fa-var-credit-card-alt: "\f283";
+$fa-var-crop: "\f125";
+$fa-var-crosshairs: "\f05b";
+$fa-var-css3: "\f13c";
+$fa-var-cube: "\f1b2";
+$fa-var-cubes: "\f1b3";
+$fa-var-cut: "\f0c4";
+$fa-var-cutlery: "\f0f5";
+$fa-var-dashboard: "\f0e4";
+$fa-var-dashcube: "\f210";
+$fa-var-database: "\f1c0";
+$fa-var-deaf: "\f2a4";
+$fa-var-deafness: "\f2a4";
+$fa-var-dedent: "\f03b";
+$fa-var-delicious: "\f1a5";
+$fa-var-desktop: "\f108";
+$fa-var-deviantart: "\f1bd";
+$fa-var-diamond: "\f219";
+$fa-var-digg: "\f1a6";
+$fa-var-dollar: "\f155";
+$fa-var-dot-circle-o: "\f192";
+$fa-var-download: "\f019";
+$fa-var-dribbble: "\f17d";
+$fa-var-dropbox: "\f16b";
+$fa-var-drupal: "\f1a9";
+$fa-var-edge: "\f282";
+$fa-var-edit: "\f044";
+$fa-var-eject: "\f052";
+$fa-var-ellipsis-h: "\f141";
+$fa-var-ellipsis-v: "\f142";
+$fa-var-empire: "\f1d1";
+$fa-var-envelope: "\f0e0";
+$fa-var-envelope-o: "\f003";
+$fa-var-envelope-square: "\f199";
+$fa-var-envira: "\f299";
+$fa-var-eraser: "\f12d";
+$fa-var-eur: "\f153";
+$fa-var-euro: "\f153";
+$fa-var-exchange: "\f0ec";
+$fa-var-exclamation: "\f12a";
+$fa-var-exclamation-circle: "\f06a";
+$fa-var-exclamation-triangle: "\f071";
+$fa-var-expand: "\f065";
+$fa-var-expeditedssl: "\f23e";
+$fa-var-external-link: "\f08e";
+$fa-var-external-link-square: "\f14c";
+$fa-var-eye: "\f06e";
+$fa-var-eye-slash: "\f070";
+$fa-var-eyedropper: "\f1fb";
+$fa-var-facebook: "\f09a";
+$fa-var-facebook-f: "\f09a";
+$fa-var-facebook-official: "\f230";
+$fa-var-facebook-square: "\f082";
+$fa-var-fast-backward: "\f049";
+$fa-var-fast-forward: "\f050";
+$fa-var-fax: "\f1ac";
+$fa-var-feed: "\f09e";
+$fa-var-female: "\f182";
+$fa-var-fighter-jet: "\f0fb";
+$fa-var-file: "\f15b";
+$fa-var-file-archive-o: "\f1c6";
+$fa-var-file-audio-o: "\f1c7";
+$fa-var-file-code-o: "\f1c9";
+$fa-var-file-excel-o: "\f1c3";
+$fa-var-file-image-o: "\f1c5";
+$fa-var-file-movie-o: "\f1c8";
+$fa-var-file-o: "\f016";
+$fa-var-file-pdf-o: "\f1c1";
+$fa-var-file-photo-o: "\f1c5";
+$fa-var-file-picture-o: "\f1c5";
+$fa-var-file-powerpoint-o: "\f1c4";
+$fa-var-file-sound-o: "\f1c7";
+$fa-var-file-text: "\f15c";
+$fa-var-file-text-o: "\f0f6";
+$fa-var-file-video-o: "\f1c8";
+$fa-var-file-word-o: "\f1c2";
+$fa-var-file-zip-o: "\f1c6";
+$fa-var-files-o: "\f0c5";
+$fa-var-film: "\f008";
+$fa-var-filter: "\f0b0";
+$fa-var-fire: "\f06d";
+$fa-var-fire-extinguisher: "\f134";
+$fa-var-firefox: "\f269";
+$fa-var-flag: "\f024";
+$fa-var-flag-checkered: "\f11e";
+$fa-var-flag-o: "\f11d";
+$fa-var-flash: "\f0e7";
+$fa-var-flask: "\f0c3";
+$fa-var-flickr: "\f16e";
+$fa-var-floppy-o: "\f0c7";
+$fa-var-folder: "\f07b";
+$fa-var-folder-o: "\f114";
+$fa-var-folder-open: "\f07c";
+$fa-var-folder-open-o: "\f115";
+$fa-var-font: "\f031";
+$fa-var-fonticons: "\f280";
+$fa-var-fort-awesome: "\f286";
+$fa-var-forumbee: "\f211";
+$fa-var-forward: "\f04e";
+$fa-var-foursquare: "\f180";
+$fa-var-frown-o: "\f119";
+$fa-var-futbol-o: "\f1e3";
+$fa-var-gamepad: "\f11b";
+$fa-var-gavel: "\f0e3";
+$fa-var-gbp: "\f154";
+$fa-var-ge: "\f1d1";
+$fa-var-gear: "\f013";
+$fa-var-gears: "\f085";
+$fa-var-genderless: "\f22d";
+$fa-var-get-pocket: "\f265";
+$fa-var-gg: "\f260";
+$fa-var-gg-circle: "\f261";
+$fa-var-gift: "\f06b";
+$fa-var-git: "\f1d3";
+$fa-var-git-square: "\f1d2";
+$fa-var-github: "\f09b";
+$fa-var-github-alt: "\f113";
+$fa-var-github-square: "\f092";
+$fa-var-gitlab: "\f296";
+$fa-var-gittip: "\f184";
+$fa-var-glass: "\f000";
+$fa-var-glide: "\f2a5";
+$fa-var-glide-g: "\f2a6";
+$fa-var-globe: "\f0ac";
+$fa-var-google: "\f1a0";
+$fa-var-google-plus: "\f0d5";
+$fa-var-google-plus-square: "\f0d4";
+$fa-var-google-wallet: "\f1ee";
+$fa-var-graduation-cap: "\f19d";
+$fa-var-gratipay: "\f184";
+$fa-var-group: "\f0c0";
+$fa-var-h-square: "\f0fd";
+$fa-var-hacker-news: "\f1d4";
+$fa-var-hand-grab-o: "\f255";
+$fa-var-hand-lizard-o: "\f258";
+$fa-var-hand-o-down: "\f0a7";
+$fa-var-hand-o-left: "\f0a5";
+$fa-var-hand-o-right: "\f0a4";
+$fa-var-hand-o-up: "\f0a6";
+$fa-var-hand-paper-o: "\f256";
+$fa-var-hand-peace-o: "\f25b";
+$fa-var-hand-pointer-o: "\f25a";
+$fa-var-hand-rock-o: "\f255";
+$fa-var-hand-scissors-o: "\f257";
+$fa-var-hand-spock-o: "\f259";
+$fa-var-hand-stop-o: "\f256";
+$fa-var-hard-of-hearing: "\f2a4";
+$fa-var-hashtag: "\f292";
+$fa-var-hdd-o: "\f0a0";
+$fa-var-header: "\f1dc";
+$fa-var-headphones: "\f025";
+$fa-var-heart: "\f004";
+$fa-var-heart-o: "\f08a";
+$fa-var-heartbeat: "\f21e";
+$fa-var-history: "\f1da";
+$fa-var-home: "\f015";
+$fa-var-hospital-o: "\f0f8";
+$fa-var-hotel: "\f236";
+$fa-var-hourglass: "\f254";
+$fa-var-hourglass-1: "\f251";
+$fa-var-hourglass-2: "\f252";
+$fa-var-hourglass-3: "\f253";
+$fa-var-hourglass-end: "\f253";
+$fa-var-hourglass-half: "\f252";
+$fa-var-hourglass-o: "\f250";
+$fa-var-hourglass-start: "\f251";
+$fa-var-houzz: "\f27c";
+$fa-var-html5: "\f13b";
+$fa-var-i-cursor: "\f246";
+$fa-var-ils: "\f20b";
+$fa-var-image: "\f03e";
+$fa-var-inbox: "\f01c";
+$fa-var-indent: "\f03c";
+$fa-var-industry: "\f275";
+$fa-var-info: "\f129";
+$fa-var-info-circle: "\f05a";
+$fa-var-inr: "\f156";
+$fa-var-instagram: "\f16d";
+$fa-var-institution: "\f19c";
+$fa-var-internet-explorer: "\f26b";
+$fa-var-intersex: "\f224";
+$fa-var-ioxhost: "\f208";
+$fa-var-italic: "\f033";
+$fa-var-joomla: "\f1aa";
+$fa-var-jpy: "\f157";
+$fa-var-jsfiddle: "\f1cc";
+$fa-var-key: "\f084";
+$fa-var-keyboard-o: "\f11c";
+$fa-var-krw: "\f159";
+$fa-var-language: "\f1ab";
+$fa-var-laptop: "\f109";
+$fa-var-lastfm: "\f202";
+$fa-var-lastfm-square: "\f203";
+$fa-var-leaf: "\f06c";
+$fa-var-leanpub: "\f212";
+$fa-var-legal: "\f0e3";
+$fa-var-lemon-o: "\f094";
+$fa-var-level-down: "\f149";
+$fa-var-level-up: "\f148";
+$fa-var-life-bouy: "\f1cd";
+$fa-var-life-buoy: "\f1cd";
+$fa-var-life-ring: "\f1cd";
+$fa-var-life-saver: "\f1cd";
+$fa-var-lightbulb-o: "\f0eb";
+$fa-var-line-chart: "\f201";
+$fa-var-link: "\f0c1";
+$fa-var-linkedin: "\f0e1";
+$fa-var-linkedin-square: "\f08c";
+$fa-var-linux: "\f17c";
+$fa-var-list: "\f03a";
+$fa-var-list-alt: "\f022";
+$fa-var-list-ol: "\f0cb";
+$fa-var-list-ul: "\f0ca";
+$fa-var-location-arrow: "\f124";
+$fa-var-lock: "\f023";
+$fa-var-long-arrow-down: "\f175";
+$fa-var-long-arrow-left: "\f177";
+$fa-var-long-arrow-right: "\f178";
+$fa-var-long-arrow-up: "\f176";
+$fa-var-low-vision: "\f2a8";
+$fa-var-magic: "\f0d0";
+$fa-var-magnet: "\f076";
+$fa-var-mail-forward: "\f064";
+$fa-var-mail-reply: "\f112";
+$fa-var-mail-reply-all: "\f122";
+$fa-var-male: "\f183";
+$fa-var-map: "\f279";
+$fa-var-map-marker: "\f041";
+$fa-var-map-o: "\f278";
+$fa-var-map-pin: "\f276";
+$fa-var-map-signs: "\f277";
+$fa-var-mars: "\f222";
+$fa-var-mars-double: "\f227";
+$fa-var-mars-stroke: "\f229";
+$fa-var-mars-stroke-h: "\f22b";
+$fa-var-mars-stroke-v: "\f22a";
+$fa-var-maxcdn: "\f136";
+$fa-var-meanpath: "\f20c";
+$fa-var-medium: "\f23a";
+$fa-var-medkit: "\f0fa";
+$fa-var-meh-o: "\f11a";
+$fa-var-mercury: "\f223";
+$fa-var-microphone: "\f130";
+$fa-var-microphone-slash: "\f131";
+$fa-var-minus: "\f068";
+$fa-var-minus-circle: "\f056";
+$fa-var-minus-square: "\f146";
+$fa-var-minus-square-o: "\f147";
+$fa-var-mixcloud: "\f289";
+$fa-var-mobile: "\f10b";
+$fa-var-mobile-phone: "\f10b";
+$fa-var-modx: "\f285";
+$fa-var-money: "\f0d6";
+$fa-var-moon-o: "\f186";
+$fa-var-mortar-board: "\f19d";
+$fa-var-motorcycle: "\f21c";
+$fa-var-mouse-pointer: "\f245";
+$fa-var-music: "\f001";
+$fa-var-navicon: "\f0c9";
+$fa-var-neuter: "\f22c";
+$fa-var-newspaper-o: "\f1ea";
+$fa-var-object-group: "\f247";
+$fa-var-object-ungroup: "\f248";
+$fa-var-odnoklassniki: "\f263";
+$fa-var-odnoklassniki-square: "\f264";
+$fa-var-opencart: "\f23d";
+$fa-var-openid: "\f19b";
+$fa-var-opera: "\f26a";
+$fa-var-optin-monster: "\f23c";
+$fa-var-outdent: "\f03b";
+$fa-var-pagelines: "\f18c";
+$fa-var-paint-brush: "\f1fc";
+$fa-var-paper-plane: "\f1d8";
+$fa-var-paper-plane-o: "\f1d9";
+$fa-var-paperclip: "\f0c6";
+$fa-var-paragraph: "\f1dd";
+$fa-var-paste: "\f0ea";
+$fa-var-pause: "\f04c";
+$fa-var-pause-circle: "\f28b";
+$fa-var-pause-circle-o: "\f28c";
+$fa-var-paw: "\f1b0";
+$fa-var-paypal: "\f1ed";
+$fa-var-pencil: "\f040";
+$fa-var-pencil-square: "\f14b";
+$fa-var-pencil-square-o: "\f044";
+$fa-var-percent: "\f295";
+$fa-var-phone: "\f095";
+$fa-var-phone-square: "\f098";
+$fa-var-photo: "\f03e";
+$fa-var-picture-o: "\f03e";
+$fa-var-pie-chart: "\f200";
+$fa-var-pied-piper: "\f1a7";
+$fa-var-pied-piper-alt: "\f1a8";
+$fa-var-pinterest: "\f0d2";
+$fa-var-pinterest-p: "\f231";
+$fa-var-pinterest-square: "\f0d3";
+$fa-var-plane: "\f072";
+$fa-var-play: "\f04b";
+$fa-var-play-circle: "\f144";
+$fa-var-play-circle-o: "\f01d";
+$fa-var-plug: "\f1e6";
+$fa-var-plus: "\f067";
+$fa-var-plus-circle: "\f055";
+$fa-var-plus-square: "\f0fe";
+$fa-var-plus-square-o: "\f196";
+$fa-var-power-off: "\f011";
+$fa-var-print: "\f02f";
+$fa-var-product-hunt: "\f288";
+$fa-var-puzzle-piece: "\f12e";
+$fa-var-qq: "\f1d6";
+$fa-var-qrcode: "\f029";
+$fa-var-question: "\f128";
+$fa-var-question-circle: "\f059";
+$fa-var-question-circle-o: "\f29c";
+$fa-var-quote-left: "\f10d";
+$fa-var-quote-right: "\f10e";
+$fa-var-ra: "\f1d0";
+$fa-var-random: "\f074";
+$fa-var-rebel: "\f1d0";
+$fa-var-recycle: "\f1b8";
+$fa-var-reddit: "\f1a1";
+$fa-var-reddit-alien: "\f281";
+$fa-var-reddit-square: "\f1a2";
+$fa-var-refresh: "\f021";
+$fa-var-registered: "\f25d";
+$fa-var-remove: "\f00d";
+$fa-var-renren: "\f18b";
+$fa-var-reorder: "\f0c9";
+$fa-var-repeat: "\f01e";
+$fa-var-reply: "\f112";
+$fa-var-reply-all: "\f122";
+$fa-var-retweet: "\f079";
+$fa-var-rmb: "\f157";
+$fa-var-road: "\f018";
+$fa-var-rocket: "\f135";
+$fa-var-rotate-left: "\f0e2";
+$fa-var-rotate-right: "\f01e";
+$fa-var-rouble: "\f158";
+$fa-var-rss: "\f09e";
+$fa-var-rss-square: "\f143";
+$fa-var-rub: "\f158";
+$fa-var-ruble: "\f158";
+$fa-var-rupee: "\f156";
+$fa-var-safari: "\f267";
+$fa-var-save: "\f0c7";
+$fa-var-scissors: "\f0c4";
+$fa-var-scribd: "\f28a";
+$fa-var-search: "\f002";
+$fa-var-search-minus: "\f010";
+$fa-var-search-plus: "\f00e";
+$fa-var-sellsy: "\f213";
+$fa-var-send: "\f1d8";
+$fa-var-send-o: "\f1d9";
+$fa-var-server: "\f233";
+$fa-var-share: "\f064";
+$fa-var-share-alt: "\f1e0";
+$fa-var-share-alt-square: "\f1e1";
+$fa-var-share-square: "\f14d";
+$fa-var-share-square-o: "\f045";
+$fa-var-shekel: "\f20b";
+$fa-var-sheqel: "\f20b";
+$fa-var-shield: "\f132";
+$fa-var-ship: "\f21a";
+$fa-var-shirtsinbulk: "\f214";
+$fa-var-shopping-bag: "\f290";
+$fa-var-shopping-basket: "\f291";
+$fa-var-shopping-cart: "\f07a";
+$fa-var-sign-in: "\f090";
+$fa-var-sign-language: "\f2a7";
+$fa-var-sign-out: "\f08b";
+$fa-var-signal: "\f012";
+$fa-var-signing: "\f2a7";
+$fa-var-simplybuilt: "\f215";
+$fa-var-sitemap: "\f0e8";
+$fa-var-skyatlas: "\f216";
+$fa-var-skype: "\f17e";
+$fa-var-slack: "\f198";
+$fa-var-sliders: "\f1de";
+$fa-var-slideshare: "\f1e7";
+$fa-var-smile-o: "\f118";
+$fa-var-snapchat: "\f2ab";
+$fa-var-snapchat-ghost: "\f2ac";
+$fa-var-snapchat-square: "\f2ad";
+$fa-var-soccer-ball-o: "\f1e3";
+$fa-var-sort: "\f0dc";
+$fa-var-sort-alpha-asc: "\f15d";
+$fa-var-sort-alpha-desc: "\f15e";
+$fa-var-sort-amount-asc: "\f160";
+$fa-var-sort-amount-desc: "\f161";
+$fa-var-sort-asc: "\f0de";
+$fa-var-sort-desc: "\f0dd";
+$fa-var-sort-down: "\f0dd";
+$fa-var-sort-numeric-asc: "\f162";
+$fa-var-sort-numeric-desc: "\f163";
+$fa-var-sort-up: "\f0de";
+$fa-var-soundcloud: "\f1be";
+$fa-var-space-shuttle: "\f197";
+$fa-var-spinner: "\f110";
+$fa-var-spoon: "\f1b1";
+$fa-var-spotify: "\f1bc";
+$fa-var-square: "\f0c8";
+$fa-var-square-o: "\f096";
+$fa-var-stack-exchange: "\f18d";
+$fa-var-stack-overflow: "\f16c";
+$fa-var-star: "\f005";
+$fa-var-star-half: "\f089";
+$fa-var-star-half-empty: "\f123";
+$fa-var-star-half-full: "\f123";
+$fa-var-star-half-o: "\f123";
+$fa-var-star-o: "\f006";
+$fa-var-steam: "\f1b6";
+$fa-var-steam-square: "\f1b7";
+$fa-var-step-backward: "\f048";
+$fa-var-step-forward: "\f051";
+$fa-var-stethoscope: "\f0f1";
+$fa-var-sticky-note: "\f249";
+$fa-var-sticky-note-o: "\f24a";
+$fa-var-stop: "\f04d";
+$fa-var-stop-circle: "\f28d";
+$fa-var-stop-circle-o: "\f28e";
+$fa-var-street-view: "\f21d";
+$fa-var-strikethrough: "\f0cc";
+$fa-var-stumbleupon: "\f1a4";
+$fa-var-stumbleupon-circle: "\f1a3";
+$fa-var-subscript: "\f12c";
+$fa-var-subway: "\f239";
+$fa-var-suitcase: "\f0f2";
+$fa-var-sun-o: "\f185";
+$fa-var-superscript: "\f12b";
+$fa-var-support: "\f1cd";
+$fa-var-table: "\f0ce";
+$fa-var-tablet: "\f10a";
+$fa-var-tachometer: "\f0e4";
+$fa-var-tag: "\f02b";
+$fa-var-tags: "\f02c";
+$fa-var-tasks: "\f0ae";
+$fa-var-taxi: "\f1ba";
+$fa-var-television: "\f26c";
+$fa-var-tencent-weibo: "\f1d5";
+$fa-var-terminal: "\f120";
+$fa-var-text-height: "\f034";
+$fa-var-text-width: "\f035";
+$fa-var-th: "\f00a";
+$fa-var-th-large: "\f009";
+$fa-var-th-list: "\f00b";
+$fa-var-thumb-tack: "\f08d";
+$fa-var-thumbs-down: "\f165";
+$fa-var-thumbs-o-down: "\f088";
+$fa-var-thumbs-o-up: "\f087";
+$fa-var-thumbs-up: "\f164";
+$fa-var-ticket: "\f145";
+$fa-var-times: "\f00d";
+$fa-var-times-circle: "\f057";
+$fa-var-times-circle-o: "\f05c";
+$fa-var-tint: "\f043";
+$fa-var-toggle-down: "\f150";
+$fa-var-toggle-left: "\f191";
+$fa-var-toggle-off: "\f204";
+$fa-var-toggle-on: "\f205";
+$fa-var-toggle-right: "\f152";
+$fa-var-toggle-up: "\f151";
+$fa-var-trademark: "\f25c";
+$fa-var-train: "\f238";
+$fa-var-transgender: "\f224";
+$fa-var-transgender-alt: "\f225";
+$fa-var-trash: "\f1f8";
+$fa-var-trash-o: "\f014";
+$fa-var-tree: "\f1bb";
+$fa-var-trello: "\f181";
+$fa-var-tripadvisor: "\f262";
+$fa-var-trophy: "\f091";
+$fa-var-truck: "\f0d1";
+$fa-var-try: "\f195";
+$fa-var-tty: "\f1e4";
+$fa-var-tumblr: "\f173";
+$fa-var-tumblr-square: "\f174";
+$fa-var-turkish-lira: "\f195";
+$fa-var-tv: "\f26c";
+$fa-var-twitch: "\f1e8";
+$fa-var-twitter: "\f099";
+$fa-var-twitter-square: "\f081";
+$fa-var-umbrella: "\f0e9";
+$fa-var-underline: "\f0cd";
+$fa-var-undo: "\f0e2";
+$fa-var-universal-access: "\f29a";
+$fa-var-university: "\f19c";
+$fa-var-unlink: "\f127";
+$fa-var-unlock: "\f09c";
+$fa-var-unlock-alt: "\f13e";
+$fa-var-unsorted: "\f0dc";
+$fa-var-upload: "\f093";
+$fa-var-usb: "\f287";
+$fa-var-usd: "\f155";
+$fa-var-user: "\f007";
+$fa-var-user-md: "\f0f0";
+$fa-var-user-plus: "\f234";
+$fa-var-user-secret: "\f21b";
+$fa-var-user-times: "\f235";
+$fa-var-users: "\f0c0";
+$fa-var-venus: "\f221";
+$fa-var-venus-double: "\f226";
+$fa-var-venus-mars: "\f228";
+$fa-var-viacoin: "\f237";
+$fa-var-viadeo: "\f2a9";
+$fa-var-viadeo-square: "\f2aa";
+$fa-var-video-camera: "\f03d";
+$fa-var-vimeo: "\f27d";
+$fa-var-vimeo-square: "\f194";
+$fa-var-vine: "\f1ca";
+$fa-var-vk: "\f189";
+$fa-var-volume-control-phone: "\f2a0";
+$fa-var-volume-down: "\f027";
+$fa-var-volume-off: "\f026";
+$fa-var-volume-up: "\f028";
+$fa-var-warning: "\f071";
+$fa-var-wechat: "\f1d7";
+$fa-var-weibo: "\f18a";
+$fa-var-weixin: "\f1d7";
+$fa-var-whatsapp: "\f232";
+$fa-var-wheelchair: "\f193";
+$fa-var-wheelchair-alt: "\f29b";
+$fa-var-wifi: "\f1eb";
+$fa-var-wikipedia-w: "\f266";
+$fa-var-windows: "\f17a";
+$fa-var-won: "\f159";
+$fa-var-wordpress: "\f19a";
+$fa-var-wpbeginner: "\f297";
+$fa-var-wpforms: "\f298";
+$fa-var-wrench: "\f0ad";
+$fa-var-xing: "\f168";
+$fa-var-xing-square: "\f169";
+$fa-var-y-combinator: "\f23b";
+$fa-var-y-combinator-square: "\f1d4";
+$fa-var-yahoo: "\f19e";
+$fa-var-yc: "\f23b";
+$fa-var-yc-square: "\f1d4";
+$fa-var-yelp: "\f1e9";
+$fa-var-yen: "\f157";
+$fa-var-youtube: "\f167";
+$fa-var-youtube-play: "\f16a";
+$fa-var-youtube-square: "\f166";
+
diff --git a/membership/static/font-awesome/scss/font-awesome.scss b/membership/static/font-awesome/scss/font-awesome.scss
new file mode 100755
index 0000000..a19d664
--- /dev/null
+++ b/membership/static/font-awesome/scss/font-awesome.scss
@@ -0,0 +1,18 @@
+/*!
+ * Font Awesome 4.6.1 by @davegandy - http://fontawesome.io - @fontawesome
+ * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+
+@import "variables";
+@import "mixins";
+@import "path";
+@import "core";
+@import "larger";
+@import "fixed-width";
+@import "list";
+@import "bordered-pulled";
+@import "animated";
+@import "rotated-flipped";
+@import "stacked";
+@import "icons";
+@import "screen-reader";
diff --git a/membership/static/membership.css b/membership/static/membership.css
new file mode 100755
index 0000000..3f0eea9
--- /dev/null
+++ b/membership/static/membership.css
@@ -0,0 +1,8276 @@
+@import url('https://fonts.googleapis.com/css?family=Lato|Lato');
+
+/*!
+ * Default theme for Pingendo
+ * Homepage: http://pingendo.com
+ * Copyright 2015 Pingendo
+ * Licensed under MIT
+ * Based on Bootstrap v3.3.4
+*/
+/* Add custom CSS classes here
+ *
+ * img {
+ * box-shadow : 0px 0px 10px black !important;
+ * }
+*/
+/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
+html {
+ font-family: sans-serif;
+ -ms-text-size-adjust: 100%;
+ -webkit-text-size-adjust: 100%;
+}
+
+body {
+ margin: 0;
+}
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+ display: block;
+}
+
+audio,
+canvas,
+progress,
+video {
+ display: inline-block;
+ vertical-align: baseline;
+}
+
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+
+[hidden],
+template {
+ display: none;
+}
+
+a {
+ background-color: transparent;
+}
+
+a:active,
+a:hover {
+ outline: 0;
+}
+
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+
+b,
+strong {
+ font-weight: bold;
+}
+
+dfn {
+ font-style: italic;
+}
+
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+mark {
+ background: #ff0;
+ color: #000;
+}
+
+small {
+ font-size: 80%;
+}
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sup {
+ top: -0.5em;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+img {
+ border: 0;
+}
+
+svg:not(:root) {
+ overflow: hidden;
+}
+
+figure {
+ margin: 1em 40px;
+}
+
+hr {
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ height: 0;
+}
+
+pre {
+ overflow: auto;
+}
+
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, monospace;
+ font-size: 1em;
+}
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ color: inherit;
+ font: inherit;
+ margin: 0;
+}
+
+button {
+ overflow: visible;
+}
+
+button,
+select {
+ text-transform: none;
+}
+
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button;
+ cursor: pointer;
+}
+
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+input {
+ line-height: normal;
+}
+
+input[type="checkbox"],
+input[type="radio"] {
+ box-sizing: border-box;
+ padding: 0;
+}
+
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+input[type="search"] {
+ -webkit-appearance: textfield;
+ -moz-box-sizing: content-box;
+ -webkit-box-sizing: content-box;
+ box-sizing: content-box;
+}
+
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+fieldset {
+ border: 1px solid #c0c0c0;
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
+}
+
+legend {
+ border: 0;
+ padding: 0;
+}
+
+textarea {
+ overflow: auto;
+}
+
+optgroup {
+ font-weight: bold;
+}
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+td,
+th {
+ padding: 0;
+}
+
+/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
+@media print {
+ *,
+ *:before,
+ *:after {
+ background: transparent !important;
+ color: #000 !important;
+ box-shadow: none !important;
+ text-shadow: none !important;
+ }
+
+ a,
+ a:visited {
+ text-decoration: underline;
+ }
+
+ a[href]:after {
+ content: " (" attr(href) ")";
+ }
+
+ abbr[title]:after {
+ content: " (" attr(title) ")";
+ }
+
+ a[href^="#"]:after,
+ a[href^="javascript:"]:after {
+ content: "";
+ }
+
+ pre,
+ blockquote {
+ border: 1px solid #999;
+ page-break-inside: avoid;
+ }
+
+ thead {
+ display: table-header-group;
+ }
+
+ tr,
+ img {
+ page-break-inside: avoid;
+ }
+
+ img {
+ max-width: 100% !important;
+ }
+
+ p,
+ h2,
+ h3 {
+ orphans: 3;
+ widows: 3;
+ }
+
+ h2,
+ h3 {
+ page-break-after: avoid;
+ }
+
+ select {
+ background: #fff !important;
+ }
+
+ .navbar {
+ display: none;
+ }
+
+ .btn > .caret,
+ .dropup > .btn > .caret {
+ border-top-color: #000 !important;
+ }
+
+ .label {
+ border: 1px solid #000;
+ }
+
+ .table {
+ border-collapse: collapse !important;
+ }
+
+ .table td,
+ .table th {
+ background-color: #fff !important;
+ }
+
+ .table-bordered th,
+ .table-bordered td {
+ border: 1px solid #ddd !important;
+ }
+}
+
+@font-face {
+ font-family: 'Glyphicons Halflings';
+ src: url('../fonts/glyphicons-halflings-regular.eot');
+ src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+}
+
+.glyphicon {
+ position: relative;
+ top: 1px;
+ display: inline-block;
+ font-family: 'Glyphicons Halflings';
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.glyphicon-asterisk:before {
+ content: "\2a";
+}
+
+.glyphicon-plus:before {
+ content: "\2b";
+}
+
+.glyphicon-euro:before,
+.glyphicon-eur:before {
+ content: "\20ac";
+}
+
+.glyphicon-minus:before {
+ content: "\2212";
+}
+
+.glyphicon-cloud:before {
+ content: "\2601";
+}
+
+.glyphicon-envelope:before {
+ content: "\2709";
+}
+
+.glyphicon-pencil:before {
+ content: "\270f";
+}
+
+.glyphicon-glass:before {
+ content: "\e001";
+}
+
+.glyphicon-music:before {
+ content: "\e002";
+}
+
+.glyphicon-search:before {
+ content: "\e003";
+}
+
+.glyphicon-heart:before {
+ content: "\e005";
+}
+
+.glyphicon-star:before {
+ content: "\e006";
+}
+
+.glyphicon-star-empty:before {
+ content: "\e007";
+}
+
+.glyphicon-user:before {
+ content: "\e008";
+}
+
+.glyphicon-film:before {
+ content: "\e009";
+}
+
+.glyphicon-th-large:before {
+ content: "\e010";
+}
+
+.glyphicon-th:before {
+ content: "\e011";
+}
+
+.glyphicon-th-list:before {
+ content: "\e012";
+}
+
+.glyphicon-ok:before {
+ content: "\e013";
+}
+
+.glyphicon-remove:before {
+ content: "\e014";
+}
+
+.glyphicon-zoom-in:before {
+ content: "\e015";
+}
+
+.glyphicon-zoom-out:before {
+ content: "\e016";
+}
+
+.glyphicon-off:before {
+ content: "\e017";
+}
+
+.glyphicon-signal:before {
+ content: "\e018";
+}
+
+.glyphicon-cog:before {
+ content: "\e019";
+}
+
+.glyphicon-trash:before {
+ content: "\e020";
+}
+
+.glyphicon-home:before {
+ content: "\e021";
+}
+
+.glyphicon-file:before {
+ content: "\e022";
+}
+
+.glyphicon-time:before {
+ content: "\e023";
+}
+
+.glyphicon-road:before {
+ content: "\e024";
+}
+
+.glyphicon-download-alt:before {
+ content: "\e025";
+}
+
+.glyphicon-download:before {
+ content: "\e026";
+}
+
+.glyphicon-upload:before {
+ content: "\e027";
+}
+
+.glyphicon-inbox:before {
+ content: "\e028";
+}
+
+.glyphicon-play-circle:before {
+ content: "\e029";
+}
+
+.glyphicon-repeat:before {
+ content: "\e030";
+}
+
+.glyphicon-refresh:before {
+ content: "\e031";
+}
+
+.glyphicon-list-alt:before {
+ content: "\e032";
+}
+
+.glyphicon-lock:before {
+ content: "\e033";
+}
+
+.glyphicon-flag:before {
+ content: "\e034";
+}
+
+.glyphicon-headphones:before {
+ content: "\e035";
+}
+
+.glyphicon-volume-off:before {
+ content: "\e036";
+}
+
+.glyphicon-volume-down:before {
+ content: "\e037";
+}
+
+.glyphicon-volume-up:before {
+ content: "\e038";
+}
+
+.glyphicon-qrcode:before {
+ content: "\e039";
+}
+
+.glyphicon-barcode:before {
+ content: "\e040";
+}
+
+.glyphicon-tag:before {
+ content: "\e041";
+}
+
+.glyphicon-tags:before {
+ content: "\e042";
+}
+
+.glyphicon-book:before {
+ content: "\e043";
+}
+
+.glyphicon-bookmark:before {
+ content: "\e044";
+}
+
+.glyphicon-print:before {
+ content: "\e045";
+}
+
+.glyphicon-camera:before {
+ content: "\e046";
+}
+
+.glyphicon-font:before {
+ content: "\e047";
+}
+
+.glyphicon-bold:before {
+ content: "\e048";
+}
+
+.glyphicon-italic:before {
+ content: "\e049";
+}
+
+.glyphicon-text-height:before {
+ content: "\e050";
+}
+
+.glyphicon-text-width:before {
+ content: "\e051";
+}
+
+.glyphicon-align-left:before {
+ content: "\e052";
+}
+
+.glyphicon-align-center:before {
+ content: "\e053";
+}
+
+.glyphicon-align-right:before {
+ content: "\e054";
+}
+
+.glyphicon-align-justify:before {
+ content: "\e055";
+}
+
+.glyphicon-list:before {
+ content: "\e056";
+}
+
+.glyphicon-indent-left:before {
+ content: "\e057";
+}
+
+.glyphicon-indent-right:before {
+ content: "\e058";
+}
+
+.glyphicon-facetime-video:before {
+ content: "\e059";
+}
+
+.glyphicon-picture:before {
+ content: "\e060";
+}
+
+.glyphicon-map-marker:before {
+ content: "\e062";
+}
+
+.glyphicon-adjust:before {
+ content: "\e063";
+}
+
+.glyphicon-tint:before {
+ content: "\e064";
+}
+
+.glyphicon-edit:before {
+ content: "\e065";
+}
+
+.glyphicon-share:before {
+ content: "\e066";
+}
+
+.glyphicon-check:before {
+ content: "\e067";
+}
+
+.glyphicon-move:before {
+ content: "\e068";
+}
+
+.glyphicon-step-backward:before {
+ content: "\e069";
+}
+
+.glyphicon-fast-backward:before {
+ content: "\e070";
+}
+
+.glyphicon-backward:before {
+ content: "\e071";
+}
+
+.glyphicon-play:before {
+ content: "\e072";
+}
+
+.glyphicon-pause:before {
+ content: "\e073";
+}
+
+.glyphicon-stop:before {
+ content: "\e074";
+}
+
+.glyphicon-forward:before {
+ content: "\e075";
+}
+
+.glyphicon-fast-forward:before {
+ content: "\e076";
+}
+
+.glyphicon-step-forward:before {
+ content: "\e077";
+}
+
+.glyphicon-eject:before {
+ content: "\e078";
+}
+
+.glyphicon-chevron-left:before {
+ content: "\e079";
+}
+
+.glyphicon-chevron-right:before {
+ content: "\e080";
+}
+
+.glyphicon-plus-sign:before {
+ content: "\e081";
+}
+
+.glyphicon-minus-sign:before {
+ content: "\e082";
+}
+
+.glyphicon-remove-sign:before {
+ content: "\e083";
+}
+
+.glyphicon-ok-sign:before {
+ content: "\e084";
+}
+
+.glyphicon-question-sign:before {
+ content: "\e085";
+}
+
+.glyphicon-info-sign:before {
+ content: "\e086";
+}
+
+.glyphicon-screenshot:before {
+ content: "\e087";
+}
+
+.glyphicon-remove-circle:before {
+ content: "\e088";
+}
+
+.glyphicon-ok-circle:before {
+ content: "\e089";
+}
+
+.glyphicon-ban-circle:before {
+ content: "\e090";
+}
+
+.glyphicon-arrow-left:before {
+ content: "\e091";
+}
+
+.glyphicon-arrow-right:before {
+ content: "\e092";
+}
+
+.glyphicon-arrow-up:before {
+ content: "\e093";
+}
+
+.glyphicon-arrow-down:before {
+ content: "\e094";
+}
+
+.glyphicon-share-alt:before {
+ content: "\e095";
+}
+
+.glyphicon-resize-full:before {
+ content: "\e096";
+}
+
+.glyphicon-resize-small:before {
+ content: "\e097";
+}
+
+.glyphicon-exclamation-sign:before {
+ content: "\e101";
+}
+
+.glyphicon-gift:before {
+ content: "\e102";
+}
+
+.glyphicon-leaf:before {
+ content: "\e103";
+}
+
+.glyphicon-fire:before {
+ content: "\e104";
+}
+
+.glyphicon-eye-open:before {
+ content: "\e105";
+}
+
+.glyphicon-eye-close:before {
+ content: "\e106";
+}
+
+.glyphicon-warning-sign:before {
+ content: "\e107";
+}
+
+.glyphicon-plane:before {
+ content: "\e108";
+}
+
+.glyphicon-calendar:before {
+ content: "\e109";
+}
+
+.glyphicon-random:before {
+ content: "\e110";
+}
+
+.glyphicon-comment:before {
+ content: "\e111";
+}
+
+.glyphicon-magnet:before {
+ content: "\e112";
+}
+
+.glyphicon-chevron-up:before {
+ content: "\e113";
+}
+
+.glyphicon-chevron-down:before {
+ content: "\e114";
+}
+
+.glyphicon-retweet:before {
+ content: "\e115";
+}
+
+.glyphicon-shopping-cart:before {
+ content: "\e116";
+}
+
+.glyphicon-folder-close:before {
+ content: "\e117";
+}
+
+.glyphicon-folder-open:before {
+ content: "\e118";
+}
+
+.glyphicon-resize-vertical:before {
+ content: "\e119";
+}
+
+.glyphicon-resize-horizontal:before {
+ content: "\e120";
+}
+
+.glyphicon-hdd:before {
+ content: "\e121";
+}
+
+.glyphicon-bullhorn:before {
+ content: "\e122";
+}
+
+.glyphicon-bell:before {
+ content: "\e123";
+}
+
+.glyphicon-certificate:before {
+ content: "\e124";
+}
+
+.glyphicon-thumbs-up:before {
+ content: "\e125";
+}
+
+.glyphicon-thumbs-down:before {
+ content: "\e126";
+}
+
+.glyphicon-hand-right:before {
+ content: "\e127";
+}
+
+.glyphicon-hand-left:before {
+ content: "\e128";
+}
+
+.glyphicon-hand-up:before {
+ content: "\e129";
+}
+
+.glyphicon-hand-down:before {
+ content: "\e130";
+}
+
+.glyphicon-circle-arrow-right:before {
+ content: "\e131";
+}
+
+.glyphicon-circle-arrow-left:before {
+ content: "\e132";
+}
+
+.glyphicon-circle-arrow-up:before {
+ content: "\e133";
+}
+
+.glyphicon-circle-arrow-down:before {
+ content: "\e134";
+}
+
+.glyphicon-globe:before {
+ content: "\e135";
+}
+
+.glyphicon-wrench:before {
+ content: "\e136";
+}
+
+.glyphicon-tasks:before {
+ content: "\e137";
+}
+
+.glyphicon-filter:before {
+ content: "\e138";
+}
+
+.glyphicon-briefcase:before {
+ content: "\e139";
+}
+
+.glyphicon-fullscreen:before {
+ content: "\e140";
+}
+
+.glyphicon-dashboard:before {
+ content: "\e141";
+}
+
+.glyphicon-paperclip:before {
+ content: "\e142";
+}
+
+.glyphicon-heart-empty:before {
+ content: "\e143";
+}
+
+.glyphicon-link:before {
+ content: "\e144";
+}
+
+.glyphicon-phone:before {
+ content: "\e145";
+}
+
+.glyphicon-pushpin:before {
+ content: "\e146";
+}
+
+.glyphicon-usd:before {
+ content: "\e148";
+}
+
+.glyphicon-gbp:before {
+ content: "\e149";
+}
+
+.glyphicon-sort:before {
+ content: "\e150";
+}
+
+.glyphicon-sort-by-alphabet:before {
+ content: "\e151";
+}
+
+.glyphicon-sort-by-alphabet-alt:before {
+ content: "\e152";
+}
+
+.glyphicon-sort-by-order:before {
+ content: "\e153";
+}
+
+.glyphicon-sort-by-order-alt:before {
+ content: "\e154";
+}
+
+.glyphicon-sort-by-attributes:before {
+ content: "\e155";
+}
+
+.glyphicon-sort-by-attributes-alt:before {
+ content: "\e156";
+}
+
+.glyphicon-unchecked:before {
+ content: "\e157";
+}
+
+.glyphicon-expand:before {
+ content: "\e158";
+}
+
+.glyphicon-collapse-down:before {
+ content: "\e159";
+}
+
+.glyphicon-collapse-up:before {
+ content: "\e160";
+}
+
+.glyphicon-log-in:before {
+ content: "\e161";
+}
+
+.glyphicon-flash:before {
+ content: "\e162";
+}
+
+.glyphicon-log-out:before {
+ content: "\e163";
+}
+
+.glyphicon-new-window:before {
+ content: "\e164";
+}
+
+.glyphicon-record:before {
+ content: "\e165";
+}
+
+.glyphicon-save:before {
+ content: "\e166";
+}
+
+.glyphicon-open:before {
+ content: "\e167";
+}
+
+.glyphicon-saved:before {
+ content: "\e168";
+}
+
+.glyphicon-import:before {
+ content: "\e169";
+}
+
+.glyphicon-export:before {
+ content: "\e170";
+}
+
+.glyphicon-send:before {
+ content: "\e171";
+}
+
+.glyphicon-floppy-disk:before {
+ content: "\e172";
+}
+
+.glyphicon-floppy-saved:before {
+ content: "\e173";
+}
+
+.glyphicon-floppy-remove:before {
+ content: "\e174";
+}
+
+.glyphicon-floppy-save:before {
+ content: "\e175";
+}
+
+.glyphicon-floppy-open:before {
+ content: "\e176";
+}
+
+.glyphicon-credit-card:before {
+ content: "\e177";
+}
+
+.glyphicon-transfer:before {
+ content: "\e178";
+}
+
+.glyphicon-cutlery:before {
+ content: "\e179";
+}
+
+.glyphicon-header:before {
+ content: "\e180";
+}
+
+.glyphicon-compressed:before {
+ content: "\e181";
+}
+
+.glyphicon-earphone:before {
+ content: "\e182";
+}
+
+.glyphicon-phone-alt:before {
+ content: "\e183";
+}
+
+.glyphicon-tower:before {
+ content: "\e184";
+}
+
+.glyphicon-stats:before {
+ content: "\e185";
+}
+
+.glyphicon-sd-video:before {
+ content: "\e186";
+}
+
+.glyphicon-hd-video:before {
+ content: "\e187";
+}
+
+.glyphicon-subtitles:before {
+ content: "\e188";
+}
+
+.glyphicon-sound-stereo:before {
+ content: "\e189";
+}
+
+.glyphicon-sound-dolby:before {
+ content: "\e190";
+}
+
+.glyphicon-sound-5-1:before {
+ content: "\e191";
+}
+
+.glyphicon-sound-6-1:before {
+ content: "\e192";
+}
+
+.glyphicon-sound-7-1:before {
+ content: "\e193";
+}
+
+.glyphicon-copyright-mark:before {
+ content: "\e194";
+}
+
+.glyphicon-registration-mark:before {
+ content: "\e195";
+}
+
+.glyphicon-cloud-download:before {
+ content: "\e197";
+}
+
+.glyphicon-cloud-upload:before {
+ content: "\e198";
+}
+
+.glyphicon-tree-conifer:before {
+ content: "\e199";
+}
+
+.glyphicon-tree-deciduous:before {
+ content: "\e200";
+}
+
+.glyphicon-cd:before {
+ content: "\e201";
+}
+
+.glyphicon-save-file:before {
+ content: "\e202";
+}
+
+.glyphicon-open-file:before {
+ content: "\e203";
+}
+
+.glyphicon-level-up:before {
+ content: "\e204";
+}
+
+.glyphicon-copy:before {
+ content: "\e205";
+}
+
+.glyphicon-paste:before {
+ content: "\e206";
+}
+
+.glyphicon-alert:before {
+ content: "\e209";
+}
+
+.glyphicon-equalizer:before {
+ content: "\e210";
+}
+
+.glyphicon-king:before {
+ content: "\e211";
+}
+
+.glyphicon-queen:before {
+ content: "\e212";
+}
+
+.glyphicon-pawn:before {
+ content: "\e213";
+}
+
+.glyphicon-bishop:before {
+ content: "\e214";
+}
+
+.glyphicon-knight:before {
+ content: "\e215";
+}
+
+.glyphicon-baby-formula:before {
+ content: "\e216";
+}
+
+.glyphicon-tent:before {
+ content: "\26fa";
+}
+
+.glyphicon-blackboard:before {
+ content: "\e218";
+}
+
+.glyphicon-bed:before {
+ content: "\e219";
+}
+
+.glyphicon-apple:before {
+ content: "\f8ff";
+}
+
+.glyphicon-erase:before {
+ content: "\e221";
+}
+
+.glyphicon-hourglass:before {
+ content: "\231b";
+}
+
+.glyphicon-lamp:before {
+ content: "\e223";
+}
+
+.glyphicon-duplicate:before {
+ content: "\e224";
+}
+
+.glyphicon-piggy-bank:before {
+ content: "\e225";
+}
+
+.glyphicon-scissors:before {
+ content: "\e226";
+}
+
+.glyphicon-bitcoin:before {
+ content: "\e227";
+}
+
+.glyphicon-btc:before {
+ content: "\e227";
+}
+
+.glyphicon-xbt:before {
+ content: "\e227";
+}
+
+.glyphicon-yen:before {
+ content: "\00a5";
+}
+
+.glyphicon-jpy:before {
+ content: "\00a5";
+}
+
+.glyphicon-ruble:before {
+ content: "\20bd";
+}
+
+.glyphicon-rub:before {
+ content: "\20bd";
+}
+
+.glyphicon-scale:before {
+ content: "\e230";
+}
+
+.glyphicon-ice-lolly:before {
+ content: "\e231";
+}
+
+.glyphicon-ice-lolly-tasted:before {
+ content: "\e232";
+}
+
+.glyphicon-education:before {
+ content: "\e233";
+}
+
+.glyphicon-option-horizontal:before {
+ content: "\e234";
+}
+
+.glyphicon-option-vertical:before {
+ content: "\e235";
+}
+
+.glyphicon-menu-hamburger:before {
+ content: "\e236";
+}
+
+.glyphicon-modal-window:before {
+ content: "\e237";
+}
+
+.glyphicon-oil:before {
+ content: "\e238";
+}
+
+.glyphicon-grain:before {
+ content: "\e239";
+}
+
+.glyphicon-sunglasses:before {
+ content: "\e240";
+}
+
+.glyphicon-text-size:before {
+ content: "\e241";
+}
+
+.glyphicon-text-color:before {
+ content: "\e242";
+}
+
+.glyphicon-text-background:before {
+ content: "\e243";
+}
+
+.glyphicon-object-align-top:before {
+ content: "\e244";
+}
+
+.glyphicon-object-align-bottom:before {
+ content: "\e245";
+}
+
+.glyphicon-object-align-horizontal:before {
+ content: "\e246";
+}
+
+.glyphicon-object-align-left:before {
+ content: "\e247";
+}
+
+.glyphicon-object-align-vertical:before {
+ content: "\e248";
+}
+
+.glyphicon-object-align-right:before {
+ content: "\e249";
+}
+
+.glyphicon-triangle-right:before {
+ content: "\e250";
+}
+
+.glyphicon-triangle-left:before {
+ content: "\e251";
+}
+
+.glyphicon-triangle-bottom:before {
+ content: "\e252";
+}
+
+.glyphicon-triangle-top:before {
+ content: "\e253";
+}
+
+.glyphicon-console:before {
+ content: "\e254";
+}
+
+.glyphicon-superscript:before {
+ content: "\e255";
+}
+
+.glyphicon-subscript:before {
+ content: "\e256";
+}
+
+.glyphicon-menu-left:before {
+ content: "\e257";
+}
+
+.glyphicon-menu-right:before {
+ content: "\e258";
+}
+
+.glyphicon-menu-down:before {
+ content: "\e259";
+}
+
+.glyphicon-menu-up:before {
+ content: "\e260";
+}
+
+* {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+*:before,
+*:after {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+html {
+ font-size: 10px;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+body {
+ font-family: Lato;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #000000;
+ background-color: #ffffff;
+}
+
+input,
+button,
+select,
+textarea {
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+
+a {
+ color: #8bc4c9;
+ text-decoration: none;
+}
+
+a:hover,
+a:focus {
+ color: #23547f;
+ text-decoration: underline;
+}
+
+a:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+figure {
+ margin: 0;
+}
+
+img {
+ vertical-align: middle;
+}
+
+.img-responsive,
+.thumbnail > img,
+.thumbnail a > img,
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+}
+
+.img-rounded {
+ border-radius: 5px;
+}
+
+.img-thumbnail {
+ padding: 4px;
+ line-height: 1.42857143;
+ background-color: #ffffff;
+ border: 1px solid #dddddd;
+ border-radius: 4px;
+ -webkit-transition: all 0.2s ease-in-out;
+ -o-transition: all 0.2s ease-in-out;
+ transition: all 0.2s ease-in-out;
+ display: inline-block;
+ max-width: 100%;
+ height: auto;
+}
+
+.img-circle {
+ border-radius: 50%;
+}
+
+hr {
+ margin-top: 20px;
+ margin-bottom: 20px;
+ border: 0;
+ border-top: 1px solid #eeeeee;
+}
+
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ margin: -1px;
+ padding: 0;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0;
+}
+
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+}
+
+[role="button"] {
+ cursor: pointer;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6 {
+ font-family: Lato;
+ font-weight: 500;
+ line-height: 1.1;
+ color: inherit;
+}
+
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small,
+.h1 small,
+.h2 small,
+.h3 small,
+.h4 small,
+.h5 small,
+.h6 small,
+h1 .small,
+h2 .small,
+h3 .small,
+h4 .small,
+h5 .small,
+h6 .small,
+.h1 .small,
+.h2 .small,
+.h3 .small,
+.h4 .small,
+.h5 .small,
+.h6 .small {
+ font-weight: normal;
+ line-height: 1;
+ color: #777777;
+}
+
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3 {
+ margin-top: 20px;
+ margin-bottom: 10px;
+}
+
+h1 small,
+.h1 small,
+h2 small,
+.h2 small,
+h3 small,
+.h3 small,
+h1 .small,
+.h1 .small,
+h2 .small,
+.h2 .small,
+h3 .small,
+.h3 .small {
+ font-size: 65%;
+}
+
+h4,
+.h4,
+h5,
+.h5,
+h6,
+.h6 {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+h4 small,
+.h4 small,
+h5 small,
+.h5 small,
+h6 small,
+.h6 small,
+h4 .small,
+.h4 .small,
+h5 .small,
+.h5 .small,
+h6 .small,
+.h6 .small {
+ font-size: 75%;
+}
+
+h1,
+.h1 {
+ font-size: 36px;
+}
+
+h2,
+.h2 {
+ font-size: 30px;
+}
+
+h3,
+.h3 {
+ font-size: 24px;
+}
+
+h4,
+.h4 {
+ font-size: 18px;
+}
+
+h5,
+.h5 {
+ font-size: 14px;
+}
+
+h6,
+.h6 {
+ font-size: 12px;
+}
+
+p {
+ margin: 0 0 10px;
+}
+
+.lead {
+ margin-bottom: 20px;
+ font-size: 16px;
+ font-weight: 300;
+ line-height: 1.4;
+}
+
+@media (min-width: 768px) {
+ .lead {
+ font-size: 21px;
+ }
+}
+
+small,
+.small {
+ font-size: 85%;
+}
+
+mark,
+.mark {
+ background-color: #f8d9ac;
+ padding: .2em;
+}
+
+.text-left {
+ text-align: left;
+}
+
+.text-right {
+ text-align: right;
+}
+
+.text-center {
+ text-align: center;
+}
+
+.text-justify {
+ text-align: justify;
+}
+
+.text-nowrap {
+ white-space: nowrap;
+}
+
+.text-lowercase {
+ text-transform: lowercase;
+}
+
+.text-uppercase {
+ text-transform: uppercase;
+}
+
+.text-capitalize {
+ text-transform: capitalize;
+}
+
+.text-muted {
+ color: #777777;
+}
+
+.text-primary {
+ color: #165A72;
+}
+
+a.text-primary:hover {
+ color: #286193;
+}
+
+.text-success {
+ color: #5cb85c;
+}
+
+a.text-success:hover {
+ color: #449d44;
+}
+
+.text-info {
+ color: #5bc0de;
+}
+
+a.text-info:hover {
+ color: #31b0d5;
+}
+
+.text-warning {
+ color: #f0ad4e;
+}
+
+a.text-warning:hover {
+ color: #ec971f;
+}
+
+.text-danger {
+ color: #d9534f;
+}
+
+a.text-danger:hover {
+ color: #c9302c;
+}
+
+.bg-primary {
+ color: #fff;
+ background-color: #337cbb;
+}
+
+a.bg-primary:hover {
+ background-color: #286193;
+}
+
+.bg-success {
+ background-color: #a3d7a3;
+}
+
+a.bg-success:hover {
+ background-color: #80c780;
+}
+
+.bg-info {
+ background-color: #b0e1ef;
+}
+
+a.bg-info:hover {
+ background-color: #85d0e7;
+}
+
+.bg-warning {
+ background-color: #f8d9ac;
+}
+
+a.bg-warning:hover {
+ background-color: #f4c37d;
+}
+
+.bg-danger {
+ background-color: #eba5a3;
+}
+
+a.bg-danger:hover {
+ background-color: #e27c79;
+}
+
+.page-header {
+ padding-bottom: 9px;
+ margin: 40px 0 20px;
+ border-bottom: 1px solid #eeeeee;
+}
+
+ul,
+ol {
+ margin-top: 0;
+ margin-bottom: 10px;
+}
+
+ul ul,
+ol ul,
+ul ol,
+ol ol {
+ margin-bottom: 0;
+}
+
+.list-unstyled {
+ padding-left: 0;
+ list-style: none;
+}
+
+.list-inline {
+ padding-left: 0;
+ list-style: none;
+ margin-left: -5px;
+}
+
+.list-inline > li {
+ display: inline-block;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+dl {
+ margin-top: 0;
+ margin-bottom: 20px;
+}
+
+dt,
+dd {
+ line-height: 1.42857143;
+}
+
+dt {
+ font-weight: bold;
+}
+
+dd {
+ margin-left: 0;
+}
+
+@media (min-width: 768px) {
+ .dl-horizontal dt {
+ float: left;
+ width: 160px;
+ clear: left;
+ text-align: right;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .dl-horizontal dd {
+ margin-left: 180px;
+ }
+}
+
+abbr[title],
+abbr[data-original-title] {
+ cursor: help;
+ border-bottom: 1px dotted #777777;
+}
+
+.initialism {
+ font-size: 90%;
+ text-transform: uppercase;
+}
+
+blockquote {
+ padding: 10px 20px;
+ margin: 0 0 20px;
+ font-size: 17.5px;
+ border-left: 5px solid #eeeeee;
+}
+
+blockquote p:last-child,
+blockquote ul:last-child,
+blockquote ol:last-child {
+ margin-bottom: 0;
+}
+
+blockquote footer,
+blockquote small,
+blockquote .small {
+ display: block;
+ font-size: 80%;
+ line-height: 1.42857143;
+ color: #777777;
+}
+
+blockquote footer:before,
+blockquote small:before,
+blockquote .small:before {
+ content: '\2014 \00A0';
+}
+
+.blockquote-reverse,
+blockquote.pull-right {
+ padding-right: 15px;
+ padding-left: 0;
+ border-right: 5px solid #eeeeee;
+ border-left: 0;
+ text-align: right;
+}
+
+.blockquote-reverse footer:before,
+blockquote.pull-right footer:before,
+.blockquote-reverse small:before,
+blockquote.pull-right small:before,
+.blockquote-reverse .small:before,
+blockquote.pull-right .small:before {
+ content: '';
+}
+
+.blockquote-reverse footer:after,
+blockquote.pull-right footer:after,
+.blockquote-reverse small:after,
+blockquote.pull-right small:after,
+.blockquote-reverse .small:after,
+blockquote.pull-right .small:after {
+ content: '\00A0 \2014';
+}
+
+address {
+ margin-bottom: 20px;
+ font-style: normal;
+ line-height: 1.42857143;
+}
+
+code,
+kbd,
+pre,
+samp {
+ font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+}
+
+code {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #c7254e;
+ background-color: #f9f2f4;
+ border-radius: 4px;
+}
+
+kbd {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #ffffff;
+ background-color: #333333;
+ border-radius: 2px;
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
+}
+
+kbd kbd {
+ padding: 0;
+ font-size: 100%;
+ font-weight: bold;
+ box-shadow: none;
+}
+
+pre {
+ display: block;
+ padding: 9.5px;
+ margin: 0 0 10px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ word-break: break-all;
+ word-wrap: break-word;
+ color: #333333;
+ background-color: #f5f5f5;
+ border: 1px solid #cccccc;
+ border-radius: 4px;
+}
+
+pre code {
+ padding: 0;
+ font-size: inherit;
+ color: inherit;
+ white-space: pre-wrap;
+ background-color: transparent;
+ border-radius: 0;
+}
+
+.pre-scrollable {
+ max-height: 340px;
+ overflow-y: scroll;
+}
+
+.container {
+ margin-right: auto;
+ margin-left: auto;
+ padding-left: 15px;
+ padding-right: 15px;
+}
+
+@media (min-width: 768px) {
+ .container {
+ width: 750px;
+ }
+}
+
+@media (min-width: 992px) {
+ .container {
+ width: 970px;
+ }
+}
+
+@media (min-width: 1200px) {
+ .container {
+ width: 1170px;
+ }
+}
+
+.container-fluid {
+ margin-right: auto;
+ margin-left: auto;
+ padding-left: 15px;
+ padding-right: 15px;
+}
+
+.row {
+ margin-left: -15px;
+ margin-right: -15px;
+}
+
+.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
+ position: relative;
+ min-height: 1px;
+ padding-left: 15px;
+ padding-right: 15px;
+}
+
+.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
+ float: left;
+}
+
+.col-xs-12 {
+ width: 100%;
+}
+
+.col-xs-11 {
+ width: 91.66666667%;
+}
+
+.col-xs-10 {
+ width: 83.33333333%;
+}
+
+.col-xs-9 {
+ width: 75%;
+}
+
+.col-xs-8 {
+ width: 66.66666667%;
+}
+
+.col-xs-7 {
+ width: 58.33333333%;
+}
+
+.col-xs-6 {
+ width: 50%;
+}
+
+.col-xs-5 {
+ width: 41.66666667%;
+}
+
+.col-xs-4 {
+ width: 33.33333333%;
+}
+
+.col-xs-3 {
+ width: 25%;
+}
+
+.col-xs-2 {
+ width: 16.66666667%;
+}
+
+.col-xs-1 {
+ width: 8.33333333%;
+}
+
+.col-xs-pull-12 {
+ right: 100%;
+}
+
+.col-xs-pull-11 {
+ right: 91.66666667%;
+}
+
+.col-xs-pull-10 {
+ right: 83.33333333%;
+}
+
+.col-xs-pull-9 {
+ right: 75%;
+}
+
+.col-xs-pull-8 {
+ right: 66.66666667%;
+}
+
+.col-xs-pull-7 {
+ right: 58.33333333%;
+}
+
+.col-xs-pull-6 {
+ right: 50%;
+}
+
+.col-xs-pull-5 {
+ right: 41.66666667%;
+}
+
+.col-xs-pull-4 {
+ right: 33.33333333%;
+}
+
+.col-xs-pull-3 {
+ right: 25%;
+}
+
+.col-xs-pull-2 {
+ right: 16.66666667%;
+}
+
+.col-xs-pull-1 {
+ right: 8.33333333%;
+}
+
+.col-xs-pull-0 {
+ right: auto;
+}
+
+.col-xs-push-12 {
+ left: 100%;
+}
+
+.col-xs-push-11 {
+ left: 91.66666667%;
+}
+
+.col-xs-push-10 {
+ left: 83.33333333%;
+}
+
+.col-xs-push-9 {
+ left: 75%;
+}
+
+.col-xs-push-8 {
+ left: 66.66666667%;
+}
+
+.col-xs-push-7 {
+ left: 58.33333333%;
+}
+
+.col-xs-push-6 {
+ left: 50%;
+}
+
+.col-xs-push-5 {
+ left: 41.66666667%;
+}
+
+.col-xs-push-4 {
+ left: 33.33333333%;
+}
+
+.col-xs-push-3 {
+ left: 25%;
+}
+
+.col-xs-push-2 {
+ left: 16.66666667%;
+}
+
+.col-xs-push-1 {
+ left: 8.33333333%;
+}
+
+.col-xs-push-0 {
+ left: auto;
+}
+
+.col-xs-offset-12 {
+ margin-left: 100%;
+}
+
+.col-xs-offset-11 {
+ margin-left: 91.66666667%;
+}
+
+.col-xs-offset-10 {
+ margin-left: 83.33333333%;
+}
+
+.col-xs-offset-9 {
+ margin-left: 75%;
+}
+
+.col-xs-offset-8 {
+ margin-left: 66.66666667%;
+}
+
+.col-xs-offset-7 {
+ margin-left: 58.33333333%;
+}
+
+.col-xs-offset-6 {
+ margin-left: 50%;
+}
+
+.col-xs-offset-5 {
+ margin-left: 41.66666667%;
+}
+
+.col-xs-offset-4 {
+ margin-left: 33.33333333%;
+}
+
+.col-xs-offset-3 {
+ margin-left: 25%;
+}
+
+.col-xs-offset-2 {
+ margin-left: 16.66666667%;
+}
+
+.col-xs-offset-1 {
+ margin-left: 8.33333333%;
+}
+
+.col-xs-offset-0 {
+ margin-left: 0%;
+}
+
+@media (min-width: 768px) {
+ .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
+ float: left;
+ }
+
+ .col-sm-12 {
+ width: 100%;
+ }
+
+ .col-sm-11 {
+ width: 91.66666667%;
+ }
+
+ .col-sm-10 {
+ width: 83.33333333%;
+ }
+
+ .col-sm-9 {
+ width: 75%;
+ }
+
+ .col-sm-8 {
+ width: 66.66666667%;
+ }
+
+ .col-sm-7 {
+ width: 58.33333333%;
+ }
+
+ .col-sm-6 {
+ width: 50%;
+ }
+
+ .col-sm-5 {
+ width: 41.66666667%;
+ }
+
+ .col-sm-4 {
+ width: 33.33333333%;
+ }
+
+ .col-sm-3 {
+ width: 25%;
+ }
+
+ .col-sm-2 {
+ width: 16.66666667%;
+ }
+
+ .col-sm-1 {
+ width: 8.33333333%;
+ }
+
+ .col-sm-pull-12 {
+ right: 100%;
+ }
+
+ .col-sm-pull-11 {
+ right: 91.66666667%;
+ }
+
+ .col-sm-pull-10 {
+ right: 83.33333333%;
+ }
+
+ .col-sm-pull-9 {
+ right: 75%;
+ }
+
+ .col-sm-pull-8 {
+ right: 66.66666667%;
+ }
+
+ .col-sm-pull-7 {
+ right: 58.33333333%;
+ }
+
+ .col-sm-pull-6 {
+ right: 50%;
+ }
+
+ .col-sm-pull-5 {
+ right: 41.66666667%;
+ }
+
+ .col-sm-pull-4 {
+ right: 33.33333333%;
+ }
+
+ .col-sm-pull-3 {
+ right: 25%;
+ }
+
+ .col-sm-pull-2 {
+ right: 16.66666667%;
+ }
+
+ .col-sm-pull-1 {
+ right: 8.33333333%;
+ }
+
+ .col-sm-pull-0 {
+ right: auto;
+ }
+
+ .col-sm-push-12 {
+ left: 100%;
+ }
+
+ .col-sm-push-11 {
+ left: 91.66666667%;
+ }
+
+ .col-sm-push-10 {
+ left: 83.33333333%;
+ }
+
+ .col-sm-push-9 {
+ left: 75%;
+ }
+
+ .col-sm-push-8 {
+ left: 66.66666667%;
+ }
+
+ .col-sm-push-7 {
+ left: 58.33333333%;
+ }
+
+ .col-sm-push-6 {
+ left: 50%;
+ }
+
+ .col-sm-push-5 {
+ left: 41.66666667%;
+ }
+
+ .col-sm-push-4 {
+ left: 33.33333333%;
+ }
+
+ .col-sm-push-3 {
+ left: 25%;
+ }
+
+ .col-sm-push-2 {
+ left: 16.66666667%;
+ }
+
+ .col-sm-push-1 {
+ left: 8.33333333%;
+ }
+
+ .col-sm-push-0 {
+ left: auto;
+ }
+
+ .col-sm-offset-12 {
+ margin-left: 100%;
+ }
+
+ .col-sm-offset-11 {
+ margin-left: 91.66666667%;
+ }
+
+ .col-sm-offset-10 {
+ margin-left: 83.33333333%;
+ }
+
+ .col-sm-offset-9 {
+ margin-left: 75%;
+ }
+
+ .col-sm-offset-8 {
+ margin-left: 66.66666667%;
+ }
+
+ .col-sm-offset-7 {
+ margin-left: 58.33333333%;
+ }
+
+ .col-sm-offset-6 {
+ margin-left: 50%;
+ }
+
+ .col-sm-offset-5 {
+ margin-left: 41.66666667%;
+ }
+
+ .col-sm-offset-4 {
+ margin-left: 33.33333333%;
+ }
+
+ .col-sm-offset-3 {
+ margin-left: 25%;
+ }
+
+ .col-sm-offset-2 {
+ margin-left: 16.66666667%;
+ }
+
+ .col-sm-offset-1 {
+ margin-left: 8.33333333%;
+ }
+
+ .col-sm-offset-0 {
+ margin-left: 0%;
+ }
+}
+
+@media (min-width: 992px) {
+ .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
+ float: left;
+ }
+
+ .col-md-12 {
+ width: 100%;
+ }
+
+ .col-md-11 {
+ width: 91.66666667%;
+ }
+
+ .col-md-10 {
+ width: 83.33333333%;
+ }
+
+ .col-md-9 {
+ width: 75%;
+ }
+
+ .col-md-8 {
+ width: 66.66666667%;
+ }
+
+ .col-md-7 {
+ width: 58.33333333%;
+ }
+
+ .col-md-6 {
+ width: 50%;
+ }
+
+ .col-md-5 {
+ width: 41.66666667%;
+ }
+
+ .col-md-4 {
+ width: 33.33333333%;
+ }
+
+ .col-md-3 {
+ width: 25%;
+ }
+
+ .col-md-2 {
+ width: 16.66666667%;
+ }
+
+ .col-md-1 {
+ width: 8.33333333%;
+ }
+
+ .col-md-pull-12 {
+ right: 100%;
+ }
+
+ .col-md-pull-11 {
+ right: 91.66666667%;
+ }
+
+ .col-md-pull-10 {
+ right: 83.33333333%;
+ }
+
+ .col-md-pull-9 {
+ right: 75%;
+ }
+
+ .col-md-pull-8 {
+ right: 66.66666667%;
+ }
+
+ .col-md-pull-7 {
+ right: 58.33333333%;
+ }
+
+ .col-md-pull-6 {
+ right: 50%;
+ }
+
+ .col-md-pull-5 {
+ right: 41.66666667%;
+ }
+
+ .col-md-pull-4 {
+ right: 33.33333333%;
+ }
+
+ .col-md-pull-3 {
+ right: 25%;
+ }
+
+ .col-md-pull-2 {
+ right: 16.66666667%;
+ }
+
+ .col-md-pull-1 {
+ right: 8.33333333%;
+ }
+
+ .col-md-pull-0 {
+ right: auto;
+ }
+
+ .col-md-push-12 {
+ left: 100%;
+ }
+
+ .col-md-push-11 {
+ left: 91.66666667%;
+ }
+
+ .col-md-push-10 {
+ left: 83.33333333%;
+ }
+
+ .col-md-push-9 {
+ left: 75%;
+ }
+
+ .col-md-push-8 {
+ left: 66.66666667%;
+ }
+
+ .col-md-push-7 {
+ left: 58.33333333%;
+ }
+
+ .col-md-push-6 {
+ left: 50%;
+ }
+
+ .col-md-push-5 {
+ left: 41.66666667%;
+ }
+
+ .col-md-push-4 {
+ left: 33.33333333%;
+ }
+
+ .col-md-push-3 {
+ left: 25%;
+ }
+
+ .col-md-push-2 {
+ left: 16.66666667%;
+ }
+
+ .col-md-push-1 {
+ left: 8.33333333%;
+ }
+
+ .col-md-push-0 {
+ left: auto;
+ }
+
+ .col-md-offset-12 {
+ margin-left: 100%;
+ }
+
+ .col-md-offset-11 {
+ margin-left: 91.66666667%;
+ }
+
+ .col-md-offset-10 {
+ margin-left: 83.33333333%;
+ }
+
+ .col-md-offset-9 {
+ margin-left: 75%;
+ }
+
+ .col-md-offset-8 {
+ margin-left: 66.66666667%;
+ }
+
+ .col-md-offset-7 {
+ margin-left: 58.33333333%;
+ }
+
+ .col-md-offset-6 {
+ margin-left: 50%;
+ }
+
+ .col-md-offset-5 {
+ margin-left: 41.66666667%;
+ }
+
+ .col-md-offset-4 {
+ margin-left: 33.33333333%;
+ }
+
+ .col-md-offset-3 {
+ margin-left: 25%;
+ }
+
+ .col-md-offset-2 {
+ margin-left: 16.66666667%;
+ }
+
+ .col-md-offset-1 {
+ margin-left: 8.33333333%;
+ }
+
+ .col-md-offset-0 {
+ margin-left: 0%;
+ }
+}
+
+@media (min-width: 1200px) {
+ .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
+ float: left;
+ }
+
+ .col-lg-12 {
+ width: 100%;
+ }
+
+ .col-lg-11 {
+ width: 91.66666667%;
+ }
+
+ .col-lg-10 {
+ width: 83.33333333%;
+ }
+
+ .col-lg-9 {
+ width: 75%;
+ }
+
+ .col-lg-8 {
+ width: 66.66666667%;
+ }
+
+ .col-lg-7 {
+ width: 58.33333333%;
+ }
+
+ .col-lg-6 {
+ width: 50%;
+ }
+
+ .col-lg-5 {
+ width: 41.66666667%;
+ }
+
+ .col-lg-4 {
+ width: 33.33333333%;
+ }
+
+ .col-lg-3 {
+ width: 25%;
+ }
+
+ .col-lg-2 {
+ width: 16.66666667%;
+ }
+
+ .col-lg-1 {
+ width: 8.33333333%;
+ }
+
+ .col-lg-pull-12 {
+ right: 100%;
+ }
+
+ .col-lg-pull-11 {
+ right: 91.66666667%;
+ }
+
+ .col-lg-pull-10 {
+ right: 83.33333333%;
+ }
+
+ .col-lg-pull-9 {
+ right: 75%;
+ }
+
+ .col-lg-pull-8 {
+ right: 66.66666667%;
+ }
+
+ .col-lg-pull-7 {
+ right: 58.33333333%;
+ }
+
+ .col-lg-pull-6 {
+ right: 50%;
+ }
+
+ .col-lg-pull-5 {
+ right: 41.66666667%;
+ }
+
+ .col-lg-pull-4 {
+ right: 33.33333333%;
+ }
+
+ .col-lg-pull-3 {
+ right: 25%;
+ }
+
+ .col-lg-pull-2 {
+ right: 16.66666667%;
+ }
+
+ .col-lg-pull-1 {
+ right: 8.33333333%;
+ }
+
+ .col-lg-pull-0 {
+ right: auto;
+ }
+
+ .col-lg-push-12 {
+ left: 100%;
+ }
+
+ .col-lg-push-11 {
+ left: 91.66666667%;
+ }
+
+ .col-lg-push-10 {
+ left: 83.33333333%;
+ }
+
+ .col-lg-push-9 {
+ left: 75%;
+ }
+
+ .col-lg-push-8 {
+ left: 66.66666667%;
+ }
+
+ .col-lg-push-7 {
+ left: 58.33333333%;
+ }
+
+ .col-lg-push-6 {
+ left: 50%;
+ }
+
+ .col-lg-push-5 {
+ left: 41.66666667%;
+ }
+
+ .col-lg-push-4 {
+ left: 33.33333333%;
+ }
+
+ .col-lg-push-3 {
+ left: 25%;
+ }
+
+ .col-lg-push-2 {
+ left: 16.66666667%;
+ }
+
+ .col-lg-push-1 {
+ left: 8.33333333%;
+ }
+
+ .col-lg-push-0 {
+ left: auto;
+ }
+
+ .col-lg-offset-12 {
+ margin-left: 100%;
+ }
+
+ .col-lg-offset-11 {
+ margin-left: 91.66666667%;
+ }
+
+ .col-lg-offset-10 {
+ margin-left: 83.33333333%;
+ }
+
+ .col-lg-offset-9 {
+ margin-left: 75%;
+ }
+
+ .col-lg-offset-8 {
+ margin-left: 66.66666667%;
+ }
+
+ .col-lg-offset-7 {
+ margin-left: 58.33333333%;
+ }
+
+ .col-lg-offset-6 {
+ margin-left: 50%;
+ }
+
+ .col-lg-offset-5 {
+ margin-left: 41.66666667%;
+ }
+
+ .col-lg-offset-4 {
+ margin-left: 33.33333333%;
+ }
+
+ .col-lg-offset-3 {
+ margin-left: 25%;
+ }
+
+ .col-lg-offset-2 {
+ margin-left: 16.66666667%;
+ }
+
+ .col-lg-offset-1 {
+ margin-left: 8.33333333%;
+ }
+
+ .col-lg-offset-0 {
+ margin-left: 0%;
+ }
+}
+
+table {
+ background-color: transparent;
+}
+
+caption {
+ padding-top: 8px;
+ padding-bottom: 8px;
+ color: #777777;
+ text-align: left;
+}
+
+th {
+ text-align: left;
+}
+
+.table {
+ width: 100%;
+ max-width: 100%;
+ margin-bottom: 20px;
+}
+
+.table > thead > tr > th,
+.table > tbody > tr > th,
+.table > tfoot > tr > th,
+.table > thead > tr > td,
+.table > tbody > tr > td,
+.table > tfoot > tr > td {
+ padding: 8px;
+ line-height: 1.42857143;
+ vertical-align: top;
+ border-top: 1px solid #dddddd;
+}
+
+.table > thead > tr > th {
+ vertical-align: bottom;
+ border-bottom: 2px solid #dddddd;
+}
+
+.table > caption + thead > tr:first-child > th,
+.table > colgroup + thead > tr:first-child > th,
+.table > thead:first-child > tr:first-child > th,
+.table > caption + thead > tr:first-child > td,
+.table > colgroup + thead > tr:first-child > td,
+.table > thead:first-child > tr:first-child > td {
+ border-top: 0;
+}
+
+.table > tbody + tbody {
+ border-top: 2px solid #dddddd;
+}
+
+.table .table {
+ background-color: #ffffff;
+}
+
+.table-condensed > thead > tr > th,
+.table-condensed > tbody > tr > th,
+.table-condensed > tfoot > tr > th,
+.table-condensed > thead > tr > td,
+.table-condensed > tbody > tr > td,
+.table-condensed > tfoot > tr > td {
+ padding: 5px;
+}
+
+.table-bordered {
+ border: 1px solid #dddddd;
+}
+
+.table-bordered > thead > tr > th,
+.table-bordered > tbody > tr > th,
+.table-bordered > tfoot > tr > th,
+.table-bordered > thead > tr > td,
+.table-bordered > tbody > tr > td,
+.table-bordered > tfoot > tr > td {
+ border: 1px solid #dddddd;
+}
+
+.table-bordered > thead > tr > th,
+.table-bordered > thead > tr > td {
+ border-bottom-width: 2px;
+}
+
+.table-striped > tbody > tr:nth-of-type(odd) {
+ background-color: #f9f9f9;
+}
+
+.table-hover > tbody > tr:hover {
+ background-color: #f5f5f5;
+}
+
+table col[class*="col-"] {
+ position: static;
+ float: none;
+ display: table-column;
+}
+
+table td[class*="col-"],
+table th[class*="col-"] {
+ position: static;
+ float: none;
+ display: table-cell;
+}
+
+.table > thead > tr > td.active,
+.table > tbody > tr > td.active,
+.table > tfoot > tr > td.active,
+.table > thead > tr > th.active,
+.table > tbody > tr > th.active,
+.table > tfoot > tr > th.active,
+.table > thead > tr.active > td,
+.table > tbody > tr.active > td,
+.table > tfoot > tr.active > td,
+.table > thead > tr.active > th,
+.table > tbody > tr.active > th,
+.table > tfoot > tr.active > th {
+ background-color: #f5f5f5;
+}
+
+.table-hover > tbody > tr > td.active:hover,
+.table-hover > tbody > tr > th.active:hover,
+.table-hover > tbody > tr.active:hover > td,
+.table-hover > tbody > tr:hover > .active,
+.table-hover > tbody > tr.active:hover > th {
+ background-color: #e8e8e8;
+}
+
+.table > thead > tr > td.success,
+.table > tbody > tr > td.success,
+.table > tfoot > tr > td.success,
+.table > thead > tr > th.success,
+.table > tbody > tr > th.success,
+.table > tfoot > tr > th.success,
+.table > thead > tr.success > td,
+.table > tbody > tr.success > td,
+.table > tfoot > tr.success > td,
+.table > thead > tr.success > th,
+.table > tbody > tr.success > th,
+.table > tfoot > tr.success > th {
+ background-color: #a3d7a3;
+}
+
+.table-hover > tbody > tr > td.success:hover,
+.table-hover > tbody > tr > th.success:hover,
+.table-hover > tbody > tr.success:hover > td,
+.table-hover > tbody > tr:hover > .success,
+.table-hover > tbody > tr.success:hover > th {
+ background-color: #91cf91;
+}
+
+.table > thead > tr > td.info,
+.table > tbody > tr > td.info,
+.table > tfoot > tr > td.info,
+.table > thead > tr > th.info,
+.table > tbody > tr > th.info,
+.table > tfoot > tr > th.info,
+.table > thead > tr.info > td,
+.table > tbody > tr.info > td,
+.table > tfoot > tr.info > td,
+.table > thead > tr.info > th,
+.table > tbody > tr.info > th,
+.table > tfoot > tr.info > th {
+ background-color: #b0e1ef;
+}
+
+.table-hover > tbody > tr > td.info:hover,
+.table-hover > tbody > tr > th.info:hover,
+.table-hover > tbody > tr.info:hover > td,
+.table-hover > tbody > tr:hover > .info,
+.table-hover > tbody > tr.info:hover > th {
+ background-color: #9bd8eb;
+}
+
+.table > thead > tr > td.warning,
+.table > tbody > tr > td.warning,
+.table > tfoot > tr > td.warning,
+.table > thead > tr > th.warning,
+.table > tbody > tr > th.warning,
+.table > tfoot > tr > th.warning,
+.table > thead > tr.warning > td,
+.table > tbody > tr.warning > td,
+.table > tfoot > tr.warning > td,
+.table > thead > tr.warning > th,
+.table > tbody > tr.warning > th,
+.table > tfoot > tr.warning > th {
+ background-color: #f8d9ac;
+}
+
+.table-hover > tbody > tr > td.warning:hover,
+.table-hover > tbody > tr > th.warning:hover,
+.table-hover > tbody > tr.warning:hover > td,
+.table-hover > tbody > tr:hover > .warning,
+.table-hover > tbody > tr.warning:hover > th {
+ background-color: #f6ce95;
+}
+
+.table > thead > tr > td.danger,
+.table > tbody > tr > td.danger,
+.table > tfoot > tr > td.danger,
+.table > thead > tr > th.danger,
+.table > tbody > tr > th.danger,
+.table > tfoot > tr > th.danger,
+.table > thead > tr.danger > td,
+.table > tbody > tr.danger > td,
+.table > tfoot > tr.danger > td,
+.table > thead > tr.danger > th,
+.table > tbody > tr.danger > th,
+.table > tfoot > tr.danger > th {
+ background-color: #eba5a3;
+}
+
+.table-hover > tbody > tr > td.danger:hover,
+.table-hover > tbody > tr > th.danger:hover,
+.table-hover > tbody > tr.danger:hover > td,
+.table-hover > tbody > tr:hover > .danger,
+.table-hover > tbody > tr.danger:hover > th {
+ background-color: #e7908e;
+}
+
+.table-responsive {
+ overflow-x: auto;
+ min-height: 0.01%;
+}
+
+@media screen and (max-width: 767px) {
+ .table-responsive {
+ width: 100%;
+ margin-bottom: 15px;
+ overflow-y: hidden;
+ -ms-overflow-style: -ms-autohiding-scrollbar;
+ border: 1px solid #dddddd;
+ }
+
+ .table-responsive > .table {
+ margin-bottom: 0;
+ }
+
+ .table-responsive > .table > thead > tr > th,
+ .table-responsive > .table > tbody > tr > th,
+ .table-responsive > .table > tfoot > tr > th,
+ .table-responsive > .table > thead > tr > td,
+ .table-responsive > .table > tbody > tr > td,
+ .table-responsive > .table > tfoot > tr > td {
+ white-space: nowrap;
+ }
+
+ .table-responsive > .table-bordered {
+ border: 0;
+ }
+
+ .table-responsive > .table-bordered > thead > tr > th:first-child,
+ .table-responsive > .table-bordered > tbody > tr > th:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+ .table-responsive > .table-bordered > thead > tr > td:first-child,
+ .table-responsive > .table-bordered > tbody > tr > td:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+ }
+
+ .table-responsive > .table-bordered > thead > tr > th:last-child,
+ .table-responsive > .table-bordered > tbody > tr > th:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+ .table-responsive > .table-bordered > thead > tr > td:last-child,
+ .table-responsive > .table-bordered > tbody > tr > td:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+ }
+
+ .table-responsive > .table-bordered > tbody > tr:last-child > th,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > th,
+ .table-responsive > .table-bordered > tbody > tr:last-child > td,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+ border-bottom: 0;
+ }
+}
+
+fieldset {
+ padding: 0;
+ margin: 0;
+ border: 0;
+ min-width: 0;
+}
+
+legend {
+ display: block;
+ width: 100%;
+ padding: 0;
+ margin-bottom: 20px;
+ font-size: 21px;
+ line-height: inherit;
+ color: #333333;
+ border: 0;
+ border-bottom: 1px solid #e5e5e5;
+}
+
+label {
+ display: inline-block;
+ max-width: 100%;
+ margin-bottom: 5px;
+ font-weight: bold;
+}
+
+input[type="search"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+input[type="radio"],
+input[type="checkbox"] {
+ margin: 4px 0 0;
+ margin-top: 1px \9;
+ line-height: normal;
+}
+
+input[type="file"] {
+ display: block;
+}
+
+input[type="range"] {
+ display: block;
+ width: 100%;
+}
+
+select[multiple],
+select[size] {
+ height: auto;
+}
+
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+output {
+ display: block;
+ padding-top: 7px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555555;
+}
+
+.form-control {
+ display: block;
+ width: 100%;
+ height: 34px;
+ padding: 6px 12px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555555;
+ background-color: #ffffff;
+ background-image: none;
+ border: 1px solid #cccccc;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+
+.form-control:focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);
+}
+
+.form-control::-moz-placeholder {
+ color: #999999;
+ opacity: 1;
+}
+
+.form-control:-ms-input-placeholder {
+ color: #999999;
+}
+
+.form-control::-webkit-input-placeholder {
+ color: #999999;
+}
+
+.form-control[disabled],
+.form-control[readonly],
+fieldset[disabled] .form-control {
+ background-color: #eeeeee;
+ opacity: 1;
+}
+
+.form-control[disabled],
+fieldset[disabled] .form-control {
+ cursor: not-allowed;
+}
+
+textarea.form-control {
+ height: auto;
+}
+
+input[type="search"] {
+ -webkit-appearance: none;
+}
+
+@media screen and (-webkit-min-device-pixel-ratio: 0) {
+ input[type="date"],
+ input[type="time"],
+ input[type="datetime-local"],
+ input[type="month"] {
+ line-height: 34px;
+ }
+
+ input[type="date"].input-sm,
+ input[type="time"].input-sm,
+ input[type="datetime-local"].input-sm,
+ input[type="month"].input-sm,
+ .input-group-sm input[type="date"],
+ .input-group-sm input[type="time"],
+ .input-group-sm input[type="datetime-local"],
+ .input-group-sm input[type="month"] {
+ line-height: 30px;
+ }
+
+ input[type="date"].input-lg,
+ input[type="time"].input-lg,
+ input[type="datetime-local"].input-lg,
+ input[type="month"].input-lg,
+ .input-group-lg input[type="date"],
+ .input-group-lg input[type="time"],
+ .input-group-lg input[type="datetime-local"],
+ .input-group-lg input[type="month"] {
+ line-height: 46px;
+ }
+}
+
+.form-group {
+ margin-bottom: 15px;
+}
+
+.radio,
+.checkbox {
+ position: relative;
+ display: block;
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+.radio label,
+.checkbox label {
+ min-height: 20px;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ cursor: pointer;
+}
+
+.radio input[type="radio"],
+.radio-inline input[type="radio"],
+.checkbox input[type="checkbox"],
+.checkbox-inline input[type="checkbox"] {
+ position: absolute;
+ margin-left: -20px;
+ margin-top: 4px \9;
+}
+
+.radio + .radio,
+.checkbox + .checkbox {
+ margin-top: -5px;
+}
+
+.radio-inline,
+.checkbox-inline {
+ position: relative;
+ display: inline-block;
+ padding-left: 20px;
+ margin-bottom: 0;
+ vertical-align: middle;
+ font-weight: normal;
+ cursor: pointer;
+}
+
+.radio-inline + .radio-inline,
+.checkbox-inline + .checkbox-inline {
+ margin-top: 0;
+ margin-left: 10px;
+}
+
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+input[type="radio"].disabled,
+input[type="checkbox"].disabled,
+fieldset[disabled] input[type="radio"],
+fieldset[disabled] input[type="checkbox"] {
+ cursor: not-allowed;
+}
+
+.radio-inline.disabled,
+.checkbox-inline.disabled,
+fieldset[disabled] .radio-inline,
+fieldset[disabled] .checkbox-inline {
+ cursor: not-allowed;
+}
+
+.radio.disabled label,
+.checkbox.disabled label,
+fieldset[disabled] .radio label,
+fieldset[disabled] .checkbox label {
+ cursor: not-allowed;
+}
+
+.form-control-static {
+ padding-top: 7px;
+ padding-bottom: 7px;
+ margin-bottom: 0;
+ min-height: 34px;
+}
+
+.form-control-static.input-lg,
+.form-control-static.input-sm {
+ padding-left: 0;
+ padding-right: 0;
+}
+
+.input-sm {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 2px;
+}
+
+select.input-sm {
+ height: 30px;
+ line-height: 30px;
+}
+
+textarea.input-sm,
+select[multiple].input-sm {
+ height: auto;
+}
+
+.form-group-sm .form-control {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 2px;
+}
+
+select.form-group-sm .form-control {
+ height: 30px;
+ line-height: 30px;
+}
+
+textarea.form-group-sm .form-control,
+select[multiple].form-group-sm .form-control {
+ height: auto;
+}
+
+.form-group-sm .form-control-static {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ min-height: 32px;
+}
+
+.input-lg {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 5px;
+}
+
+select.input-lg {
+ height: 46px;
+ line-height: 46px;
+}
+
+textarea.input-lg,
+select[multiple].input-lg {
+ height: auto;
+}
+
+.form-group-lg .form-control {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 5px;
+}
+
+select.form-group-lg .form-control {
+ height: 46px;
+ line-height: 46px;
+}
+
+textarea.form-group-lg .form-control,
+select[multiple].form-group-lg .form-control {
+ height: auto;
+}
+
+.form-group-lg .form-control-static {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ min-height: 38px;
+}
+
+.has-feedback {
+ position: relative;
+}
+
+.has-feedback .form-control {
+ padding-right: 42.5px;
+}
+
+.form-control-feedback {
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: 2;
+ display: block;
+ width: 34px;
+ height: 34px;
+ line-height: 34px;
+ text-align: center;
+ pointer-events: none;
+}
+
+.input-lg + .form-control-feedback {
+ width: 46px;
+ height: 46px;
+ line-height: 46px;
+}
+
+.input-sm + .form-control-feedback {
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+}
+
+.has-success .help-block,
+.has-success .control-label,
+.has-success .radio,
+.has-success .checkbox,
+.has-success .radio-inline,
+.has-success .checkbox-inline,
+.has-success.radio label,
+.has-success.checkbox label,
+.has-success.radio-inline label,
+.has-success.checkbox-inline label {
+ color: #5cb85c;
+}
+
+.has-success .form-control {
+ border-color: #5cb85c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+
+.has-success .form-control:focus {
+ border-color: #449d44;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #a3d7a3;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #a3d7a3;
+}
+
+.has-success .input-group-addon {
+ color: #5cb85c;
+ border-color: #5cb85c;
+ background-color: #a3d7a3;
+}
+
+.has-success .form-control-feedback {
+ color: #5cb85c;
+}
+
+.has-warning .help-block,
+.has-warning .control-label,
+.has-warning .radio,
+.has-warning .checkbox,
+.has-warning .radio-inline,
+.has-warning .checkbox-inline,
+.has-warning.radio label,
+.has-warning.checkbox label,
+.has-warning.radio-inline label,
+.has-warning.checkbox-inline label {
+ color: #f0ad4e;
+}
+
+.has-warning .form-control {
+ border-color: #f0ad4e;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+
+.has-warning .form-control:focus {
+ border-color: #ec971f;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f8d9ac;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f8d9ac;
+}
+
+.has-warning .input-group-addon {
+ color: #f0ad4e;
+ border-color: #f0ad4e;
+ background-color: #f8d9ac;
+}
+
+.has-warning .form-control-feedback {
+ color: #f0ad4e;
+}
+
+.has-error .help-block,
+.has-error .control-label,
+.has-error .radio,
+.has-error .checkbox,
+.has-error .radio-inline,
+.has-error .checkbox-inline,
+.has-error.radio label,
+.has-error.checkbox label,
+.has-error.radio-inline label,
+.has-error.checkbox-inline label {
+ color: #d9534f;
+}
+
+.has-error .form-control {
+ border-color: #d9534f;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+
+.has-error .form-control:focus {
+ border-color: #c9302c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #eba5a3;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #eba5a3;
+}
+
+.has-error .input-group-addon {
+ color: #d9534f;
+ border-color: #d9534f;
+ background-color: #eba5a3;
+}
+
+.has-error .form-control-feedback {
+ color: #d9534f;
+}
+
+.has-feedback label ~ .form-control-feedback {
+ top: 25px;
+}
+
+.has-feedback label.sr-only ~ .form-control-feedback {
+ top: 0;
+}
+
+.help-block {
+ display: block;
+ margin-top: 5px;
+ margin-bottom: 10px;
+ color: #404040;
+}
+
+@media (min-width: 768px) {
+ .form-inline .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .form-inline .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+
+ .form-inline .form-control-static {
+ display: inline-block;
+ }
+
+ .form-inline .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+
+ .form-inline .input-group .input-group-addon,
+ .form-inline .input-group .input-group-btn,
+ .form-inline .input-group .form-control {
+ width: auto;
+ }
+
+ .form-inline .input-group > .form-control {
+ width: 100%;
+ }
+
+ .form-inline .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .form-inline .radio,
+ .form-inline .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .form-inline .radio label,
+ .form-inline .checkbox label {
+ padding-left: 0;
+ }
+
+ .form-inline .radio input[type="radio"],
+ .form-inline .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+
+ .form-inline .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+
+.form-horizontal .radio,
+.form-horizontal .checkbox,
+.form-horizontal .radio-inline,
+.form-horizontal .checkbox-inline {
+ margin-top: 0;
+ margin-bottom: 0;
+ padding-top: 7px;
+}
+
+.form-horizontal .radio,
+.form-horizontal .checkbox {
+ min-height: 27px;
+}
+
+.form-horizontal .form-group {
+ margin-left: -15px;
+ margin-right: -15px;
+}
+
+@media (min-width: 768px) {
+ .form-horizontal .control-label {
+ text-align: right;
+ margin-bottom: 0;
+ padding-top: 7px;
+ }
+}
+
+.form-horizontal .has-feedback .form-control-feedback {
+ right: 15px;
+}
+
+@media (min-width: 768px) {
+ .form-horizontal .form-group-lg .control-label {
+ padding-top: 14.333333px;
+ }
+}
+
+@media (min-width: 768px) {
+ .form-horizontal .form-group-sm .control-label {
+ padding-top: 6px;
+ }
+}
+
+.btn {
+ display: inline-block;
+ margin-bottom: 0;
+ font-weight: normal;
+ text-align: center;
+ vertical-align: middle;
+ touch-action: manipulation;
+ cursor: pointer;
+ background-image: none;
+ border: 1px solid transparent;
+ white-space: nowrap;
+ padding: 6px 12px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ border-radius: 4px;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.btn:focus,
+.btn:active:focus,
+.btn.active:focus,
+.btn.focus,
+.btn:active.focus,
+.btn.active.focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+.btn:hover,
+.btn:focus,
+.btn.focus {
+ color: #000000;
+ text-decoration: none;
+}
+
+.btn:active,
+.btn.active {
+ outline: 0;
+ background-image: none;
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+}
+
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+ cursor: not-allowed;
+ pointer-events: none;
+ opacity: 0.65;
+ filter: alpha(opacity=65);
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.btn-default {
+ color: #ffffff;
+ background-color: #a0ced7;
+ border-color: #9dc8ce;
+}
+
+.btn-default:hover,
+.btn-default:focus,
+.btn-default.focus,
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ color: #ffffff;
+ background-color: #1a6687;
+ border-color: #1a6687;
+}
+
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ background-image: none;
+}
+
+.btn-default.disabled,
+.btn-default[disabled],
+fieldset[disabled] .btn-default,
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled.focus,
+.btn-default[disabled].focus,
+fieldset[disabled] .btn-default.focus,
+.btn-default.disabled:active,
+.btn-default[disabled]:active,
+fieldset[disabled] .btn-default:active,
+.btn-default.disabled.active,
+.btn-default[disabled].active,
+fieldset[disabled] .btn-default.active {
+ background-color: #ffffff;
+ border-color: #a0ced7;
+}
+
+.btn-default .badge {
+ color: #ffffff;
+ background-color: #000000;
+}
+
+.btn-primary {
+ color: #ffffff;
+ background-color: #8bc4c9;
+ border-color: #9dc8ce;
+}
+
+.btn-primary:hover,
+.btn-primary:focus,
+.btn-primary.focus,
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ color: #ffffff;
+ background-color: #1a6687;
+ border-color: #165a72;
+}
+
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ background-image: none;
+}
+
+.btn-primary.disabled,
+.btn-primary[disabled],
+fieldset[disabled] .btn-primary,
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled.focus,
+.btn-primary[disabled].focus,
+fieldset[disabled] .btn-primary.focus,
+.btn-primary.disabled:active,
+.btn-primary[disabled]:active,
+fieldset[disabled] .btn-primary:active,
+.btn-primary.disabled.active,
+.btn-primary[disabled].active,
+fieldset[disabled] .btn-primary.active {
+ background-color: #337cbb;
+ border-color: #2e6fa7;
+}
+
+.btn-primary .badge {
+ color: #337cbb;
+ background-color: #ffffff;
+}
+
+.btn-success {
+ color: #ffffff;
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+
+.btn-success:hover,
+.btn-success:focus,
+.btn-success.focus,
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ color: #ffffff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ background-image: none;
+}
+
+.btn-success.disabled,
+.btn-success[disabled],
+fieldset[disabled] .btn-success,
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled.focus,
+.btn-success[disabled].focus,
+fieldset[disabled] .btn-success.focus,
+.btn-success.disabled:active,
+.btn-success[disabled]:active,
+fieldset[disabled] .btn-success:active,
+.btn-success.disabled.active,
+.btn-success[disabled].active,
+fieldset[disabled] .btn-success.active {
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+
+.btn-success .badge {
+ color: #5cb85c;
+ background-color: #ffffff;
+}
+
+.btn-info {
+ color: #ffffff;
+ background-color: #E4762B;
+ border-color: #E28809;
+}
+
+.btn-info:hover,
+.btn-info:focus,
+.btn-info.focus,
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ color: #ffffff;
+ background-color: #E63F0A;
+ border-color: #E63F0A;
+}
+
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ background-image: none;
+}
+
+.btn-info.disabled,
+.btn-info[disabled],
+fieldset[disabled] .btn-info,
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled.focus,
+.btn-info[disabled].focus,
+fieldset[disabled] .btn-info.focus,
+.btn-info.disabled:active,
+.btn-info[disabled]:active,
+fieldset[disabled] .btn-info:active,
+.btn-info.disabled.active,
+.btn-info[disabled].active,
+fieldset[disabled] .btn-info.active {
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+
+.btn-info .badge {
+ color: #5bc0de;
+ background-color: #ffffff;
+}
+
+.btn-warning {
+ color: #ffffff;
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+
+.btn-warning:hover,
+.btn-warning:focus,
+.btn-warning.focus,
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ color: #ffffff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ background-image: none;
+}
+
+.btn-warning.disabled,
+.btn-warning[disabled],
+fieldset[disabled] .btn-warning,
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled.focus,
+.btn-warning[disabled].focus,
+fieldset[disabled] .btn-warning.focus,
+.btn-warning.disabled:active,
+.btn-warning[disabled]:active,
+fieldset[disabled] .btn-warning:active,
+.btn-warning.disabled.active,
+.btn-warning[disabled].active,
+fieldset[disabled] .btn-warning.active {
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+
+.btn-warning .badge {
+ color: #f0ad4e;
+ background-color: #ffffff;
+}
+
+.btn-danger {
+ color: #ffffff;
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+
+.btn-danger:hover,
+.btn-danger:focus,
+.btn-danger.focus,
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ color: #ffffff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ background-image: none;
+}
+
+.btn-danger.disabled,
+.btn-danger[disabled],
+fieldset[disabled] .btn-danger,
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled.focus,
+.btn-danger[disabled].focus,
+fieldset[disabled] .btn-danger.focus,
+.btn-danger.disabled:active,
+.btn-danger[disabled]:active,
+fieldset[disabled] .btn-danger:active,
+.btn-danger.disabled.active,
+.btn-danger[disabled].active,
+fieldset[disabled] .btn-danger.active {
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+
+.btn-danger .badge {
+ color: #d9534f;
+ background-color: #ffffff;
+}
+
+.btn-link {
+ color: #337cbb;
+ font-weight: normal;
+ border-radius: 0;
+}
+
+.btn-link,
+.btn-link:active,
+.btn-link.active,
+.btn-link[disabled],
+fieldset[disabled] .btn-link {
+ background-color: transparent;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.btn-link,
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+ border-color: transparent;
+}
+
+.btn-link:hover,
+.btn-link:focus {
+ color: #23547f;
+ text-decoration: underline;
+ background-color: transparent;
+}
+
+.btn-link[disabled]:hover,
+fieldset[disabled] .btn-link:hover,
+.btn-link[disabled]:focus,
+fieldset[disabled] .btn-link:focus {
+ color: #777777;
+ text-decoration: none;
+}
+
+.btn-lg,
+.btn-group-lg > .btn {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 5px;
+}
+
+.btn-sm,
+.btn-group-sm > .btn {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 2px;
+}
+
+.btn-xs,
+.btn-group-xs > .btn {
+ padding: 1px 5px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 2px;
+}
+
+.btn-block {
+ display: block;
+ width: 100%;
+}
+
+.btn-block + .btn-block {
+ margin-top: 5px;
+}
+
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+ width: 100%;
+}
+
+.fade {
+ opacity: 0;
+ -webkit-transition: opacity 0.15s linear;
+ -o-transition: opacity 0.15s linear;
+ transition: opacity 0.15s linear;
+}
+
+.fade.in {
+ opacity: 1;
+}
+
+.collapse {
+ display: none;
+}
+
+.collapse.in {
+ display: block;
+}
+
+tr.collapse.in {
+ display: table-row;
+}
+
+tbody.collapse.in {
+ display: table-row-group;
+}
+
+.collapsing {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ -webkit-transition-property: height, visibility;
+ transition-property: height, visibility;
+ -webkit-transition-duration: 0.35s;
+ transition-duration: 0.35s;
+ -webkit-transition-timing-function: ease;
+ transition-timing-function: ease;
+}
+
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-left: 2px;
+ vertical-align: middle;
+ border-top: 4px dashed;
+ border-right: 4px solid transparent;
+ border-left: 4px solid transparent;
+}
+
+.dropup,
+.dropdown {
+ position: relative;
+}
+
+.dropdown-toggle:focus {
+ outline: 0;
+}
+
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 1000;
+ display: none;
+ float: left;
+ min-width: 160px;
+ padding: 5px 0;
+ margin: 2px 0 0;
+ list-style: none;
+ font-size: 14px;
+ text-align: left;
+ background-color: #ffffff;
+ border: 1px solid #cccccc;
+ border: 1px solid rgba(0, 0, 0, 0.15);
+ border-radius: 4px;
+ -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
+ background-clip: padding-box;
+}
+
+.dropdown-menu.pull-right {
+ right: 0;
+ left: auto;
+}
+
+.dropdown-menu .divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+
+.dropdown-menu > li > a {
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: normal;
+ line-height: 1.42857143;
+ color: #333333;
+ white-space: nowrap;
+}
+
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+ text-decoration: none;
+ color: #262626;
+ background-color: #f5f5f5;
+}
+
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+ color: #ffffff;
+ text-decoration: none;
+ outline: 0;
+ background-color: #337cbb;
+}
+
+.dropdown-menu > .disabled > a,
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ color: #777777;
+}
+
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ text-decoration: none;
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ cursor: not-allowed;
+}
+
+.open > .dropdown-menu {
+ display: block;
+}
+
+.open > a {
+ outline: 0;
+}
+
+.dropdown-menu-right {
+ left: auto;
+ right: 0;
+}
+
+.dropdown-menu-left {
+ left: 0;
+ right: auto;
+}
+
+.dropdown-header {
+ display: block;
+ padding: 3px 20px;
+ font-size: 12px;
+ line-height: 1.42857143;
+ color: #777777;
+ white-space: nowrap;
+}
+
+.dropdown-backdrop {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ top: 0;
+ z-index: 990;
+}
+
+.pull-right > .dropdown-menu {
+ right: 0;
+ left: auto;
+}
+
+.dropup .caret,
+.navbar-fixed-bottom .dropdown .caret {
+ border-top: 0;
+ border-bottom: 4px solid;
+ content: "";
+}
+
+.dropup .dropdown-menu,
+.navbar-fixed-bottom .dropdown .dropdown-menu {
+ top: auto;
+ bottom: 100%;
+ margin-bottom: 2px;
+}
+
+@media (min-width: 768px) {
+ .navbar-right .dropdown-menu {
+ left: auto;
+ right: 0;
+ }
+
+ .navbar-right .dropdown-menu-left {
+ left: 0;
+ right: auto;
+ }
+}
+
+.btn-group,
+.btn-group-vertical {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.btn-group > .btn,
+.btn-group-vertical > .btn {
+ position: relative;
+ float: left;
+}
+
+.btn-group > .btn:hover,
+.btn-group-vertical > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group-vertical > .btn:focus,
+.btn-group > .btn:active,
+.btn-group-vertical > .btn:active,
+.btn-group > .btn.active,
+.btn-group-vertical > .btn.active {
+ z-index: 2;
+}
+
+.btn-group .btn + .btn,
+.btn-group .btn + .btn-group,
+.btn-group .btn-group + .btn,
+.btn-group .btn-group + .btn-group {
+ margin-left: -1px;
+}
+
+.btn-toolbar {
+ margin-left: -5px;
+}
+
+.btn-toolbar .btn-group,
+.btn-toolbar .input-group {
+ float: left;
+}
+
+.btn-toolbar > .btn,
+.btn-toolbar > .btn-group,
+.btn-toolbar > .input-group {
+ margin-left: 5px;
+}
+
+.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
+ border-radius: 0;
+}
+
+.btn-group > .btn:first-child {
+ margin-left: 0;
+}
+
+.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
+ border-bottom-right-radius: 0;
+ border-top-right-radius: 0;
+}
+
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
+ border-bottom-left-radius: 0;
+ border-top-left-radius: 0;
+}
+
+.btn-group > .btn-group {
+ float: left;
+}
+
+.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+
+.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-bottom-right-radius: 0;
+ border-top-right-radius: 0;
+}
+
+.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-bottom-left-radius: 0;
+ border-top-left-radius: 0;
+}
+
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+ outline: 0;
+}
+
+.btn-group > .btn + .dropdown-toggle {
+ padding-left: 8px;
+ padding-right: 8px;
+}
+
+.btn-group > .btn-lg + .dropdown-toggle {
+ padding-left: 12px;
+ padding-right: 12px;
+}
+
+.btn-group.open .dropdown-toggle {
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+}
+
+.btn-group.open .dropdown-toggle.btn-link {
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.btn .caret {
+ margin-left: 0;
+}
+
+.btn-lg .caret {
+ border-width: 5px 5px 0;
+ border-bottom-width: 0;
+}
+
+.dropup .btn-lg .caret {
+ border-width: 0 5px 5px;
+}
+
+.btn-group-vertical > .btn,
+.btn-group-vertical > .btn-group,
+.btn-group-vertical > .btn-group > .btn {
+ display: block;
+ float: none;
+ width: 100%;
+ max-width: 100%;
+}
+
+.btn-group-vertical > .btn-group > .btn {
+ float: none;
+}
+
+.btn-group-vertical > .btn + .btn,
+.btn-group-vertical > .btn + .btn-group,
+.btn-group-vertical > .btn-group + .btn,
+.btn-group-vertical > .btn-group + .btn-group {
+ margin-top: -1px;
+ margin-left: 0;
+}
+
+.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+
+.btn-group-vertical > .btn:first-child:not(:last-child) {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.btn-group-vertical > .btn:last-child:not(:first-child) {
+ border-bottom-left-radius: 4px;
+ border-top-right-radius: 0;
+ border-top-left-radius: 0;
+}
+
+.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-top-right-radius: 0;
+ border-top-left-radius: 0;
+}
+
+.btn-group-justified {
+ display: table;
+ width: 100%;
+ table-layout: fixed;
+ border-collapse: separate;
+}
+
+.btn-group-justified > .btn,
+.btn-group-justified > .btn-group {
+ float: none;
+ display: table-cell;
+ width: 1%;
+}
+
+.btn-group-justified > .btn-group .btn {
+ width: 100%;
+}
+
+.btn-group-justified > .btn-group .dropdown-menu {
+ left: auto;
+}
+
+[data-toggle="buttons"] > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn input[type="checkbox"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none;
+}
+
+.input-group {
+ position: relative;
+ display: table;
+ border-collapse: separate;
+}
+
+.input-group[class*="col-"] {
+ float: none;
+ padding-left: 0;
+ padding-right: 0;
+}
+
+.input-group .form-control {
+ position: relative;
+ z-index: 2;
+ float: left;
+ width: 100%;
+ margin-bottom: 0;
+}
+
+.input-group-lg > .form-control,
+.input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 5px;
+}
+
+select.input-group-lg > .form-control,
+select.input-group-lg > .input-group-addon,
+select.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ line-height: 46px;
+}
+
+textarea.input-group-lg > .form-control,
+textarea.input-group-lg > .input-group-addon,
+textarea.input-group-lg > .input-group-btn > .btn,
+select[multiple].input-group-lg > .form-control,
+select[multiple].input-group-lg > .input-group-addon,
+select[multiple].input-group-lg > .input-group-btn > .btn {
+ height: auto;
+}
+
+.input-group-sm > .form-control,
+.input-group-sm > .input-group-addon,
+.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 2px;
+}
+
+select.input-group-sm > .form-control,
+select.input-group-sm > .input-group-addon,
+select.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ line-height: 30px;
+}
+
+textarea.input-group-sm > .form-control,
+textarea.input-group-sm > .input-group-addon,
+textarea.input-group-sm > .input-group-btn > .btn,
+select[multiple].input-group-sm > .form-control,
+select[multiple].input-group-sm > .input-group-addon,
+select[multiple].input-group-sm > .input-group-btn > .btn {
+ height: auto;
+}
+
+.input-group-addon,
+.input-group-btn,
+.input-group .form-control {
+ display: table-cell;
+}
+
+.input-group-addon:not(:first-child):not(:last-child),
+.input-group-btn:not(:first-child):not(:last-child),
+.input-group .form-control:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+
+.input-group-addon,
+.input-group-btn {
+ width: 1%;
+ white-space: nowrap;
+ vertical-align: middle;
+}
+
+.input-group-addon {
+ padding: 6px 12px;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1;
+ color: #555555;
+ text-align: center;
+ background-color: #eeeeee;
+ border: 1px solid #cccccc;
+ border-radius: 4px;
+}
+
+.input-group-addon.input-sm {
+ padding: 5px 10px;
+ font-size: 12px;
+ border-radius: 2px;
+}
+
+.input-group-addon.input-lg {
+ padding: 10px 16px;
+ font-size: 18px;
+ border-radius: 5px;
+}
+
+.input-group-addon input[type="radio"],
+.input-group-addon input[type="checkbox"] {
+ margin-top: 0;
+}
+
+.input-group .form-control:first-child,
+.input-group-addon:first-child,
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group > .btn,
+.input-group-btn:first-child > .dropdown-toggle,
+.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
+.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
+ border-bottom-right-radius: 0;
+ border-top-right-radius: 0;
+}
+
+.input-group-addon:first-child {
+ border-right: 0;
+}
+
+.input-group .form-control:last-child,
+.input-group-addon:last-child,
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group > .btn,
+.input-group-btn:last-child > .dropdown-toggle,
+.input-group-btn:first-child > .btn:not(:first-child),
+.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
+ border-bottom-left-radius: 0;
+ border-top-left-radius: 0;
+}
+
+.input-group-addon:last-child {
+ border-left: 0;
+}
+
+.input-group-btn {
+ position: relative;
+ font-size: 0;
+ white-space: nowrap;
+}
+
+.input-group-btn > .btn {
+ position: relative;
+}
+
+.input-group-btn > .btn + .btn {
+ margin-left: -1px;
+}
+
+.input-group-btn > .btn:hover,
+.input-group-btn > .btn:focus,
+.input-group-btn > .btn:active {
+ z-index: 2;
+}
+
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group {
+ margin-right: -1px;
+}
+
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group {
+ margin-left: -1px;
+}
+
+.nav {
+ margin-bottom: 0;
+ padding-left: 0;
+ list-style: none;
+}
+
+.nav > li {
+ position: relative;
+ display: block;
+}
+
+.nav > li > a {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+}
+
+.nav > li > a:hover,
+.nav > li > a:focus {
+ text-decoration: none;
+ background-color: #eeeeee;
+}
+
+.nav > li.disabled > a {
+ color: #777777;
+}
+
+.nav > li.disabled > a:hover,
+.nav > li.disabled > a:focus {
+ color: #777777;
+ text-decoration: none;
+ background-color: transparent;
+ cursor: not-allowed;
+}
+
+.nav .open > a,
+.nav .open > a:hover,
+.nav .open > a:focus {
+ background-color: #eeeeee;
+ border-color: #337cbb;
+}
+
+.nav .nav-divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+
+.nav > li > a > img {
+ max-width: none;
+}
+
+.nav-tabs {
+ border-bottom: 1px solid #dddddd;
+}
+
+.nav-tabs > li {
+ float: left;
+ margin-bottom: -1px;
+}
+
+.nav-tabs > li > a {
+ margin-right: 2px;
+ line-height: 1.42857143;
+ border: 1px solid transparent;
+ border-radius: 4px 4px 0 0;
+}
+
+.nav-tabs > li > a:hover {
+ border-color: #eeeeee #eeeeee #dddddd;
+}
+
+.nav-tabs > li.active > a,
+.nav-tabs > li.active > a:hover,
+.nav-tabs > li.active > a:focus {
+ color: #555555;
+ background-color: #ffffff;
+ border: 1px solid #dddddd;
+ border-bottom-color: transparent;
+ cursor: default;
+}
+
+.nav-tabs.nav-justified {
+ width: 100%;
+ border-bottom: 0;
+}
+
+.nav-tabs.nav-justified > li {
+ float: none;
+}
+
+.nav-tabs.nav-justified > li > a {
+ text-align: center;
+ margin-bottom: 5px;
+}
+
+.nav-tabs.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+
+ .nav-tabs.nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+
+.nav-tabs.nav-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px;
+}
+
+.nav-tabs.nav-justified > .active > a,
+.nav-tabs.nav-justified > .active > a:hover,
+.nav-tabs.nav-justified > .active > a:focus {
+ border: 1px solid #dddddd;
+}
+
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li > a {
+ border-bottom: 1px solid #dddddd;
+ border-radius: 4px 4px 0 0;
+ }
+
+ .nav-tabs.nav-justified > .active > a,
+ .nav-tabs.nav-justified > .active > a:hover,
+ .nav-tabs.nav-justified > .active > a:focus {
+ border-bottom-color: #ffffff;
+ }
+}
+
+.nav-pills > li {
+ float: left;
+}
+
+.nav-pills > li > a {
+ border-radius: 4px;
+}
+
+.nav-pills > li + li {
+ margin-left: 2px;
+}
+
+.nav-pills > li.active > a,
+.nav-pills > li.active > a:hover,
+.nav-pills > li.active > a:focus {
+ color: #ffffff;
+ background-color: #337cbb;
+}
+
+.nav-stacked > li {
+ float: none;
+}
+
+.nav-stacked > li + li {
+ margin-top: 2px;
+ margin-left: 0;
+}
+
+.nav-justified {
+ width: 100%;
+}
+
+.nav-justified > li {
+ float: none;
+}
+
+.nav-justified > li > a {
+ text-align: center;
+ margin-bottom: 5px;
+}
+
+.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+
+@media (min-width: 768px) {
+ .nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+
+ .nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+
+.nav-tabs-justified {
+ border-bottom: 0;
+}
+
+.nav-tabs-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px;
+}
+
+.nav-tabs-justified > .active > a,
+.nav-tabs-justified > .active > a:hover,
+.nav-tabs-justified > .active > a:focus {
+ border: 1px solid #dddddd;
+}
+
+@media (min-width: 768px) {
+ .nav-tabs-justified > li > a {
+ border-bottom: 1px solid #dddddd;
+ border-radius: 4px 4px 0 0;
+ }
+
+ .nav-tabs-justified > .active > a,
+ .nav-tabs-justified > .active > a:hover,
+ .nav-tabs-justified > .active > a:focus {
+ border-bottom-color: #ffffff;
+ }
+}
+
+.tab-content > .tab-pane {
+ display: none;
+}
+
+.tab-content > .active {
+ display: block;
+}
+
+.nav-tabs .dropdown-menu {
+ margin-top: -1px;
+ border-top-right-radius: 0;
+ border-top-left-radius: 0;
+}
+
+.navbar {
+ position: relative;
+ min-height: 50px;
+ margin-bottom: 0px;
+ border: 1px solid transparent;
+}
+
+@media (min-width: 768px) {
+ .navbar {
+ border-radius: 4px;
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-header {
+ float: left;
+ }
+}
+
+.navbar-collapse {
+ overflow-x: visible;
+ padding-right: 15px;
+ padding-left: 15px;
+ border-top: 1px solid transparent;
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
+ -webkit-overflow-scrolling: touch;
+}
+
+.navbar-collapse.in {
+ overflow-y: auto;
+}
+
+@media (min-width: 768px) {
+ .navbar-collapse {
+ width: auto;
+ border-top: 0;
+ box-shadow: none;
+ }
+
+ .navbar-collapse.collapse {
+ display: block !important;
+ height: auto !important;
+ padding-bottom: 0;
+ overflow: visible !important;
+ }
+
+ .navbar-collapse.in {
+ overflow-y: visible;
+ }
+
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-static-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ padding-left: 0;
+ padding-right: 0;
+ }
+}
+
+.navbar-fixed-top .navbar-collapse,
+.navbar-fixed-bottom .navbar-collapse {
+ max-height: 340px;
+}
+
+@media (max-device-width: 480px) and (orientation: landscape) {
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ max-height: 200px;
+ }
+}
+
+.container > .navbar-header,
+.container-fluid > .navbar-header,
+.container > .navbar-collapse,
+.container-fluid > .navbar-collapse {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+
+@media (min-width: 768px) {
+ .container > .navbar-header,
+ .container-fluid > .navbar-header,
+ .container > .navbar-collapse,
+ .container-fluid > .navbar-collapse {
+ margin-right: 0;
+ margin-left: 0;
+ }
+}
+
+.navbar-static-top {
+ z-index: 1000;
+ border-width: 0 0 1px;
+}
+
+@media (min-width: 768px) {
+ .navbar-static-top {
+ border-radius: 0;
+ }
+}
+
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+ position: fixed;
+ right: 0;
+ left: 0;
+ z-index: 1030;
+}
+
+@media (min-width: 768px) {
+ .navbar-fixed-top,
+ .navbar-fixed-bottom {
+ border-radius: 0;
+ }
+}
+
+.navbar-fixed-top {
+ top: 0;
+ border-width: 0 0 1px;
+}
+
+.navbar-fixed-bottom {
+ bottom: 0;
+ margin-bottom: 0;
+ border-width: 1px 0 0;
+}
+
+.navbar-brand {
+ float: left;
+ padding: 15px 15px;
+ font-size: 18px;
+ line-height: 20px;
+ height: 50px;
+}
+
+.navbar-brand:hover,
+.navbar-brand:focus {
+ text-decoration: none;
+}
+
+.navbar-brand > img {
+ display: block;
+}
+
+@media (min-width: 768px) {
+ .navbar > .container .navbar-brand,
+ .navbar > .container-fluid .navbar-brand {
+ margin-left: -15px;
+ }
+}
+
+.navbar-toggle {
+ position: relative;
+ float: right;
+ margin-right: 15px;
+ padding: 9px 10px;
+ margin-top: 8px;
+ margin-bottom: 8px;
+ background-color: transparent;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+
+.navbar-toggle:focus {
+ outline: 0;
+}
+
+.navbar-toggle .icon-bar {
+ display: block;
+ width: 22px;
+ height: 2px;
+ border-radius: 1px;
+}
+
+.navbar-toggle .icon-bar + .icon-bar {
+ margin-top: 4px;
+}
+
+@media (min-width: 768px) {
+ .navbar-toggle {
+ display: none;
+ }
+}
+
+.navbar-nav {
+ margin: 7.5px -15px;
+}
+
+.navbar-nav > li > a {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ line-height: 20px;
+}
+
+@media (max-width: 767px) {
+ .navbar-nav .open .dropdown-menu {
+ position: static;
+ float: none;
+ width: auto;
+ margin-top: 0;
+ background-color: transparent;
+ border: 0;
+ box-shadow: none;
+ }
+
+ .navbar-nav .open .dropdown-menu > li > a,
+ .navbar-nav .open .dropdown-menu .dropdown-header {
+ padding: 5px 15px 5px 25px;
+ }
+
+ .navbar-nav .open .dropdown-menu > li > a {
+ line-height: 20px;
+ }
+
+ .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-nav .open .dropdown-menu > li > a:focus {
+ background-image: none;
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-nav {
+ float: left;
+ margin: 0;
+ }
+
+ .navbar-nav > li {
+ float: left;
+ }
+
+ .navbar-nav > li > a {
+ padding-top: 15px;
+ padding-bottom: 15px;
+ }
+}
+
+.navbar-form {
+ margin-left: -15px;
+ margin-right: -15px;
+ padding: 10px 15px;
+ border-top: 1px solid transparent;
+ border-bottom: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
+ margin-top: 8px;
+ margin-bottom: 8px;
+}
+
+@media (min-width: 768px) {
+ .navbar-form .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .navbar-form .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+
+ .navbar-form .form-control-static {
+ display: inline-block;
+ }
+
+ .navbar-form .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+
+ .navbar-form .input-group .input-group-addon,
+ .navbar-form .input-group .input-group-btn,
+ .navbar-form .input-group .form-control {
+ width: auto;
+ }
+
+ .navbar-form .input-group > .form-control {
+ width: 100%;
+ }
+
+ .navbar-form .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .navbar-form .radio,
+ .navbar-form .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .navbar-form .radio label,
+ .navbar-form .checkbox label {
+ padding-left: 0;
+ }
+
+ .navbar-form .radio input[type="radio"],
+ .navbar-form .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+
+ .navbar-form .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+
+@media (max-width: 767px) {
+ .navbar-form .form-group {
+ margin-bottom: 5px;
+ }
+
+ .navbar-form .form-group:last-child {
+ margin-bottom: 0;
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-form {
+ width: auto;
+ border: 0;
+ margin-left: 0;
+ margin-right: 0;
+ padding-top: 0;
+ padding-bottom: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+}
+
+.navbar-nav > li > .dropdown-menu {
+ margin-top: 0;
+ border-top-right-radius: 0;
+ border-top-left-radius: 0;
+}
+
+.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
+ margin-bottom: 0;
+ border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.navbar-btn {
+ margin-top: 8px;
+ margin-bottom: 8px;
+}
+
+.navbar-btn.btn-sm {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+.navbar-btn.btn-xs {
+ margin-top: 14px;
+ margin-bottom: 14px;
+}
+
+.navbar-text {
+ margin-top: 15px;
+ margin-bottom: 15px;
+}
+
+@media (min-width: 768px) {
+ .navbar-text {
+ float: left;
+ margin-left: 15px;
+ margin-right: 15px;
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-left {
+ float: left !important;
+ }
+
+ .navbar-right {
+ float: right !important;
+ margin-right: -15px;
+ }
+
+ .navbar-right ~ .navbar-right {
+ margin-right: 0;
+ }
+}
+
+.navbar-default {
+ background-color: #f8f8f8;
+ border-color: #e7e7e7;
+}
+
+.navbar-default .navbar-brand {
+ color: #000000;
+}
+
+.navbar-default .navbar-brand:hover,
+.navbar-default .navbar-brand:focus {
+ color: #000000;
+ background-color: transparent;
+}
+
+.navbar-default .navbar-text {
+ color: #000000;
+}
+
+.navbar-default .navbar-nav > li > a {
+ color: #000000;
+}
+
+.navbar-default .navbar-nav > li > a:hover,
+.navbar-default .navbar-nav > li > a:focus {
+ color: #000000;
+ background-color: transparent;
+}
+
+.navbar-default .navbar-nav > .active > a,
+.navbar-default .navbar-nav > .active > a:hover,
+.navbar-default .navbar-nav > .active > a:focus {
+ color: #000000;
+ background-color: #e7e7e7;
+}
+
+.navbar-default .navbar-nav > .disabled > a,
+.navbar-default .navbar-nav > .disabled > a:hover,
+.navbar-default .navbar-nav > .disabled > a:focus {
+ color: #cccccc;
+ background-color: transparent;
+}
+
+.navbar-default .navbar-toggle {
+ border-color: #dddddd;
+}
+
+.navbar-default .navbar-toggle:hover,
+.navbar-default .navbar-toggle:focus {
+ background-color: #dddddd;
+}
+
+.navbar-default .navbar-toggle .icon-bar {
+ background-color: #888888;
+}
+
+.navbar-default .navbar-collapse,
+.navbar-default .navbar-form {
+ border-color: #e7e7e7;
+}
+
+.navbar-default .navbar-nav > .open > a,
+.navbar-default .navbar-nav > .open > a:hover,
+.navbar-default .navbar-nav > .open > a:focus {
+ background-color: #e7e7e7;
+ color: #000000;
+}
+
+@media (max-width: 767px) {
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a {
+ color: #000000;
+ }
+
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #000000;
+ background-color: transparent;
+ }
+
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #000000;
+ background-color: #e7e7e7;
+ }
+
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #cccccc;
+ background-color: transparent;
+ }
+}
+
+.navbar-default .navbar-link {
+ color: #000000;
+}
+
+.navbar-default .navbar-link:hover {
+ color: #000000;
+}
+
+.navbar-default .btn-link {
+ color: #000000;
+}
+
+.navbar-default .btn-link:hover,
+.navbar-default .btn-link:focus {
+ color: #000000;
+}
+
+.navbar-default .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-default .btn-link:hover,
+.navbar-default .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-default .btn-link:focus {
+ color: #cccccc;
+}
+
+.navbar-inverse {
+ background-color: #222222;
+ border-color: #080808;
+}
+
+.navbar-inverse .navbar-brand {
+ color: #9d9d9d;
+}
+
+.navbar-inverse .navbar-brand:hover,
+.navbar-inverse .navbar-brand:focus {
+ color: #ffffff;
+ background-color: transparent;
+}
+
+.navbar-inverse .navbar-text {
+ color: #9d9d9d;
+}
+
+.navbar-inverse .navbar-nav > li > a {
+ color: #9d9d9d;
+}
+
+.navbar-inverse .navbar-nav > li > a:hover,
+.navbar-inverse .navbar-nav > li > a:focus {
+ color: #ffffff;
+ background-color: transparent;
+}
+
+.navbar-inverse .navbar-nav > .active > a,
+.navbar-inverse .navbar-nav > .active > a:hover,
+.navbar-inverse .navbar-nav > .active > a:focus {
+ color: #ffffff;
+ background-color: #080808;
+}
+
+.navbar-inverse .navbar-nav > .disabled > a,
+.navbar-inverse .navbar-nav > .disabled > a:hover,
+.navbar-inverse .navbar-nav > .disabled > a:focus {
+ color: #444444;
+ background-color: transparent;
+}
+
+.navbar-inverse .navbar-toggle {
+ border-color: #333333;
+}
+
+.navbar-inverse .navbar-toggle:hover,
+.navbar-inverse .navbar-toggle:focus {
+ background-color: #333333;
+}
+
+.navbar-inverse .navbar-toggle .icon-bar {
+ background-color: #ffffff;
+}
+
+.navbar-inverse .navbar-collapse,
+.navbar-inverse .navbar-form {
+ border-color: #101010;
+}
+
+.navbar-inverse .navbar-nav > .open > a,
+.navbar-inverse .navbar-nav > .open > a:hover,
+.navbar-inverse .navbar-nav > .open > a:focus {
+ background-color: #080808;
+ color: #ffffff;
+}
+
+@media (max-width: 767px) {
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
+ border-color: #080808;
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
+ background-color: #080808;
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
+ color: #9d9d9d;
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #ffffff;
+ background-color: transparent;
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #ffffff;
+ background-color: #080808;
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #444444;
+ background-color: transparent;
+ }
+}
+
+.navbar-inverse .navbar-link {
+ color: #9d9d9d;
+}
+
+.navbar-inverse .navbar-link:hover {
+ color: #ffffff;
+}
+
+.navbar-inverse .btn-link {
+ color: #9d9d9d;
+}
+
+.navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link:focus {
+ color: #ffffff;
+}
+
+.navbar-inverse .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-inverse .btn-link:focus {
+ color: #444444;
+}
+
+.breadcrumb {
+ padding: 8px 15px;
+ margin-bottom: 20px;
+ list-style: none;
+ background-color: #f5f5f5;
+ border-radius: 4px;
+}
+
+.breadcrumb > li {
+ display: inline-block;
+}
+
+.breadcrumb > li + li:before {
+ content: "/\00a0";
+ padding: 0 5px;
+ color: #cccccc;
+}
+
+.breadcrumb > .active {
+ color: #777777;
+}
+
+.pagination {
+ display: inline-block;
+ padding-left: 0;
+ margin: 20px 0;
+ border-radius: 4px;
+}
+
+.pagination > li {
+ display: inline;
+}
+
+.pagination > li > a,
+.pagination > li > span {
+ position: relative;
+ float: left;
+ padding: 6px 12px;
+ line-height: 1.42857143;
+ text-decoration: none;
+ color: #337cbb;
+ background-color: #ffffff;
+ border: 1px solid #dddddd;
+ margin-left: -1px;
+}
+
+.pagination > li:first-child > a,
+.pagination > li:first-child > span {
+ margin-left: 0;
+ border-bottom-left-radius: 4px;
+ border-top-left-radius: 4px;
+}
+
+.pagination > li:last-child > a,
+.pagination > li:last-child > span {
+ border-bottom-right-radius: 4px;
+ border-top-right-radius: 4px;
+}
+
+.pagination > li > a:hover,
+.pagination > li > span:hover,
+.pagination > li > a:focus,
+.pagination > li > span:focus {
+ color: #23547f;
+ background-color: #eeeeee;
+ border-color: #dddddd;
+}
+
+.pagination > .active > a,
+.pagination > .active > span,
+.pagination > .active > a:hover,
+.pagination > .active > span:hover,
+.pagination > .active > a:focus,
+.pagination > .active > span:focus {
+ z-index: 2;
+ color: #ffffff;
+ background-color: #337cbb;
+ border-color: #337cbb;
+ cursor: default;
+}
+
+.pagination > .disabled > span,
+.pagination > .disabled > span:hover,
+.pagination > .disabled > span:focus,
+.pagination > .disabled > a,
+.pagination > .disabled > a:hover,
+.pagination > .disabled > a:focus {
+ color: #777777;
+ background-color: #ffffff;
+ border-color: #dddddd;
+ cursor: not-allowed;
+}
+
+.pagination-lg > li > a,
+.pagination-lg > li > span {
+ padding: 10px 16px;
+ font-size: 18px;
+}
+
+.pagination-lg > li:first-child > a,
+.pagination-lg > li:first-child > span {
+ border-bottom-left-radius: 5px;
+ border-top-left-radius: 5px;
+}
+
+.pagination-lg > li:last-child > a,
+.pagination-lg > li:last-child > span {
+ border-bottom-right-radius: 5px;
+ border-top-right-radius: 5px;
+}
+
+.pagination-sm > li > a,
+.pagination-sm > li > span {
+ padding: 5px 10px;
+ font-size: 12px;
+}
+
+.pagination-sm > li:first-child > a,
+.pagination-sm > li:first-child > span {
+ border-bottom-left-radius: 2px;
+ border-top-left-radius: 2px;
+}
+
+.pagination-sm > li:last-child > a,
+.pagination-sm > li:last-child > span {
+ border-bottom-right-radius: 2px;
+ border-top-right-radius: 2px;
+}
+
+.pager {
+ padding-left: 0;
+ margin: 20px 0;
+ list-style: none;
+ text-align: center;
+}
+
+.pager li {
+ display: inline;
+}
+
+.pager li > a,
+.pager li > span {
+ display: inline-block;
+ padding: 5px 14px;
+ background-color: #ffffff;
+ border: 1px solid #dddddd;
+ border-radius: 15px;
+}
+
+.pager li > a:hover,
+.pager li > a:focus {
+ text-decoration: none;
+ background-color: #eeeeee;
+}
+
+.pager .next > a,
+.pager .next > span {
+ float: right;
+}
+
+.pager .previous > a,
+.pager .previous > span {
+ float: left;
+}
+
+.pager .disabled > a,
+.pager .disabled > a:hover,
+.pager .disabled > a:focus,
+.pager .disabled > span {
+ color: #777777;
+ background-color: #ffffff;
+ cursor: not-allowed;
+}
+
+.label {
+ display: inline;
+ padding: .2em .6em .3em;
+ font-size: 75%;
+ font-weight: bold;
+ line-height: 1;
+ color: #ffffff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ border-radius: .25em;
+}
+
+a.label:hover,
+a.label:focus {
+ color: #ffffff;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.label:empty {
+ display: none;
+}
+
+.btn .label {
+ position: relative;
+ top: -1px;
+}
+
+.label-default {
+ background-color: #777777;
+}
+
+.label-default[href]:hover,
+.label-default[href]:focus {
+ background-color: #5e5e5e;
+}
+
+.label-primary {
+ background-color: #337cbb;
+}
+
+.label-primary[href]:hover,
+.label-primary[href]:focus {
+ background-color: #286193;
+}
+
+.label-success {
+ background-color: #5cb85c;
+}
+
+.label-success[href]:hover,
+.label-success[href]:focus {
+ background-color: #449d44;
+}
+
+.label-info {
+ background-color: #5bc0de;
+}
+
+.label-info[href]:hover,
+.label-info[href]:focus {
+ background-color: #31b0d5;
+}
+
+.label-warning {
+ background-color: #f0ad4e;
+}
+
+.label-warning[href]:hover,
+.label-warning[href]:focus {
+ background-color: #ec971f;
+}
+
+.label-danger {
+ background-color: #d9534f;
+}
+
+.label-danger[href]:hover,
+.label-danger[href]:focus {
+ background-color: #c9302c;
+}
+
+.badge {
+ display: inline-block;
+ min-width: 10px;
+ padding: 3px 7px;
+ font-size: 12px;
+ font-weight: bold;
+ color: #ffffff;
+ line-height: 1;
+ vertical-align: baseline;
+ white-space: nowrap;
+ text-align: center;
+ background-color: #777777;
+ border-radius: 10px;
+}
+
+.badge:empty {
+ display: none;
+}
+
+.btn .badge {
+ position: relative;
+ top: -1px;
+}
+
+.btn-xs .badge,
+.btn-group-xs > .btn .badge {
+ top: 0;
+ padding: 1px 5px;
+}
+
+a.badge:hover,
+a.badge:focus {
+ color: #ffffff;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.list-group-item.active > .badge,
+.nav-pills > .active > a > .badge {
+ color: #337cbb;
+ background-color: #ffffff;
+}
+
+.list-group-item > .badge {
+ float: right;
+}
+
+.list-group-item > .badge + .badge {
+ margin-right: 5px;
+}
+
+.nav-pills > li > a > .badge {
+ margin-left: 3px;
+}
+
+.jumbotron {
+ padding: 30px 15px;
+ margin-bottom: 30px;
+ color: inherit;
+ background-color: #eeeeee;
+}
+
+.jumbotron h1,
+.jumbotron .h1 {
+ color: inherit;
+}
+
+.jumbotron p {
+ margin-bottom: 15px;
+ font-size: 21px;
+ font-weight: 200;
+}
+
+.jumbotron > hr {
+ border-top-color: #d5d5d5;
+}
+
+.container .jumbotron,
+.container-fluid .jumbotron {
+ border-radius: 5px;
+}
+
+.jumbotron .container {
+ max-width: 100%;
+}
+
+@media screen and (min-width: 768px) {
+ .jumbotron {
+ padding: 48px 0;
+ }
+
+ .container .jumbotron,
+ .container-fluid .jumbotron {
+ padding-left: 60px;
+ padding-right: 60px;
+ }
+
+ .jumbotron h1,
+ .jumbotron .h1 {
+ font-size: 63px;
+ }
+}
+
+.thumbnail {
+ display: block;
+ padding: 4px;
+ margin-bottom: 20px;
+ line-height: 1.42857143;
+ background-color: #ffffff;
+ border: 1px solid #dddddd;
+ border-radius: 4px;
+ -webkit-transition: border 0.2s ease-in-out;
+ -o-transition: border 0.2s ease-in-out;
+ transition: border 0.2s ease-in-out;
+}
+
+.thumbnail > img,
+.thumbnail a > img {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+a.thumbnail:hover,
+a.thumbnail:focus,
+a.thumbnail.active {
+ border-color: #337cbb;
+}
+
+.thumbnail .caption {
+ padding: 9px;
+ color: #000000;
+}
+
+.alert {
+ padding: 15px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+
+.alert h4 {
+ margin-top: 0;
+ color: inherit;
+}
+
+.alert .alert-link {
+ font-weight: bold;
+}
+
+.alert > p,
+.alert > ul {
+ margin-bottom: 0;
+}
+
+.alert > p + p {
+ margin-top: 5px;
+}
+
+.alert-dismissable,
+.alert-dismissible {
+ padding-right: 35px;
+}
+
+.alert-dismissable .close,
+.alert-dismissible .close {
+ position: relative;
+ top: -2px;
+ right: -21px;
+ color: inherit;
+}
+
+.alert-success {
+ background-color: #a3d7a3;
+ border-color: #9ccf91;
+ color: #5cb85c;
+}
+
+.alert-success hr {
+ border-top-color: #8cc780;
+}
+
+.alert-success .alert-link {
+ color: #449d44;
+}
+
+.alert-info {
+ background-color: #b0e1ef;
+ border-color: #92e4e9;
+ color: #5bc0de;
+}
+
+.alert-info hr {
+ border-top-color: #7ddee5;
+}
+
+.alert-info .alert-link {
+ color: #31b0d5;
+}
+
+.alert-warning {
+ background-color: #f8d9ac;
+ border-color: #f6bd95;
+ color: #f0ad4e;
+}
+
+.alert-warning hr {
+ border-top-color: #f4af7d;
+}
+
+.alert-warning .alert-link {
+ color: #ec971f;
+}
+
+.alert-danger {
+ background-color: #eba5a3;
+ border-color: #e78e9a;
+ color: #d9534f;
+}
+
+.alert-danger hr {
+ border-top-color: #e27987;
+}
+
+.alert-danger .alert-link {
+ color: #c9302c;
+}
+
+@-webkit-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+
+@keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+
+.progress {
+ overflow: hidden;
+ height: 20px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+}
+
+.progress-bar {
+ float: left;
+ width: 0%;
+ height: 100%;
+ font-size: 12px;
+ line-height: 20px;
+ color: #ffffff;
+ text-align: center;
+ background-color: #337cbb;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ -webkit-transition: width 0.6s ease;
+ -o-transition: width 0.6s ease;
+ transition: width 0.6s ease;
+}
+
+.progress-striped .progress-bar,
+.progress-bar-striped {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-size: 40px 40px;
+}
+
+.progress.active .progress-bar,
+.progress-bar.active {
+ -webkit-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite;
+}
+
+.progress-bar-success {
+ background-color: #5cb85c;
+}
+
+.progress-striped .progress-bar-success {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+
+.progress-bar-info {
+ background-color: #5bc0de;
+}
+
+.progress-striped .progress-bar-info {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+
+.progress-bar-warning {
+ background-color: #f0ad4e;
+}
+
+.progress-striped .progress-bar-warning {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+
+.progress-bar-danger {
+ background-color: #d9534f;
+}
+
+.progress-striped .progress-bar-danger {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+
+.media {
+ margin-top: 15px;
+}
+
+.media:first-child {
+ margin-top: 0;
+}
+
+.media,
+.media-body {
+ zoom: 1;
+ overflow: hidden;
+}
+
+.media-body {
+ width: 10000px;
+}
+
+.media-object {
+ display: block;
+}
+
+.media-right,
+.media > .pull-right {
+ padding-left: 10px;
+}
+
+.media-left,
+.media > .pull-left {
+ padding-right: 10px;
+}
+
+.media-left,
+.media-right,
+.media-body {
+ display: table-cell;
+ vertical-align: top;
+}
+
+.media-middle {
+ vertical-align: middle;
+}
+
+.media-bottom {
+ vertical-align: bottom;
+}
+
+.media-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+
+.media-list {
+ padding-left: 0;
+ list-style: none;
+}
+
+.list-group {
+ margin-bottom: 20px;
+ padding-left: 0;
+}
+
+.list-group-item {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+ margin-bottom: -1px;
+ background-color: #ffffff;
+ border: 1px solid #999999;
+}
+
+.list-group-item:first-child {
+ border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+}
+
+.list-group-item:last-child {
+ margin-bottom: 0;
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+
+a.list-group-item {
+ color: #555555;
+}
+
+a.list-group-item .list-group-item-heading {
+ color: #333333;
+}
+
+a.list-group-item:hover,
+a.list-group-item:focus {
+ text-decoration: none;
+ color: #555555;
+ background-color: #f5f5f5;
+}
+
+.list-group-item.disabled,
+.list-group-item.disabled:hover,
+.list-group-item.disabled:focus {
+ background-color: #eeeeee;
+ color: #777777;
+ cursor: not-allowed;
+}
+
+.list-group-item.disabled .list-group-item-heading,
+.list-group-item.disabled:hover .list-group-item-heading,
+.list-group-item.disabled:focus .list-group-item-heading {
+ color: inherit;
+}
+
+.list-group-item.disabled .list-group-item-text,
+.list-group-item.disabled:hover .list-group-item-text,
+.list-group-item.disabled:focus .list-group-item-text {
+ color: #777777;
+}
+
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
+ z-index: 2;
+ color: #ffffff;
+ background-color: #337cbb;
+ border-color: #337cbb;
+}
+
+.list-group-item.active .list-group-item-heading,
+.list-group-item.active:hover .list-group-item-heading,
+.list-group-item.active:focus .list-group-item-heading,
+.list-group-item.active .list-group-item-heading > small,
+.list-group-item.active:hover .list-group-item-heading > small,
+.list-group-item.active:focus .list-group-item-heading > small,
+.list-group-item.active .list-group-item-heading > .small,
+.list-group-item.active:hover .list-group-item-heading > .small,
+.list-group-item.active:focus .list-group-item-heading > .small {
+ color: inherit;
+}
+
+.list-group-item.active .list-group-item-text,
+.list-group-item.active:hover .list-group-item-text,
+.list-group-item.active:focus .list-group-item-text {
+ color: #07121b;
+}
+
+.list-group-item-success {
+ color: #5cb85c;
+ background-color: #a3d7a3;
+}
+
+a.list-group-item-success {
+ color: #5cb85c;
+}
+
+a.list-group-item-success .list-group-item-heading {
+ color: inherit;
+}
+
+a.list-group-item-success:hover,
+a.list-group-item-success:focus {
+ color: #5cb85c;
+ background-color: #91cf91;
+}
+
+a.list-group-item-success.active,
+a.list-group-item-success.active:hover,
+a.list-group-item-success.active:focus {
+ color: #fff;
+ background-color: #5cb85c;
+ border-color: #5cb85c;
+}
+
+.list-group-item-info {
+ color: #5bc0de;
+ background-color: #b0e1ef;
+}
+
+a.list-group-item-info {
+ color: #5bc0de;
+}
+
+a.list-group-item-info .list-group-item-heading {
+ color: inherit;
+}
+
+a.list-group-item-info:hover,
+a.list-group-item-info:focus {
+ color: #5bc0de;
+ background-color: #9bd8eb;
+}
+
+a.list-group-item-info.active,
+a.list-group-item-info.active:hover,
+a.list-group-item-info.active:focus {
+ color: #fff;
+ background-color: #5bc0de;
+ border-color: #5bc0de;
+}
+
+.list-group-item-warning {
+ color: #f0ad4e;
+ background-color: #f8d9ac;
+}
+
+a.list-group-item-warning {
+ color: #f0ad4e;
+}
+
+a.list-group-item-warning .list-group-item-heading {
+ color: inherit;
+}
+
+a.list-group-item-warning:hover,
+a.list-group-item-warning:focus {
+ color: #f0ad4e;
+ background-color: #f6ce95;
+}
+
+a.list-group-item-warning.active,
+a.list-group-item-warning.active:hover,
+a.list-group-item-warning.active:focus {
+ color: #fff;
+ background-color: #f0ad4e;
+ border-color: #f0ad4e;
+}
+
+.list-group-item-danger {
+ color: #d9534f;
+ background-color: #eba5a3;
+}
+
+a.list-group-item-danger {
+ color: #d9534f;
+}
+
+a.list-group-item-danger .list-group-item-heading {
+ color: inherit;
+}
+
+a.list-group-item-danger:hover,
+a.list-group-item-danger:focus {
+ color: #d9534f;
+ background-color: #e7908e;
+}
+
+a.list-group-item-danger.active,
+a.list-group-item-danger.active:hover,
+a.list-group-item-danger.active:focus {
+ color: #fff;
+ background-color: #d9534f;
+ border-color: #d9534f;
+}
+
+.list-group-item-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+
+.list-group-item-text {
+ margin-bottom: 0;
+ line-height: 1.3;
+}
+
+.panel {
+ margin-bottom: 20px;
+ background-color: #ffffff;
+ border: 1px solid transparent;
+ border-radius: 4px;
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
+}
+
+.panel-body {
+ padding: 15px;
+}
+
+.panel-heading {
+ padding: 10px 15px;
+ border-bottom: 1px solid transparent;
+ border-top-right-radius: 3px;
+ border-top-left-radius: 3px;
+}
+
+.panel-heading > .dropdown .dropdown-toggle {
+ color: inherit;
+}
+
+.panel-title {
+ margin-top: 0;
+ margin-bottom: 0;
+ font-size: 16px;
+ color: inherit;
+}
+
+.panel-title > a,
+.panel-title > small,
+.panel-title > .small,
+.panel-title > small > a,
+.panel-title > .small > a {
+ color: inherit;
+}
+
+.panel-footer {
+ padding: 10px 15px;
+ background-color: #f5f5f5;
+ border-top: 1px solid #dddddd;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+
+.panel > .list-group,
+.panel > .panel-collapse > .list-group {
+ margin-bottom: 0;
+}
+
+.panel > .list-group .list-group-item,
+.panel > .panel-collapse > .list-group .list-group-item {
+ border-width: 1px 0;
+ border-radius: 0;
+}
+
+.panel > .list-group:first-child .list-group-item:first-child,
+.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
+ border-top: 0;
+ border-top-right-radius: 3px;
+ border-top-left-radius: 3px;
+}
+
+.panel > .list-group:last-child .list-group-item:last-child,
+.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
+ border-bottom: 0;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+
+.panel-heading + .list-group .list-group-item:first-child {
+ border-top-width: 0;
+}
+
+.list-group + .panel-footer {
+ border-top-width: 0;
+}
+
+.panel > .table,
+.panel > .table-responsive > .table,
+.panel > .panel-collapse > .table {
+ margin-bottom: 0;
+}
+
+.panel > .table caption,
+.panel > .table-responsive > .table caption,
+.panel > .panel-collapse > .table caption {
+ padding-left: 15px;
+ padding-right: 15px;
+}
+
+.panel > .table:first-child,
+.panel > .table-responsive:first-child > .table:first-child {
+ border-top-right-radius: 3px;
+ border-top-left-radius: 3px;
+}
+
+.panel > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+
+.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
+ border-top-left-radius: 3px;
+}
+
+.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
+ border-top-right-radius: 3px;
+}
+
+.panel > .table:last-child,
+.panel > .table-responsive:last-child > .table:last-child {
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+
+.panel > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+}
+
+.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
+ border-bottom-left-radius: 3px;
+}
+
+.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
+ border-bottom-right-radius: 3px;
+}
+
+.panel > .panel-body + .table,
+.panel > .panel-body + .table-responsive,
+.panel > .table + .panel-body,
+.panel > .table-responsive + .panel-body {
+ border-top: 1px solid #dddddd;
+}
+
+.panel > .table > tbody:first-child > tr:first-child th,
+.panel > .table > tbody:first-child > tr:first-child td {
+ border-top: 0;
+}
+
+.panel > .table-bordered,
+.panel > .table-responsive > .table-bordered {
+ border: 0;
+}
+
+.panel > .table-bordered > thead > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
+.panel > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-bordered > thead > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
+.panel > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-bordered > tfoot > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+}
+
+.panel > .table-bordered > thead > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
+.panel > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-bordered > thead > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
+.panel > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-bordered > tfoot > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+}
+
+.panel > .table-bordered > thead > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
+.panel > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-bordered > thead > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
+.panel > .table-bordered > tbody > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
+ border-bottom: 0;
+}
+
+.panel > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-bordered > tfoot > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
+ border-bottom: 0;
+}
+
+.panel > .table-responsive {
+ border: 0;
+ margin-bottom: 0;
+}
+
+.panel-group {
+ margin-bottom: 20px;
+}
+
+.panel-group .panel {
+ margin-bottom: 0;
+ border-radius: 4px;
+}
+
+.panel-group .panel + .panel {
+ margin-top: 5px;
+}
+
+.panel-group .panel-heading {
+ border-bottom: 0;
+}
+
+.panel-group .panel-heading + .panel-collapse > .panel-body,
+.panel-group .panel-heading + .panel-collapse > .list-group {
+ border-top: 1px solid #dddddd;
+}
+
+.panel-group .panel-footer {
+ border-top: 0;
+}
+
+.panel-group .panel-footer + .panel-collapse .panel-body {
+ border-bottom: 1px solid #dddddd;
+}
+
+.panel-default {
+ border-color: #dddddd;
+}
+
+.panel-default > .panel-heading {
+ color: #333333;
+ background-color: #f5f5f5;
+ border-color: #dddddd;
+}
+
+.panel-default > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #dddddd;
+}
+
+.panel-default > .panel-heading .badge {
+ color: #f5f5f5;
+ background-color: #333333;
+}
+
+.panel-default > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #dddddd;
+}
+
+.panel-primary {
+ border-color: #337cbb;
+}
+
+.panel-primary > .panel-heading {
+ color: #ffffff;
+ background-color: #337cbb;
+ border-color: #337cbb;
+}
+
+.panel-primary > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #337cbb;
+}
+
+.panel-primary > .panel-heading .badge {
+ color: #337cbb;
+ background-color: #ffffff;
+}
+
+.panel-primary > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #337cbb;
+}
+
+.panel-success {
+ border-color: #9ccf91;
+}
+
+.panel-success > .panel-heading {
+ color: #5cb85c;
+ background-color: #a3d7a3;
+ border-color: #9ccf91;
+}
+
+.panel-success > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #9ccf91;
+}
+
+.panel-success > .panel-heading .badge {
+ color: #a3d7a3;
+ background-color: #5cb85c;
+}
+
+.panel-success > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #9ccf91;
+}
+
+.panel-info {
+ border-color: #92e4e9;
+}
+
+.panel-info > .panel-heading {
+ color: #5bc0de;
+ background-color: #b0e1ef;
+ border-color: #92e4e9;
+}
+
+.panel-info > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #92e4e9;
+}
+
+.panel-info > .panel-heading .badge {
+ color: #b0e1ef;
+ background-color: #5bc0de;
+}
+
+.panel-info > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #92e4e9;
+}
+
+.panel-warning {
+ border-color: #f6bd95;
+}
+
+.panel-warning > .panel-heading {
+ color: #f0ad4e;
+ background-color: #f8d9ac;
+ border-color: #f6bd95;
+}
+
+.panel-warning > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #f6bd95;
+}
+
+.panel-warning > .panel-heading .badge {
+ color: #f8d9ac;
+ background-color: #f0ad4e;
+}
+
+.panel-warning > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #f6bd95;
+}
+
+.panel-danger {
+ border-color: #e78e9a;
+}
+
+.panel-danger > .panel-heading {
+ color: #d9534f;
+ background-color: #eba5a3;
+ border-color: #e78e9a;
+}
+
+.panel-danger > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #e78e9a;
+}
+
+.panel-danger > .panel-heading .badge {
+ color: #eba5a3;
+ background-color: #d9534f;
+}
+
+.panel-danger > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #e78e9a;
+}
+
+.embed-responsive {
+ position: relative;
+ display: block;
+ height: 0;
+ padding: 0;
+ overflow: hidden;
+}
+
+.embed-responsive .embed-responsive-item,
+.embed-responsive iframe,
+.embed-responsive embed,
+.embed-responsive object,
+.embed-responsive video {
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ height: 100%;
+ width: 100%;
+ border: 0;
+}
+
+.embed-responsive-16by9 {
+ padding-bottom: 56.25%;
+}
+
+.embed-responsive-4by3 {
+ padding-bottom: 75%;
+}
+
+.well {
+ min-height: 20px;
+ padding: 19px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ border: 1px solid #e3e3e3;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+}
+
+.well blockquote {
+ border-color: #ddd;
+ border-color: rgba(0, 0, 0, 0.15);
+}
+
+.well-lg {
+ padding: 24px;
+ border-radius: 5px;
+}
+
+.well-sm {
+ padding: 9px;
+ border-radius: 2px;
+}
+
+.close {
+ float: right;
+ font-size: 21px;
+ font-weight: bold;
+ line-height: 1;
+ color: #000000;
+ text-shadow: 0 1px 0 #ffffff;
+ opacity: 0.2;
+ filter: alpha(opacity=20);
+}
+
+.close:hover,
+.close:focus {
+ color: #000000;
+ text-decoration: none;
+ cursor: pointer;
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+}
+
+button.close {
+ padding: 0;
+ cursor: pointer;
+ background: transparent;
+ border: 0;
+ -webkit-appearance: none;
+}
+
+.modal-open {
+ overflow: hidden;
+}
+
+.modal {
+ display: none;
+ overflow: hidden;
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1050;
+ -webkit-overflow-scrolling: touch;
+ outline: 0;
+}
+
+.modal.fade .modal-dialog {
+ -webkit-transform: translate(0, -25%);
+ -ms-transform: translate(0, -25%);
+ -o-transform: translate(0, -25%);
+ transform: translate(0, -25%);
+ -webkit-transition: -webkit-transform 0.3s ease-out;
+ -moz-transition: -moz-transform 0.3s ease-out;
+ -o-transition: -o-transform 0.3s ease-out;
+ transition: transform 0.3s ease-out;
+}
+
+.modal.in .modal-dialog {
+ -webkit-transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
+ transform: translate(0, 0);
+}
+
+.modal-open .modal {
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+
+.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: 10px;
+}
+
+.modal-content {
+ position: relative;
+ background-color: #ffffff;
+ border: 1px solid #999999;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ border-radius: 5px;
+ -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
+ box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
+ background-clip: padding-box;
+ outline: 0;
+}
+
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1040;
+ background-color: #000000;
+}
+
+.modal-backdrop.fade {
+ opacity: 0;
+ filter: alpha(opacity=0);
+}
+
+.modal-backdrop.in {
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+}
+
+.modal-header {
+ padding: 15px;
+ border-bottom: 1px solid #e5e5e5;
+ min-height: 16.42857143px;
+}
+
+.modal-header .close {
+ margin-top: -2px;
+}
+
+.modal-title {
+ margin: 0;
+ line-height: 1.42857143;
+}
+
+.modal-body {
+ position: relative;
+ padding: 15px;
+}
+
+.modal-footer {
+ padding: 15px;
+ text-align: right;
+ border-top: 1px solid #e5e5e5;
+}
+
+.modal-footer .btn + .btn {
+ margin-left: 5px;
+ margin-bottom: 0;
+}
+
+.modal-footer .btn-group .btn + .btn {
+ margin-left: -1px;
+}
+
+.modal-footer .btn-block + .btn-block {
+ margin-left: 0;
+}
+
+.modal-scrollbar-measure {
+ position: absolute;
+ top: -9999px;
+ width: 50px;
+ height: 50px;
+ overflow: scroll;
+}
+
+@media (min-width: 768px) {
+ .modal-dialog {
+ width: 600px;
+ margin: 30px auto;
+ }
+
+ .modal-content {
+ -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
+ }
+
+ .modal-sm {
+ width: 300px;
+ }
+}
+
+@media (min-width: 992px) {
+ .modal-lg {
+ width: 900px;
+ }
+}
+
+.tooltip {
+ position: absolute;
+ z-index: 1070;
+ display: block;
+ font-family: Lato;
+ font-size: 12px;
+ font-weight: normal;
+ line-height: 1.4;
+ opacity: 0;
+ filter: alpha(opacity=0);
+}
+
+.tooltip.in {
+ opacity: 0.9;
+ filter: alpha(opacity=90);
+}
+
+.tooltip.top {
+ margin-top: -3px;
+ padding: 5px 0;
+}
+
+.tooltip.right {
+ margin-left: 3px;
+ padding: 0 5px;
+}
+
+.tooltip.bottom {
+ margin-top: 3px;
+ padding: 5px 0;
+}
+
+.tooltip.left {
+ margin-left: -3px;
+ padding: 0 5px;
+}
+
+.tooltip-inner {
+ max-width: 200px;
+ padding: 3px 8px;
+ color: #ffffff;
+ text-align: center;
+ text-decoration: none;
+ background-color: #000000;
+ border-radius: 4px;
+}
+
+.tooltip-arrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+
+.tooltip.top .tooltip-arrow {
+ bottom: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000000;
+}
+
+.tooltip.top-left .tooltip-arrow {
+ bottom: 0;
+ right: 5px;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000000;
+}
+
+.tooltip.top-right .tooltip-arrow {
+ bottom: 0;
+ left: 5px;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000000;
+}
+
+.tooltip.right .tooltip-arrow {
+ top: 50%;
+ left: 0;
+ margin-top: -5px;
+ border-width: 5px 5px 5px 0;
+ border-right-color: #000000;
+}
+
+.tooltip.left .tooltip-arrow {
+ top: 50%;
+ right: 0;
+ margin-top: -5px;
+ border-width: 5px 0 5px 5px;
+ border-left-color: #000000;
+}
+
+.tooltip.bottom .tooltip-arrow {
+ top: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000000;
+}
+
+.tooltip.bottom-left .tooltip-arrow {
+ top: 0;
+ right: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000000;
+}
+
+.tooltip.bottom-right .tooltip-arrow {
+ top: 0;
+ left: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000000;
+}
+
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 1060;
+ display: none;
+ max-width: 276px;
+ padding: 1px;
+ font-family: Lato;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: left;
+ background-color: #ffffff;
+ background-clip: padding-box;
+ border: 1px solid #cccccc;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ border-radius: 5px;
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ white-space: normal;
+}
+
+.popover.top {
+ margin-top: -10px;
+}
+
+.popover.right {
+ margin-left: 10px;
+}
+
+.popover.bottom {
+ margin-top: 10px;
+}
+
+.popover.left {
+ margin-left: -10px;
+}
+
+.popover-title {
+ margin: 0;
+ padding: 8px 14px;
+ font-size: 14px;
+ background-color: #f7f7f7;
+ border-bottom: 1px solid #ebebeb;
+ border-radius: 4px 4px 0 0;
+}
+
+.popover-content {
+ padding: 9px 14px;
+}
+
+.popover > .arrow,
+.popover > .arrow:after {
+ position: absolute;
+ display: block;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+
+.popover > .arrow {
+ border-width: 11px;
+}
+
+.popover > .arrow:after {
+ border-width: 10px;
+ content: "";
+}
+
+.popover.top > .arrow {
+ left: 50%;
+ margin-left: -11px;
+ border-bottom-width: 0;
+ border-top-color: #999999;
+ border-top-color: rgba(0, 0, 0, 0.25);
+ bottom: -11px;
+}
+
+.popover.top > .arrow:after {
+ content: " ";
+ bottom: 1px;
+ margin-left: -10px;
+ border-bottom-width: 0;
+ border-top-color: #ffffff;
+}
+
+.popover.right > .arrow {
+ top: 50%;
+ left: -11px;
+ margin-top: -11px;
+ border-left-width: 0;
+ border-right-color: #999999;
+ border-right-color: rgba(0, 0, 0, 0.25);
+}
+
+.popover.right > .arrow:after {
+ content: " ";
+ left: 1px;
+ bottom: -10px;
+ border-left-width: 0;
+ border-right-color: #ffffff;
+}
+
+.popover.bottom > .arrow {
+ left: 50%;
+ margin-left: -11px;
+ border-top-width: 0;
+ border-bottom-color: #999999;
+ border-bottom-color: rgba(0, 0, 0, 0.25);
+ top: -11px;
+}
+
+.popover.bottom > .arrow:after {
+ content: " ";
+ top: 1px;
+ margin-left: -10px;
+ border-top-width: 0;
+ border-bottom-color: #ffffff;
+}
+
+.popover.left > .arrow {
+ top: 50%;
+ right: -11px;
+ margin-top: -11px;
+ border-right-width: 0;
+ border-left-color: #999999;
+ border-left-color: rgba(0, 0, 0, 0.25);
+}
+
+.popover.left > .arrow:after {
+ content: " ";
+ right: 1px;
+ border-right-width: 0;
+ border-left-color: #ffffff;
+ bottom: -10px;
+}
+
+.carousel {
+ position: relative;
+}
+
+.carousel-inner {
+ position: relative;
+ overflow: hidden;
+ width: 100%;
+}
+
+.carousel-inner > .item {
+ display: none;
+ position: relative;
+ -webkit-transition: 0.6s ease-in-out left;
+ -o-transition: 0.6s ease-in-out left;
+ transition: 0.6s ease-in-out left;
+}
+
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ line-height: 1;
+}
+
+@media all and (transform-3d), (-webkit-transform-3d) {
+ .carousel-inner > .item {
+ -webkit-transition: -webkit-transform 0.6s ease-in-out;
+ -moz-transition: -moz-transform 0.6s ease-in-out;
+ -o-transition: -o-transform 0.6s ease-in-out;
+ transition: transform 0.6s ease-in-out;
+ -webkit-backface-visibility: hidden;
+ -moz-backface-visibility: hidden;
+ backface-visibility: hidden;
+ -webkit-perspective: 1000;
+ -moz-perspective: 1000;
+ perspective: 1000;
+ }
+
+ .carousel-inner > .item.next,
+ .carousel-inner > .item.active.right {
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ left: 0;
+ }
+
+ .carousel-inner > .item.prev,
+ .carousel-inner > .item.active.left {
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ left: 0;
+ }
+
+ .carousel-inner > .item.next.left,
+ .carousel-inner > .item.prev.right,
+ .carousel-inner > .item.active {
+ -webkit-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ left: 0;
+ }
+}
+
+.carousel-inner > .active,
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ display: block;
+}
+
+.carousel-inner > .active {
+ left: 0;
+}
+
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ position: absolute;
+ top: 0;
+ width: 100%;
+}
+
+.carousel-inner > .next {
+ left: 100%;
+}
+
+.carousel-inner > .prev {
+ left: -100%;
+}
+
+.carousel-inner > .next.left,
+.carousel-inner > .prev.right {
+ left: 0;
+}
+
+.carousel-inner > .active.left {
+ left: -100%;
+}
+
+.carousel-inner > .active.right {
+ left: 100%;
+}
+
+.carousel-control {
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ width: 15%;
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+ font-size: 20px;
+ color: #ffffff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
+}
+
+.carousel-control.left {
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
+ background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
+}
+
+.carousel-control.right {
+ left: auto;
+ right: 0;
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
+ background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
+}
+
+.carousel-control:hover,
+.carousel-control:focus {
+ outline: 0;
+ color: #ffffff;
+ text-decoration: none;
+ opacity: 0.9;
+ filter: alpha(opacity=90);
+}
+
+.carousel-control .icon-prev,
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-left,
+.carousel-control .glyphicon-chevron-right {
+ position: absolute;
+ top: 50%;
+ z-index: 5;
+ display: inline-block;
+}
+
+.carousel-control .icon-prev,
+.carousel-control .glyphicon-chevron-left {
+ left: 50%;
+ margin-left: -10px;
+}
+
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-right {
+ right: 50%;
+ margin-right: -10px;
+}
+
+.carousel-control .icon-prev,
+.carousel-control .icon-next {
+ width: 20px;
+ height: 20px;
+ margin-top: -10px;
+ line-height: 1;
+ font-family: serif;
+}
+
+.carousel-control .icon-prev:before {
+ content: '\2039';
+}
+
+.carousel-control .icon-next:before {
+ content: '\203a';
+}
+
+.carousel-indicators {
+ position: absolute;
+ bottom: 10px;
+ left: 50%;
+ z-index: 15;
+ width: 60%;
+ margin-left: -30%;
+ padding-left: 0;
+ list-style: none;
+ text-align: center;
+}
+
+.carousel-indicators li {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ margin: 1px;
+ text-indent: -999px;
+ border: 1px solid #ffffff;
+ border-radius: 10px;
+ cursor: pointer;
+ background-color: #000 \9;
+ background-color: rgba(0, 0, 0, 0);
+}
+
+.carousel-indicators .active {
+ margin: 0;
+ width: 12px;
+ height: 12px;
+ background-color: #ffffff;
+}
+
+.carousel-caption {
+ position: absolute;
+ left: 15%;
+ right: 15%;
+ bottom: 20px;
+ z-index: 10;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ color: #ffffff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
+}
+
+.carousel-caption .btn {
+ text-shadow: none;
+}
+
+@media screen and (min-width: 768px) {
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-prev,
+ .carousel-control .icon-next {
+ width: 30px;
+ height: 30px;
+ margin-top: -15px;
+ font-size: 30px;
+ }
+
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .icon-prev {
+ margin-left: -15px;
+ }
+
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-next {
+ margin-right: -15px;
+ }
+
+ .carousel-caption {
+ left: 20%;
+ right: 20%;
+ padding-bottom: 30px;
+ }
+
+ .carousel-indicators {
+ bottom: 20px;
+ }
+}
+
+.clearfix:before,
+.clearfix:after,
+.dl-horizontal dd:before,
+.dl-horizontal dd:after,
+.container:before,
+.container:after,
+.container-fluid:before,
+.container-fluid:after,
+.row:before,
+.row:after,
+.form-horizontal .form-group:before,
+.form-horizontal .form-group:after,
+.btn-toolbar:before,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:before,
+.btn-group-vertical > .btn-group:after,
+.nav:before,
+.nav:after,
+.navbar:before,
+.navbar:after,
+.navbar-header:before,
+.navbar-header:after,
+.navbar-collapse:before,
+.navbar-collapse:after,
+.pager:before,
+.pager:after,
+.panel-body:before,
+.panel-body:after,
+.modal-footer:before,
+.modal-footer:after {
+ content: " ";
+ display: table;
+}
+
+.clearfix:after,
+.dl-horizontal dd:after,
+.container:after,
+.container-fluid:after,
+.row:after,
+.form-horizontal .form-group:after,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:after,
+.nav:after,
+.navbar:after,
+.navbar-header:after,
+.navbar-collapse:after,
+.pager:after,
+.panel-body:after,
+.modal-footer:after {
+ clear: both;
+}
+
+.center-block {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.pull-right {
+ float: right !important;
+}
+
+.pull-left {
+ float: left !important;
+}
+
+.hide {
+ display: none !important;
+}
+
+.show {
+ display: block !important;
+}
+
+.invisible {
+ visibility: hidden;
+}
+
+.text-hide {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+
+.hidden {
+ display: none !important;
+}
+
+.affix {
+ position: fixed;
+}
+
+@-ms-viewport {
+ width: device-width;
+}
+
+.visible-xs,
+.visible-sm,
+.visible-md,
+.visible-lg {
+ display: none !important;
+}
+
+.visible-xs-block,
+.visible-xs-inline,
+.visible-xs-inline-block,
+.visible-sm-block,
+.visible-sm-inline,
+.visible-sm-inline-block,
+.visible-md-block,
+.visible-md-inline,
+.visible-md-inline-block,
+.visible-lg-block,
+.visible-lg-inline,
+.visible-lg-inline-block {
+ display: none !important;
+}
+
+@media (max-width: 767px) {
+ .visible-xs {
+ display: block !important;
+ }
+
+ table.visible-xs {
+ display: table;
+ }
+
+ tr.visible-xs {
+ display: table-row !important;
+ }
+
+ th.visible-xs,
+ td.visible-xs {
+ display: table-cell !important;
+ }
+}
+
+@media (max-width: 767px) {
+ .visible-xs-block {
+ display: block !important;
+ }
+}
+
+@media (max-width: 767px) {
+ .visible-xs-inline {
+ display: inline !important;
+ }
+}
+
+@media (max-width: 767px) {
+ .visible-xs-inline-block {
+ display: inline-block !important;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm {
+ display: block !important;
+ }
+
+ table.visible-sm {
+ display: table;
+ }
+
+ tr.visible-sm {
+ display: table-row !important;
+ }
+
+ th.visible-sm,
+ td.visible-sm {
+ display: table-cell !important;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-block {
+ display: block !important;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline {
+ display: inline !important;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline-block {
+ display: inline-block !important;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md {
+ display: block !important;
+ }
+
+ table.visible-md {
+ display: table;
+ }
+
+ tr.visible-md {
+ display: table-row !important;
+ }
+
+ th.visible-md,
+ td.visible-md {
+ display: table-cell !important;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-block {
+ display: block !important;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline {
+ display: inline !important;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline-block {
+ display: inline-block !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .visible-lg {
+ display: block !important;
+ }
+
+ table.visible-lg {
+ display: table;
+ }
+
+ tr.visible-lg {
+ display: table-row !important;
+ }
+
+ th.visible-lg,
+ td.visible-lg {
+ display: table-cell !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .visible-lg-block {
+ display: block !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .visible-lg-inline {
+ display: inline !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .visible-lg-inline-block {
+ display: inline-block !important;
+ }
+}
+
+@media (max-width: 767px) {
+ .hidden-xs {
+ display: none !important;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .hidden-sm {
+ display: none !important;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .hidden-md {
+ display: none !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .hidden-lg {
+ display: none !important;
+ }
+}
+
+.visible-print {
+ display: none !important;
+}
+
+@media print {
+ .visible-print {
+ display: block !important;
+ }
+
+ table.visible-print {
+ display: table;
+ }
+
+ tr.visible-print {
+ display: table-row !important;
+ }
+
+ th.visible-print,
+ td.visible-print {
+ display: table-cell !important;
+ }
+}
+
+.visible-print-block {
+ display: none !important;
+}
+
+@media print {
+ .visible-print-block {
+ display: block !important;
+ }
+}
+
+.visible-print-inline {
+ display: none !important;
+}
+
+@media print {
+ .visible-print-inline {
+ display: inline !important;
+ }
+}
+
+.visible-print-inline-block {
+ display: none !important;
+}
+
+@media print {
+ .visible-print-inline-block {
+ display: inline-block !important;
+ }
+}
+
+@media print {
+ .hidden-print {
+ display: none !important;
+ }
+}
+
+/*!
+ * Pingendo customization for Bootstrap
+ * Homepage: http://pingendo.com
+ * Copyright 2015 Pingendo
+ * Licensed under MIT
+*/
+/* Google web fonts support */
+/* TODO: webkit need this why ?*/
+html,
+body {
+ height: 100%;
+}
+
+/* text-inverse is deprecated */
+.text-inverse {
+ color: #ffffff;
+}
+
+/* TODO: verify if we can touch only section */
+.jumbotron {
+ margin-bottom: 0px !important;
+}
+
+.jumbotron h1.text-primary {
+ color: #337cbb !important;
+}
+
+.jumbotron h1.text-inverse {
+ color: #ffffff !important;
+}
+
+.jumbotron h1.text-info {
+ color: #5bc0de !important;
+}
+
+.jumbotron h1.text-success {
+ color: #5cb85c !important;
+}
+
+.jumbotron h1.text-warning {
+ color: #f0ad4e !important;
+}
+
+.jumbotron h1.text-danger {
+ color: #d9534f !important;
+}
+
+.carousel .item img {
+ min-width: 100%;
+}
+
+.section {
+ position: relative;
+ padding: 35px 0;
+}
+
+.section .background-image {
+ z-index: 0;
+ position: absolute;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ background-size: cover;
+ background-position: center;
+}
+
+.section .background-image.background-image-fixed {
+ background-attachment: fixed;
+}
+
+.section-primary {
+ background-color: #8bc4c9 !important;
+ color: #ffffff;
+}
+
+.section-primary .background-image {
+ opacity: 0.5;
+}
+
+.section-info {
+ background-color: #5bc0de !important;
+ color: #ffffff;
+}
+
+.section-info .background-image {
+ opacity: 0.5;
+}
+
+.section-success {
+ background-color: #5cb85c !important;
+ color: #ffffff;
+}
+
+.section-success .background-image {
+ opacity: 0.5;
+}
+
+.section-warning {
+ background-color: #f0ad4e !important;
+ color: #ffffff;
+}
+
+.section-warning .background-image {
+ opacity: 0.5;
+}
+
+.section-danger {
+ background-color: #d9534f !important;
+ color: #ffffff;
+}
+
+.section-danger .background-image {
+ opacity: 0.5;
+}
+
+.cover {
+ padding: 30px 15px;
+ margin-bottom: 30px;
+ color: inherit;
+ background-color: #eeeeee;
+ margin-bottom: 0px !important;
+ padding: 0px 0px;
+ background-color: transparent;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
+ -webkit-align-items: center;
+ align-items: center;
+ overflow: hidden;
+ position: relative;
+ min-height: 100%;
+}
+
+.cover h1,
+.cover .h1 {
+ color: inherit;
+}
+
+.cover p {
+ margin-bottom: 15px;
+ font-size: 21px;
+ font-weight: 200;
+}
+
+.cover > hr {
+ border-top-color: #d5d5d5;
+}
+
+.container .cover,
+.container-fluid .cover {
+ border-radius: 5px;
+}
+
+.cover .container {
+ max-width: 100%;
+}
+
+@media screen and (min-width: 768px) {
+ .cover {
+ padding: 48px 0;
+ }
+
+ .container .cover,
+ .container-fluid .cover {
+ padding-left: 60px;
+ padding-right: 60px;
+ }
+
+ .cover h1,
+ .cover .h1 {
+ font-size: 63px;
+ }
+}
+
+.cover h1.text-primary {
+ color: #337cbb !important;
+}
+
+.cover h1.text-inverse {
+ color: #ffffff !important;
+}
+
+.cover h1.text-info {
+ color: #5bc0de !important;
+}
+
+.cover h1.text-success {
+ color: #5cb85c !important;
+}
+
+.cover h1.text-warning {
+ color: #f0ad4e !important;
+}
+
+.cover h1.text-danger {
+ color: #d9534f !important;
+}
+
+@media screen and (min-width: 768px) {
+ .cover {
+ padding: 0px;
+ }
+
+ .container .cover,
+ .container-fluid .cover {
+ padding-left: 0px;
+ padding-right: 0px;
+ }
+}
+
+.cover .navbar {
+ position: absolute;
+ top: 0px;
+ width: 100%;
+ border: none;
+ background-color: transparent !important;
+}
+
+.cover .navbar .navbar-nav li.active a {
+ background-color: transparent !important;
+}
+
+.cover .navbar .navbar-toggle {
+ border-color: transparent;
+}
+
+.cover .navbar .navbar-toggle:hover,
+.cover .navbar .navbar-toggle:focus {
+ background-color: transparent;
+}
+
+.cover .navbar .navbar-toggle .icon-bar {
+ background-color: #000000;
+}
+
+.cover .navbar.navbar-inverse .navbar-toggle {
+ border-color: transparent;
+}
+
+.cover .navbar.navbar-inverse .navbar-toggle:hover,
+.cover .navbar.navbar-inverse .navbar-toggle:focus {
+ background-color: transparent;
+}
+
+.cover .navbar.navbar-inverse .navbar-toggle .icon-bar {
+ background-color: #ffffff;
+}
+
+.cover .cover-image {
+ z-index: -1;
+ position: absolute;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ background-size: cover;
+ background-position: center;
+}
+
+.cover .cover-image.background-image-fixed,
+.cover .cover-image.cover-image-fixed {
+ background-attachment: fixed;
+}
+
+.user {
+ padding-bottom: 4%;
+ padding-right: 2%;
+ background-position: 6px 7px;
+ background-repeat: no-repeat;
+ background-color: white;
+ padding: 5px 8px 4px 8px;
+ -webkit-border-radius: 0px 0px 8px 8px;
+ -moz-border-radius: 0px 0px 8px 8px;
+ border-radius: 1px 1px 1px 1px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ float: left;
+ margin-left: 8px;
+ background-color: #333;
+ padding: 4px 4px 0px 4px;
+ -webkit-border-radius: 0px 0px 10px 10px;
+ -moz-border-radius: 0px 0px 10px 10px;
+ border-radius: 0px 0px 10px 10px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #794646;
+ background-color: #fff;
+}
+.u_P{
+ padding-right: 2%;
+ padding-bottom:0.5%;
+ margin-right: 1%;
+}
+/* PINGENDO COMMENT DO NOT REMOVE */
diff --git a/membership/static/membership.less b/membership/static/membership.less
new file mode 100755
index 0000000..8f2beea
--- /dev/null
+++ b/membership/static/membership.less
@@ -0,0 +1,733 @@
+/*!
+ * Default theme for Pingendo
+ * Homepage: http://pingendo.com
+ * Copyright 2015 Pingendo
+ * Licensed under MIT
+ * Based on Bootstrap v3.3.4
+*/
+
+
+/* Add custom CSS classes here
+ *
+ * img {
+ * box-shadow : 0px 0px 10px black !important;
+ * }
+*/
+
+//
+// Variables
+// --------------------------------------------------
+//== Colors
+//
+//## Gray and brand colors for use across Bootstrap.
+@gray-base : #000;
+@gray-darker : lighten(@gray-base, 13.5%); // #222
+@gray-dark : lighten(@gray-base, 20%); // #333
+@gray : lighten(@gray-base, 33.5%); // #555
+@gray-light : lighten(@gray-base, 46.7%); // #777
+@gray-lighter : lighten(@gray-base, 93.5%); // #eee
+@brand-primary : #a0ced7;
+@brand-success : #5cb85c;
+@brand-info : #5bc0de;
+@brand-warning : #f0ad4e;
+@brand-danger : #d9534f;
+//== Scaffolding
+//
+//## Settings for some of the most global styles.
+//** Background color for ``.
+@body-bg : white;
+//** Global text color on ``.
+@text-color : black;
+//** Global textual link color.
+@link-color : @brand-primary;
+//** Link hover color set via `darken()` function.
+@link-hover-color : darken(@link-color, 15%);
+//** Link hover decoration.
+@link-hover-decoration : underline;
+//== Typography
+//
+//## Font, line-height, and color for body text, headings, and more.
+@font-family-sans-serif : "Helvetica Neue",
+Helvetica,
+Arial,
+sans-serif;
+@font-family-serif : Georgia,
+"Times New Roman",
+Times,
+serif;
+//** Default monospace fonts for ``, ``, and ``.
+@font-family-monospace : Menlo,
+Monaco,
+Consolas,
+"Courier New",
+monospace;
+@font-family-base : Lato;
+@font-size-base : 14px;
+@font-size-large : ceil((@font-size-base * 1.25)); // ~18px
+@font-size-small : ceil((@font-size-base * 0.85)); // ~12px
+@font-size-h1 : floor((@font-size-base * 2.6)); // ~36px
+@font-size-h2 : floor((@font-size-base * 2.15)); // ~30px
+@font-size-h3 : ceil((@font-size-base * 1.7)); // ~24px
+@font-size-h4 : ceil((@font-size-base * 1.25)); // ~18px
+@font-size-h5 : @font-size-base;
+@font-size-h6 : ceil((@font-size-base * 0.85)); // ~12px
+//** Unit-less `line-height` for use in components like buttons.
+@line-height-base : 1.428571429; // 20/14
+//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
+@line-height-computed : floor((@font-size-base * @line-height-base)); // ~20px
+//** By default, this inherits from the ``.
+@headings-font-family : Lato;
+@headings-font-weight : 500;
+@headings-line-height : 1.1;
+@headings-color : inherit;
+//== Iconography
+//
+//## Specify custom location and filename of the included Glyphicons icon font. Useful for those including Bootstrap via Bower.
+//** Load fonts from this directory.
+@icon-font-path : "../fonts/";
+//** File name for all font files.
+@icon-font-name : "glyphicons-halflings-regular";
+//** Element ID within SVG icon file.
+@icon-font-svg-id : "glyphicons_halflingsregular";
+//== Components
+//
+//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
+@padding-base-vertical : 6px;
+@padding-base-horizontal : 12px;
+@padding-large-vertical : 10px;
+@padding-large-horizontal : 16px;
+@padding-small-vertical : 5px;
+@padding-small-horizontal : 10px;
+@padding-xs-vertical : 1px;
+@padding-xs-horizontal : 5px;
+@line-height-large : 1.3333333; // extra decimals for Win 8.1 Chrome
+@line-height-small : 1.5;
+@border-radius-base : 4px;
+@border-radius-large : 6px;
+@border-radius-small : 3px;
+//** Global color for active items (e.g., navs or dropdowns).
+@component-active-color : contrast(@component-active-bg, @text-color, @text-inverse, 43%);
+//** Global background color for active items (e.g., navs or dropdowns).
+@component-active-bg : @brand-primary;
+//** Width of the `border` for generating carets that indicator dropdowns.
+@caret-width-base : 4px;
+//** Carets increase slightly in size for larger components.
+@caret-width-large : 5px;
+//== Tables
+//
+//## Customizes the `.table` component with basic values, each used across all table variations.
+//** Padding for ``s and ` `s.
+@table-cell-padding : 8px;
+//** Padding for cells in `.table-condensed`.
+@table-condensed-cell-padding : 5px;
+//** Default background color used for all tables.
+@table-bg : transparent;
+//** Background color used for `.table-striped`.
+@table-bg-accent : #f9f9f9;
+//** Background color used for `.table-hover`.
+@table-bg-hover : #f5f5f5;
+@table-bg-active : @table-bg-hover;
+//** Border color for table and cell borders.
+@table-border-color : #ddd;
+//== Buttons
+//
+//## For each of Bootstrap's buttons, define text, background and border color.
+@btn-font-weight : normal;
+@btn-default-color : @text-color;
+@btn-default-bg : @body-bg;
+@btn-default-border :;
+@btn-primary-color : white;
+@btn-primary-bg : @brand-primary; #a0ced7
+@btn-primary-border : darken(@btn-primary-bg, 5%);
+@btn-success-color : white;
+@btn-success-bg : @brand-success;
+@btn-success-border : darken(@btn-success-bg, 5%);
+@btn-info-color : white;
+@btn-info-bg : @brand-info;
+@btn-info-border : darken(@btn-info-bg, 5%);
+@btn-warning-color : white;
+@btn-warning-bg : @brand-warning;
+@btn-warning-border : darken(@btn-warning-bg, 5%);
+@btn-danger-color : contrast(@btn-danger-bg, @text-color, @text-inverse, 43%);
+@btn-danger-bg : @brand-danger;
+@btn-danger-border : darken(@btn-danger-bg, 5%);
+@btn-link-disabled-color : @gray-light;
+//== Forms
+//
+//##
+//** ` ` background color
+@input-bg : #fff;
+//** ` ` background color
+@input-bg-disabled : @gray-lighter;
+//** Text color for ` `s
+@input-color : @gray;
+//** ` ` border color
+@input-border : #ccc;
+// TODO: Rename `@input-border-radius` to `@input-border-radius-base` in v4
+//** Default `.form-control` border radius
+@input-border-radius : @border-radius-base;
+//** Large `.form-control` border radius
+@input-border-radius-large : @border-radius-large;
+//** Small `.form-control` border radius
+@input-border-radius-small : @border-radius-small;
+//** Border color for inputs on focus
+@input-border-focus : #66afe9;
+//** Placeholder text color
+@input-color-placeholder : #999;
+//** Default `.form-control` height
+@input-height-base : (@line-height-computed + (@padding-base-vertical * 2) + 2);
+//** Large `.form-control` height
+@input-height-large : (ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2);
+//** Small `.form-control` height
+@input-height-small : (floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2);
+//** `.form-group` margin
+@form-group-margin-bottom: 15px;
+@legend-color : @gray-dark;
+@legend-border-color : #e5e5e5;
+//** Background color for textual input addons
+@input-group-addon-bg : @gray-lighter;
+//** Border color for textual input addons
+@input-group-addon-border-color : @input-border;
+//** Disabled cursor for form controls and buttons.
+@cursor-disabled : not-allowed;
+//== Dropdowns
+//
+//## Dropdown menu container and contents.
+//** Background for the dropdown menu.
+@dropdown-bg : #fff;
+//** Dropdown menu `border-color`.
+@dropdown-border : rgba(0, 0, 0, .15);
+//** Dropdown menu `border-color` **for IE8**.
+@dropdown-fallback-border : #ccc;
+//** Divider color for between dropdown items.
+@dropdown-divider-bg : #e5e5e5;
+//** Dropdown link text color.
+@dropdown-link-color : @gray-dark;
+//** Hover color for dropdown links.
+@dropdown-link-hover-color : darken(@gray-dark, 5%);
+//** Hover background for dropdown links.
+@dropdown-link-hover-bg : #f5f5f5;
+//** Active dropdown menu item text color.
+@dropdown-link-active-color : @component-active-color;
+//** Active dropdown menu item background color.
+@dropdown-link-active-bg : @component-active-bg;
+//** Disabled dropdown menu item background color.
+@dropdown-link-disabled-color : @gray-light;
+//** Text color for headers within dropdown menus.
+@dropdown-header-color : @gray-light;
+//** Deprecated `@dropdown-caret-color` as of v3.1.0
+@dropdown-caret-color : #000;
+//-- Z-index master list
+//
+// Warning: Avoid customizing these values. They're used for a bird's eye view
+// of components dependent on the z-axis and are designed to all work together.
+//
+// Note: These variables are not generated into the Customizer.
+@zindex-navbar : 1000;
+@zindex-dropdown : 1000;
+@zindex-popover : 1060;
+@zindex-tooltip : 1070;
+@zindex-navbar-fixed : 1030;
+@zindex-modal-background: 1040;
+@zindex-modal: 1050;
+//== Media queries breakpoints
+//
+//## Define the breakpoints at which your layout will change, adapting to different screen sizes.
+// Extra small screen / phone
+//** Deprecated `@screen-xs` as of v3.0.1
+@screen-xs : 480px;
+//** Deprecated `@screen-xs-min` as of v3.2.0
+@screen-xs-min : @screen-xs;
+//** Deprecated `@screen-phone` as of v3.0.1
+@screen-phone : @screen-xs-min;
+// Small screen / tablet
+//** Deprecated `@screen-sm` as of v3.0.1
+@screen-sm : 768px;
+@screen-sm-min : @screen-sm;
+//** Deprecated `@screen-tablet` as of v3.0.1
+@screen-tablet : @screen-sm-min;
+// Medium screen / desktop
+//** Deprecated `@screen-md` as of v3.0.1
+@screen-md : 992px;
+@screen-md-min : @screen-md;
+//** Deprecated `@screen-desktop` as of v3.0.1
+@screen-desktop : @screen-md-min;
+// Large screen / wide desktop
+//** Deprecated `@screen-lg` as of v3.0.1
+@screen-lg : 1200px;
+@screen-lg-min : @screen-lg;
+//** Deprecated `@screen-lg-desktop` as of v3.0.1
+@screen-lg-desktop : @screen-lg-min;
+// So media queries don't overlap when required, provide a maximum
+@screen-xs-max : (@screen-sm-min - 1);
+@screen-sm-max : (@screen-md-min - 1);
+@screen-md-max : (@screen-lg-min - 1);
+//== Grid system
+//
+//## Define your custom responsive grid.
+//** Number of columns in the grid.
+@grid-columns : 12;
+//** Padding between columns. Gets divided in half for the left and right.
+@grid-gutter-width : 30px;
+// Navbar collapse
+//** Point at which the navbar becomes uncollapsed.
+@grid-float-breakpoint : @screen-sm-min;
+//** Point at which the navbar begins collapsing.
+@grid-float-breakpoint-max : (@grid-float-breakpoint - 1);
+//== Container sizes
+//
+//## Define the maximum width of `.container` for different screen sizes.
+// Small screen / tablet
+@container-tablet : (720px + @grid-gutter-width);
+//** For `@screen-sm-min` and up.
+@container-sm : @container-tablet;
+// Medium screen / desktop
+@container-desktop : (940px + @grid-gutter-width);
+//** For `@screen-md-min` and up.
+@container-md : @container-desktop;
+// Large screen / wide desktop
+@container-large-desktop : (1140px + @grid-gutter-width);
+//** For `@screen-lg-min` and up.
+@container-lg : @container-large-desktop;
+//== Navbar
+//
+//##
+// Basics of a navbar
+@navbar-height : 50px;
+@navbar-margin-bottom : @line-height-computed;
+@navbar-border-radius : @border-radius-base;
+@navbar-padding-horizontal : floor((@grid-gutter-width / 2));
+@navbar-padding-vertical : ((@navbar-height - @line-height-computed) / 2);
+@navbar-collapse-max-height : 340px;
+@navbar-default-color : black;
+@navbar-default-bg : #f8f8f8;
+@navbar-default-border : darken(@navbar-default-bg, 6.5%);
+// Navbar links
+@navbar-default-link-color : contrast(@navbar-default-bg, @text-color, @text-inverse, 43%);
+@navbar-default-link-hover-color : @navbar-default-color;
+@navbar-default-link-hover-bg : transparent;
+@navbar-default-link-active-color : @navbar-default-color;
+@navbar-default-link-active-bg : darken(@navbar-default-bg, 6.5%);
+@navbar-default-link-disabled-color : #ccc;
+@navbar-default-link-disabled-bg : transparent;
+// Navbar brand label
+@navbar-default-brand-color : @navbar-default-link-color;
+@navbar-default-brand-hover-color : darken(@navbar-default-brand-color, 10%);
+@navbar-default-brand-hover-bg : transparent;
+// Navbar toggle
+@navbar-default-toggle-hover-bg : #ddd;
+@navbar-default-toggle-icon-bar-bg : #888;
+@navbar-default-toggle-border-color : #ddd;
+// Inverted navbar
+// Reset inverted navbar basics
+@navbar-inverse-color : lighten(@gray-light, 15%);
+@navbar-inverse-bg : #222;
+@navbar-inverse-border : darken(@navbar-inverse-bg, 10%);
+// Inverted navbar links
+@navbar-inverse-link-color : lighten(@gray-light, 15%);
+@navbar-inverse-link-hover-color : #fff;
+@navbar-inverse-link-hover-bg : transparent;
+@navbar-inverse-link-active-color : @navbar-inverse-link-hover-color;
+@navbar-inverse-link-active-bg : darken(@navbar-inverse-bg, 10%);
+@navbar-inverse-link-disabled-color : #444;
+@navbar-inverse-link-disabled-bg : transparent;
+// Inverted navbar brand label
+@navbar-inverse-brand-color : @navbar-inverse-link-color;
+@navbar-inverse-brand-hover-color : #fff;
+@navbar-inverse-brand-hover-bg : transparent;
+// Inverted navbar toggle
+@navbar-inverse-toggle-hover-bg : #333;
+@navbar-inverse-toggle-icon-bar-bg : #fff;
+@navbar-inverse-toggle-border-color : #333;
+//== Navs
+//
+//##
+//=== Shared nav styles
+@nav-link-padding : 10px 15px;
+@nav-link-hover-bg : @gray-lighter;
+@nav-disabled-link-color : @gray-light;
+@nav-disabled-link-hover-color : @gray-light;
+//== Tabs
+@nav-tabs-border-color : #ddd;
+@nav-tabs-link-hover-border-color : @gray-lighter;
+@nav-tabs-active-link-hover-bg : @body-bg;
+@nav-tabs-active-link-hover-color : @gray;
+@nav-tabs-active-link-hover-border-color : #ddd;
+@nav-tabs-justified-link-border-color : #ddd;
+@nav-tabs-justified-active-link-border-color : @body-bg;
+//== Pills
+@nav-pills-border-radius : @border-radius-base;
+@nav-pills-active-link-hover-bg : @component-active-bg;
+@nav-pills-active-link-hover-color : @component-active-color;
+//== Pagination
+//
+//##
+@pagination-color : @link-color;
+@pagination-bg : #fff;
+@pagination-border : #ddd;
+@pagination-hover-color : @link-hover-color;
+@pagination-hover-bg : @gray-lighter;
+@pagination-hover-border : #ddd;
+@pagination-active-color : #fff;
+@pagination-active-bg : @brand-primary;
+@pagination-active-border : @brand-primary;
+@pagination-disabled-color : @gray-light;
+@pagination-disabled-bg : #fff;
+@pagination-disabled-border : #ddd;
+//== Pager
+//
+//##
+@pager-bg : @pagination-bg;
+@pager-border : @pagination-border;
+@pager-border-radius : 15px;
+@pager-hover-bg : @pagination-hover-bg;
+@pager-active-bg : @pagination-active-bg;
+@pager-active-color : @pagination-active-color;
+@pager-disabled-color : @pagination-disabled-color;
+//== Jumbotron
+//
+//##
+@jumbotron-padding : 30px;
+@jumbotron-color : inherit;
+@jumbotron-bg : @gray-lighter;
+@jumbotron-heading-color : inherit;
+@jumbotron-font-size : ceil((@font-size-base * 1.5));
+@jumbotron-heading-font-size: ceil((@font-size-base * 4.5));
+//== Form states and alerts
+//
+//## Define colors for form feedback states and, by default, alerts.
+@state-success-text : @brand-success;
+@state-success-bg : lighten(@brand-success, 20%);
+@state-success-border : darken(spin(@state-success-bg, -10), 5%);
+@state-info-text : @brand-info;
+@state-info-bg : lighten(@brand-info, 20%);
+@state-info-border : darken(spin(@state-info-bg, -10), 7%);
+@state-warning-text : @brand-warning;
+@state-warning-bg : lighten(@brand-warning, 20%);
+@state-warning-border : darken(spin(@state-warning-bg, -10), 5%);
+@state-danger-text : @brand-danger;
+@state-danger-bg : lighten(@brand-danger, 20%);
+@state-danger-border : darken(spin(@state-danger-bg, -10), 5%);
+//== Tooltips
+//
+//##
+//** Tooltip max width
+@tooltip-max-width : 200px;
+//** Tooltip text color
+@tooltip-color : #fff;
+//** Tooltip background color
+@tooltip-bg : #000;
+@tooltip-opacity : .9;
+//** Tooltip arrow width
+@tooltip-arrow-width : 5px;
+//** Tooltip arrow color
+@tooltip-arrow-color : @tooltip-bg;
+//== Popovers
+//
+//##
+//** Popover body background color
+@popover-bg : #fff;
+//** Popover maximum width
+@popover-max-width : 276px;
+//** Popover border color
+@popover-border-color : rgba(0, 0, 0, .2);
+//** Popover fallback border color
+@popover-fallback-border-color : #ccc;
+//** Popover title background color
+@popover-title-bg : darken(@popover-bg, 3%);
+//** Popover arrow width
+@popover-arrow-width : 10px;
+//** Popover arrow color
+@popover-arrow-color : @popover-bg;
+//** Popover outer arrow width
+@popover-arrow-outer-width : (@popover-arrow-width + 1);
+//** Popover outer arrow color
+@popover-arrow-outer-color : fadein(@popover-border-color, 5%);
+//** Popover outer arrow fallback color
+@popover-arrow-outer-fallback-color : darken(@popover-fallback-border-color, 20%);
+//== Labels
+//
+//##
+//** Default label background color
+@label-default-bg : @gray-light;
+//** Primary label background color
+@label-primary-bg : @brand-primary;
+//** Success label background color
+@label-success-bg : @brand-success;
+//** Info label background color
+@label-info-bg : @brand-info;
+//** Warning label background color
+@label-warning-bg : @brand-warning;
+//** Danger label background color
+@label-danger-bg : @brand-danger;
+//** Default label text color
+@label-color : #fff;
+//** Default text color of a linked label
+@label-link-hover-color : #fff;
+//== Modals
+//
+//##
+//** Padding applied to the modal body
+@modal-inner-padding : 15px;
+//** Padding applied to the modal title
+@modal-title-padding : 15px;
+//** Modal title line-height
+@modal-title-line-height : @line-height-base;
+//** Background color of modal content area
+@modal-content-bg : #fff;
+//** Modal content border color
+@modal-content-border-color : rgba(0, 0, 0, .2);
+//** Modal content border color **for IE8**
+@modal-content-fallback-border-color : #999;
+//** Modal backdrop background color
+@modal-backdrop-bg : #000;
+//** Modal backdrop opacity
+@modal-backdrop-opacity : .5;
+//** Modal header border color
+@modal-header-border-color : #e5e5e5;
+//** Modal footer border color
+@modal-footer-border-color : @modal-header-border-color;
+@modal-lg : 900px;
+@modal-md : 600px;
+@modal-sm : 300px;
+//== Alerts
+//
+//## Define alert colors, border radius, and padding.
+@alert-padding : 15px;
+@alert-border-radius : @border-radius-base;
+@alert-link-font-weight : bold;
+@alert-success-bg : @state-success-bg;
+@alert-success-text : @state-success-text;
+@alert-success-border : @state-success-border;
+@alert-info-bg : @state-info-bg;
+@alert-info-text : @state-info-text;
+@alert-info-border : @state-info-border;
+@alert-warning-bg : @state-warning-bg;
+@alert-warning-text : @state-warning-text;
+@alert-warning-border : @state-warning-border;
+@alert-danger-bg : @state-danger-bg;
+@alert-danger-text : @state-danger-text;
+@alert-danger-border : @state-danger-border;
+//== Progress bars
+//
+//##
+//** Background color of the whole progress component
+@progress-bg : #f5f5f5;
+//** Progress bar text color
+@progress-bar-color : #fff;
+//** Variable for setting rounded corners on progress bar.
+@progress-border-radius : @border-radius-base;
+//** Default progress bar color
+@progress-bar-bg : @brand-primary;
+//** Success progress bar color
+@progress-bar-success-bg : @brand-success;
+//** Warning progress bar color
+@progress-bar-warning-bg : @brand-warning;
+//** Danger progress bar color
+@progress-bar-danger-bg : @brand-danger;
+//** Info progress bar color
+@progress-bar-info-bg : @brand-info;
+//== List group
+//
+//##
+//** Background color on `.list-group-item`
+@list-group-bg : @body-bg;
+//** `.list-group-item` border color
+@list-group-border : darken(@list-group-bg, 40%);
+//** List group border radius
+@list-group-border-radius : @border-radius-base;
+//** Background color of single list items on hover
+@list-group-hover-bg : #f5f5f5;
+//** Text color of active list items
+@list-group-active-color : @component-active-color;
+//** Background color of active list items
+@list-group-active-bg : @component-active-bg;
+//** Border color of active list elements
+@list-group-active-border : @list-group-active-bg;
+//** Text color for content within active list items
+@list-group-active-text-color : darken(@list-group-active-bg, 40%);
+//** Text color of disabled list items
+@list-group-disabled-color : @gray-light;
+//** Background color of disabled list items
+@list-group-disabled-bg : @gray-lighter;
+//** Text color for content within disabled list items
+@list-group-disabled-text-color : @list-group-disabled-color;
+@list-group-link-color : #555;
+@list-group-link-hover-color : @list-group-link-color;
+@list-group-link-heading-color : #333;
+//== Panels
+//
+//##
+@panel-bg : @body-bg;
+@panel-body-padding : 15px;
+@panel-heading-padding : 10px 15px;
+@panel-footer-padding : @panel-heading-padding;
+@panel-border-radius : @border-radius-base;
+//** Border color for elements within panels
+@panel-inner-border : #ddd;
+@panel-footer-bg : #f5f5f5;
+@panel-default-text : @gray-dark;
+@panel-default-border : #ddd;
+@panel-default-heading-bg : #f5f5f5;
+@panel-primary-text : contrast(@brand-primary, @text-color, @text-inverse, 43%);
+@panel-primary-border : @brand-primary;
+@panel-primary-heading-bg : @brand-primary;
+@panel-success-text : @state-success-text;
+@panel-success-border : @state-success-border;
+@panel-success-heading-bg : @state-success-bg;
+@panel-info-text : @state-info-text;
+@panel-info-border : @state-info-border;
+@panel-info-heading-bg : @state-info-bg;
+@panel-warning-text : @state-warning-text;
+@panel-warning-border : @state-warning-border;
+@panel-warning-heading-bg : @state-warning-bg;
+@panel-danger-text : @state-danger-text;
+@panel-danger-border : @state-danger-border;
+@panel-danger-heading-bg : @state-danger-bg;
+//== Thumbnails
+//
+//##
+//** Padding around the thumbnail image
+@thumbnail-padding : 4px;
+//** Thumbnail background color
+@thumbnail-bg : @body-bg;
+//** Thumbnail border color
+@thumbnail-border : #ddd;
+//** Thumbnail border radius
+@thumbnail-border-radius : @border-radius-base;
+//** Custom text color for thumbnail captions
+@thumbnail-caption-color : @text-color;
+//** Padding around the thumbnail caption
+@thumbnail-caption-padding : 9px;
+//== Wells
+//
+//##
+@well-bg : #f5f5f5;
+@well-border : darken(@well-bg, 7%);
+//== Badges
+//
+//##
+@badge-color : #fff;
+//** Linked badge text color on hover
+@badge-link-hover-color : #fff;
+@badge-bg : @gray-light;
+//** Badge text color in active nav link
+@badge-active-color : @link-color;
+//** Badge background color in active nav link
+@badge-active-bg : #fff;
+@badge-font-weight : bold;
+@badge-line-height : 1;
+@badge-border-radius : 10px;
+//== Breadcrumbs
+//
+//##
+@breadcrumb-padding-vertical : 8px;
+@breadcrumb-padding-horizontal : 15px;
+//** Breadcrumb background color
+@breadcrumb-bg : #f5f5f5;
+//** Breadcrumb text color
+@breadcrumb-color : #ccc;
+//** Text color of current page in the breadcrumb
+@breadcrumb-active-color : @gray-light;
+//** Textual separator for between breadcrumb elements
+@breadcrumb-separator : "/";
+//== Carousel
+//
+//##
+@carousel-text-shadow : 0 1px 2px rgba(0, 0, 0, .6);
+@carousel-control-color : #fff;
+@carousel-control-width : 15%;
+@carousel-control-opacity : .5;
+@carousel-control-font-size : 20px;
+@carousel-indicator-active-bg : #fff;
+@carousel-indicator-border-color : #fff;
+@carousel-caption-color : #fff;
+//== Close
+//
+//##
+@close-font-weight : bold;
+@close-color : #000;
+@close-text-shadow : 0 1px 0 #fff;
+//== Code
+//
+//##
+@code-color : #c7254e;
+@code-bg : #f9f2f4;
+@kbd-color : #fff;
+@kbd-bg : #333;
+@pre-bg : #f5f5f5;
+@pre-color : @gray-dark;
+@pre-border-color : #ccc;
+@pre-scrollable-max-height : 340px;
+//== Type
+//
+//##
+//** Horizontal offset for forms and lists.
+@component-offset-horizontal : 180px;
+//** Text muted color
+@text-muted : @gray-light;
+//** Abbreviations and acronyms border color
+@abbr-border-color : @gray-light;
+//** Headings small color
+@headings-small-color : @gray-light;
+//** Blockquote small color
+@blockquote-small-color : @gray-light;
+//** Blockquote font size
+@blockquote-font-size : (@font-size-base * 1.25);
+//** Blockquote border color
+@blockquote-border-color : @gray-lighter;
+//** Page header border color
+@page-header-border-color: @gray-lighter;
+//** Width of horizontal description list titles
+@dl-horizontal-offset : @component-offset-horizontal;
+//** Horizontal line color.
+@hr-border : @gray-lighter;
+// Pingendo variables
+@section-spacing : 35px;
+// Core variables and mixins
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/mixins.less";
+// Reset and dependencies
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/normalize.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/print.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/glyphicons.less";
+// Core CSS
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/scaffolding.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/type.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/code.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/grid.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/tables.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/forms.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/buttons.less";
+// Components
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/component-animations.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/dropdowns.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/button-groups.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/input-groups.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/navs.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/navbar.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/breadcrumbs.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/pagination.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/pager.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/labels.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/badges.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/jumbotron.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/thumbnails.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/alerts.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/progress-bars.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/media.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/list-group.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/panels.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/responsive-embed.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/wells.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/close.less";
+// Components w/ JavaScript
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/modals.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/tooltip.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/popovers.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/carousel.less";
+// Utility classes
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/utilities.less";
+@import "https://raw.githubusercontent.com/twbs/bootstrap/v3.3.4/less/responsive-utilities.less";
+@import "https://raw.githubusercontent.com/Pingendo/pingendo-bootstrap/gh-pages/less/pingendo-custom.less";
+
+/* PINGENDO COMMENT DO NOT REMOVE */
\ No newline at end of file
diff --git a/membership/static/photo-1418479631014-8cbf89db3431 2.jpg b/membership/static/photo-1418479631014-8cbf89db3431 2.jpg
new file mode 100755
index 0000000..45c12ab
Binary files /dev/null and b/membership/static/photo-1418479631014-8cbf89db3431 2.jpg differ
diff --git a/membership/static/photo-1418479631014-8cbf89db3431 2@2x.png b/membership/static/photo-1418479631014-8cbf89db3431 2@2x.png
new file mode 100755
index 0000000..e39740f
Binary files /dev/null and b/membership/static/photo-1418479631014-8cbf89db3431 2@2x.png differ
diff --git a/membership/static/photo-1418479631014-8cbf89db3431.jpeg b/membership/static/photo-1418479631014-8cbf89db3431.jpeg
new file mode 100755
index 0000000..f90e2cc
Binary files /dev/null and b/membership/static/photo-1418479631014-8cbf89db3431.jpeg differ
diff --git a/membership/static/photo-1418479631014-8cbf89db3431.sketch b/membership/static/photo-1418479631014-8cbf89db3431.sketch
new file mode 100755
index 0000000..1fd104f
Binary files /dev/null and b/membership/static/photo-1418479631014-8cbf89db3431.sketch differ
diff --git a/membership/static/stylesheet.css b/membership/static/stylesheet.css
new file mode 100755
index 0000000..9357a1c
--- /dev/null
+++ b/membership/static/stylesheet.css
@@ -0,0 +1,168 @@
+@charset "utf-8";
+/* CSS Document */
+
+/* ---------- FONTAWESOME ---------- */
+/* ---------- http://fortawesome.github.com/Font-Awesome/ ---------- */
+/* ---------- http://weloveiconfonts.com/ ---------- */
+
+*[class*="fontawesome-"]:before {
+ font-family: 'FontAwesome', sans-serif;
+}
+
+/* ---------- GENERAL ---------- */
+
+/*body {*/
+/*background: #f9f9f9;*/
+/*color: #0e171c;*/
+/*font: 300 100%/1em 'Lato', sans-serif;*/
+/*margin: 0;*/
+/*}*/
+/**/
+/*a {*/
+/*text-decoration: none;*/
+/*}*/
+
+/*Month size*/
+#monthtitle {
+ font-size: 1.2em;
+ line-height: 1.25em;
+ margin: .25em 0;
+ font-weight: 600;
+}
+
+h3 {
+ font-size: 1.5em;
+ line-height: 1em;
+ margin: .33em 0;
+}
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+ margin: auto;
+
+}
+
+/*.container {*/
+/*height: 358px;*/
+/*left: 50%;*/
+/*margin: -255px 0 0 -245px;*/
+/*position: absolute;*/
+/*top: 50%;*/
+/*width: 340px;*/
+/*}*/
+
+/* ---------- CALENDAR ---------- */
+
+.calendar {
+ text-align: center;
+}
+
+.calendar header {
+ position: relative;
+}
+
+.calendar #monthtitle {
+ text-transform: uppercase;
+ color: #1A6687;
+}
+
+#datesbooked {
+ color: #1a6687;
+ padding-top: 2px;
+}
+
+/*Title*/
+.calendar thead {
+ font-weight: 500;
+ /*text-transform: uppercase;*/
+ color: #8BC4C9;
+ /*margin-bottom:1px;*/
+
+}
+
+/*Body text*/
+.calendar tbody {
+ color: #7c8a95;
+}
+
+/*select date*/
+.calendar tbody td:hover {
+ background: #8BC4C9;
+ color: #f9f9f9;
+ /*border: .1px solid #8BC4C9;*/
+
+ /*border-radius: 50%;*/
+}
+
+.selected {
+ background: #6b9699;
+ color: #f9f9f9;
+}
+
+.calendar thead > tr > td {
+ border-top: hidden;
+ border-left: hidden;
+ border-right: hidden;
+}
+
+.calendar td {
+ border: .1px solid #cbd1d2;
+ /*border-radius: 50%;*/
+ display: inline-block;
+ height: 2.5em;
+ line-height: 2.5em;
+ text-align: center;
+ width: 2.5em;
+
+}
+
+.calendar .prev-month,
+.calendar .next-month {
+ /*border: .1px solid #cbd1d2;*/
+ color: #cbd1d2;
+
+}
+
+.calendar .prev-month:hover,
+.calendar .next-month:hover {
+ border: .5px solid #cbd1d2;
+ background: #cbd1d2;
+ color: #f9f9f9;
+}
+
+/*Today*/
+.current-day {
+ color: #8BC4C9;
+ /*background-color: #8BC4C9;*/
+}
+
+/*Next,Prev month*/
+.btn-prev,
+.btn-next {
+ border: 1px solid transparent;
+ color: #8BC4C9;
+ font-size: 1.5em;
+ padding: 1em;
+ /*height: .7em;*/
+ /*line-height: .3em;*/
+ /*margin: auto;*/
+ /*position: absolute;*/
+ /*top: .1em;*/
+ /*width: 25em;*/
+}
+
+.btn-prev:hover,
+.btn-next:hover {
+ background: none;
+ color: #1A6687;
+}
+
+.btn-prev {
+ left: 6em;
+}
+
+.btn-next {
+ right: 6em;
+}
+
diff --git a/membership/templates/calendar/calendar.html b/membership/templates/calendar/calendar.html
new file mode 100755
index 0000000..0085236
--- /dev/null
+++ b/membership/templates/calendar/calendar.html
@@ -0,0 +1,113 @@
+
+
+
+
diff --git a/membership/templates/confirm.html b/membership/templates/confirm.html
new file mode 100755
index 0000000..314253d
--- /dev/null
+++ b/membership/templates/confirm.html
@@ -0,0 +1,65 @@
+
+
+
+
+
+ {% load static %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Your membership is almost ready!
+ If this is correct information, click
+ CONFIRM
+
+ Name: {{ name }}
+
+ {% if email %}
+ Email: {{ email }}
+ {% else %}
+
+ {% endif %}
+ Membership requested for:
+ 01.01.2016-31.12.2016
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/membership/templates/creditcard.html b/membership/templates/creditcard.html
new file mode 100755
index 0000000..11d4c4f
--- /dev/null
+++ b/membership/templates/creditcard.html
@@ -0,0 +1,108 @@
+
+
+ {% load static %}
+
+
+
+
+
+
+
+
+
+ {% load static %}
+
+
+
+
+
+
+
+
+
Payment details
+
+
+
+
+
+ {% csrf_token %}
+ {% for field in form %}
+
+ {{ field.label }}*
+ {{ field }}
+ {% for error in field.errors %}
+ {{ error|striptags }}
+ {% endfor %}
+
+ {% endfor %}
+ Submit
+
+
Cancel
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/membership/templates/error.html b/membership/templates/error.html
new file mode 100755
index 0000000..1cd0441
--- /dev/null
+++ b/membership/templates/error.html
@@ -0,0 +1,55 @@
+
+
+ {% load static %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Oops! Something went wrong..
+
+
+
+
+
Your last action was not complete. {{ msg }}
+ Have problems? contact us at
+ help@digitalglarus.ch
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/membership/templates/login.html b/membership/templates/login.html
new file mode 100755
index 0000000..21fa571
--- /dev/null
+++ b/membership/templates/login.html
@@ -0,0 +1,53 @@
+{% extends "new_base_glarus.html" %}
+{% load static cms_tags bootstrap3%}
+{% block title %}crowdfunding{% endblock %}
+
+{% block content %}
+
+
+
+
+
+
I'm already a member!
+
To book you need to be logged in.
+
Log in
+
+
+ {% csrf_token %}
+ {% for field in login_form %}
+
+
+ {% bootstrap_field field type='fields'%}
+
+ {% endfor %}
+ {{ login_form.non_field_errors }}
+ Submit
+
+
+
+
+
+
Not yet a member?
+
+
It only takes your email to register!
+ You'll get a mail from us for confirmation.
+
+
Register
+
+
+ {% csrf_token %}
+
+ {% for field in register_form %}
+ {% bootstrap_field field type='fields'%}
+
+
+ {% endfor %}
+
+ Submit
+
+
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/membership/templates/membership.html b/membership/templates/membership.html
new file mode 100755
index 0000000..f2b8cb5
--- /dev/null
+++ b/membership/templates/membership.html
@@ -0,0 +1,249 @@
+{% load static cms_tags %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% if request.user.is_authenticated %}
+
{{ request.user.name }} (
Logout )
+ {% else %}
+
Login
+ {% endif %}
+
+
+
+ {% load static %}
+
+
+
+
+
+
When do you want to cowork?
+
+
Pick a date!
+
Calender
+
+
+
+
+
+
+
+ {% include 'calendar/calendar.html' %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Become our member of Digital Glarus!
+
+
+
+
+
+
+
+
+
+
+
+
The Spontaneous
+
+
35CHF/Month (1 day pass included)
+
+
Do you dream of having a place to be inspired in the middle of the Alps?
+ With only 35CHF a month, you can enjoy the full benefit of a Digital Chalet
+ Schwanden membership! You can enjoy high speed network connection and comfortable
+ working desks where you can come up with best ideas for your project surrounded
+ by friendly coworkers. And if your work gets too productive to leave, you
+ can crash on our guest bed for the night, the house has everything a coworker
+ needs from an equipped kitchen to a shower. The Spontaneous includes 1
+ day pass included, it is perfect for you if you are planning a retreat
+ month of a coworking in the nature, or coming for a limited period to Switzerland
+ for coworking. It is a perfect try-out package!
+
+
+
Buy Now
+
+
+
+
+
+
+
+
+
The Committed
+
+
360CHF/Year (2 free day per month included)
+
+
Be a regular coworker in our Digital Chalet Schwanden! With only 360CHF,
+ you can enjoy the full coworking space for the whole year, with additional
+ 2 free day passes for each month. It is an ideal deal for our busy and
+ active coworkers who would like to save time(and nerve)for requesting new
+ membership every month. Signifiantly discounted price is applied for yearly
+ membership.
+
+
+
Buy Now
+
+
+
+
+
+
+
+
+
+
+
+
A Quick Glance..
+
+
A short guide for membership features.
+
+
+
+
+
+
+
+
+ The Spontaneous
+ The Committed
+
+
+
+
+ Includes
+ 1 work day included
+ 2 free work days per month
+
+
+ Fits for
+ Great for trial, see how it goes
+ Perfect for coworking with great price
+
+
+ Price
+ Decicde every month
+ Pay once per year
+
+
+ Membership price
+ 35CHF/Month
+ 360CHF/Year
+
+
+ Price per additional day
+ 20 CHF
+ 15 CHF
+
+
+
+
+
+
+
+
+
+
+
+
Digital Glarus
+
+
In der Au 7 8762 Schwanden
+ Copyright © ungleich GmbH 2016
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/membership/templates/success.html b/membership/templates/success.html
new file mode 100755
index 0000000..2b690bf
--- /dev/null
+++ b/membership/templates/success.html
@@ -0,0 +1,32 @@
+{% load static %}
+
+
+
+
+
+
+
+
+
+
+
+
+
You're successfully registered!
+
+
+
+
+
+ Check your email to activate your account.
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/membership/templates/validated.html b/membership/templates/validated.html
new file mode 100755
index 0000000..ca84730
--- /dev/null
+++ b/membership/templates/validated.html
@@ -0,0 +1,39 @@
+{% load static %}
+
+
+
+
+
+
+
+
+ {% if request.session.next == None %}
+
+ {% endif %}
+
+
+
+
+
+
+
+ {% if msg == 'succeeded' %}
+ Thank You for Your payment! redirecting...
+ {% else %}
+ Your payment was not processed correctly. Please contact us
here !
+ {% endif %}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/membership/templates/validated_email.html b/membership/templates/validated_email.html
new file mode 100755
index 0000000..a1c06a5
--- /dev/null
+++ b/membership/templates/validated_email.html
@@ -0,0 +1,38 @@
+
+
+
+
+ {% load static %}
+
+
+
+
+ {% if request.session.next == None %}
+
+ {% endif %}
+
+
+
+
+
+
+
+ {% if msg %}
+ Email verified! redirecting...
+ {% else %}
+
Email not verfied!
+ {% endif %}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/membership/tests.py b/membership/tests.py
new file mode 100755
index 0000000..4b36fe4
--- /dev/null
+++ b/membership/tests.py
@@ -0,0 +1,41 @@
+# import re
+
+# from django.test import TestCase
+# from django.core.urlresolvers import reverse
+# from django.core import mail
+
+
+# class LoginTestCase(TestCase):
+# def test_login(self):
+# url = reverse('login_glarus')
+# res = self.client.post(
+# url,
+# data={
+# 'email': 'test@gmail.com',
+# 'password': 'test', 'name':
+# 'test'}
+# )
+# self.assertContains(res, "You\'re successfully registered!", 1, 200)
+# self.assertEqual(len(mail.outbox), 1)
+#
+# validation_url = re.findall(r"http://.*?(/.*)", mail.outbox[0].body)
+# res1 = self.client.get(validation_url[0] + '/')
+# self.assertContains(res1, "Email verified!", 1, 200)
+#
+# res2 = self.client.post(
+# url, data={'email': 'test@gmail.com', 'password': 'test'}
+# )
+# self.assertEqual(res2.status_code, 302)
+# redirect_location = res2.get('Location')
+#
+# res3 = self.client.get(redirect_location)
+# self.assertContains(res3, 'Pick coworking date.', 1, 200)
+#
+# # check fail login
+#
+# res4 = self.client.post(
+# url, data={
+# 'email': 'test@gmail.com', 'password': 'falsepassword'
+# }
+# )
+# self.assertContains(res4, 'Sorry, that login was invalid.', 1, 200)
diff --git a/membership/urls.py b/membership/urls.py
new file mode 100755
index 0000000..901a8e0
--- /dev/null
+++ b/membership/urls.py
@@ -0,0 +1,13 @@
+from django.urls import re_path
+from django.contrib.auth.decorators import login_required
+
+from . import views
+
+urlpatterns = (
+ re_path(r"^$", views.LoginRegistrationView.as_view(), name='login_glarus'),
+ re_path(r"^validate/(?P.*)/$", views.validate_email),
+ re_path(r"^membership/$", login_required(views.MembershipView.as_view()), name='membership'),
+ re_path(r'logout/?$', views.logout_glarus, name='logout_glarus'),
+ re_path(r"^buy/(?P\w+)/$", login_required(views.CreditCardView.as_view()), name='payment'),
+ re_path(r'^buy/(?P\w+)/reset', login_required(views.reset), name='reset')
+)
diff --git a/membership/views.py b/membership/views.py
new file mode 100755
index 0000000..6fea3ed
--- /dev/null
+++ b/membership/views.py
@@ -0,0 +1,136 @@
+from django.shortcuts import render, redirect
+from django.views.generic import View
+from django.views.decorators.cache import cache_control
+from django.conf import settings
+from django.db.models import Q
+from django.utils.translation import get_language
+from django.contrib.auth import logout
+from django.http import HttpResponseRedirect
+from django.contrib.auth import login
+
+from .models import CustomUser, StripeCustomer
+from .forms import LoginForm, RegisterForm, PaymentForm
+from utils.stripe_utils import StripeUtils
+
+
+def validate_email(request, validate_slug):
+ validated = CustomUser.validate_url(validate_slug)
+ if validated:
+ return render(request, 'templates/validated_email.html', {'msg': True})
+ else:
+ return render(request, 'templates/error.html', {'msg': 'Validation failed.'})
+
+
+def reset(request, time):
+ request.session['next'] = 0
+ return redirect('payment', time=time)
+
+
+class CreditCardView(View):
+ def _get_context(self, request, time):
+ request.session['time'] = time
+ context = {}
+ context['name'] = request.user.name
+ if time == 'month':
+ context['time'] = "1 month"
+ context['price'] = "35"
+ context['free'] = "1"
+ elif time == 'year':
+ context['time'] = '1 year'
+ context['price'] = '360'
+ context['free'] = "2"
+ context['stripe_key'] = settings.STRIPE_API_PUBLIC_KEY
+ context['form'] = PaymentForm()
+ return context
+
+ @cache_control(no_cache=True, must_revalidate=True)
+ def get(self, request, time=None):
+ context = self._get_context(request, time)
+ next = request.session.get('next')
+ if next == 1 or next == 0:
+ template = 'templates/creditcard.html'
+ request.session['next'] += 1
+ elif next == 2:
+ customer = StripeCustomer.get_or_create(email=request.user.email, token=request.session['token'])
+ stripe_utils = StripeUtils()
+ charge = stripe_utils.make_charge(request.session['amount'], customer=customer.stripe_id)
+ template = 'templates/validated.html'
+ resp = charge.get('response_object')
+ context['msg'] = resp.get('status', None)
+ request.session['next'] = None
+ return render(request, template, context)
+
+ def post(self, request, time=None):
+ form = PaymentForm(request.POST)
+ stripe_token = request.POST['stripeToken']
+
+ if form.is_valid():
+ form.save(request.user)
+ amount = 35 if time == 'month' else 360
+ request.session['token'] = stripe_token
+ request.session['amount'] = amount
+ request.session['next'] += 1
+ return render(request, 'templates/confirm.html',
+ context={'name': request.user.name, 'email': request.user.email})
+ else:
+ context = self._get_context(request, time)
+ context['form'] = form
+ return render(request, 'templates/creditcard.html', context=context)
+
+
+class LoginRegistrationView(View):
+ def get(self, request):
+ login_form = LoginForm()
+ register_form = RegisterForm()
+ request.session['next'] = None
+ if request.user.is_authenticated():
+ return redirect("membership")
+ else:
+ return render(request, 'templates/login.html',
+ {'login_form': login_form, 'register_form': register_form})
+
+ def post(self, request):
+ is_login = request.POST.get('is_login', False)
+
+ if not is_login:
+ form = RegisterForm(request.POST)
+ if form.is_valid():
+ email = form.validated_data.get('email')
+ password = form.validated_data.get('password')
+ name = form.validated_data.get('name')
+ user = CustomUser.register(name, password, email)
+ if user:
+ return render(request, 'templates/success.html')
+ else:
+ return render(request, 'templates/error.html')
+ else:
+ login_form = LoginForm()
+ return render(request, 'templates/login.html',
+ context={'login_form': login_form, 'register_form': form})
+ else:
+ form = LoginForm(request.POST)
+ if form.is_valid():
+ user = form.login(request)
+ if user:
+ login(request, user)
+ return redirect('membership')
+ else:
+ registration_form = RegisterForm()
+ return render(request, 'templates/login.html',
+ context={'login_form': form, 'register_form': registration_form})
+
+
+class MembershipView(View):
+ def get(self, request):
+ # if the user has payed already
+ member_payed = request.user.creditcards_set.filter(Q(payment_type='month') | Q(payment_type='year'))
+ if member_payed:
+ return redirect('/')
+ request.session['next'] = 0
+ language = get_language()
+ return render(request, 'templates/membership.html', context={'language_code': language})
+
+
+def logout_glarus(request):
+ logout(request)
+ return HttpResponseRedirect('/digitalglarus')
diff --git a/nginx/Dockerfile b/nginx/Dockerfile
new file mode 100644
index 0000000..3a45637
--- /dev/null
+++ b/nginx/Dockerfile
@@ -0,0 +1,11 @@
+# Use the official Nginx image from the Docker Hub
+FROM nginx:latest
+
+# Copy custom configuration file to Nginx configuration directory
+COPY ./nginx.conf /etc/nginx/nginx.conf
+
+# Expose port
+EXPOSE 80
+
+# Start Nginx
+CMD ["nginx", "-g", "daemon off;"]
diff --git a/nginx/nginx.conf b/nginx/nginx.conf
new file mode 100644
index 0000000..c26cacf
--- /dev/null
+++ b/nginx/nginx.conf
@@ -0,0 +1,25 @@
+# nginx.conf
+events {
+ # Configuration related to event processing
+ # For most cases, the default settings suffice
+}
+
+# Default server configuration
+http {
+ server {
+ listen 80;
+ server_name localhost;
+
+ location / {
+ # Forward requests to the uWSGI server
+ #uwsgi_pass unix:/app/dynamicweb2.sock;
+ uwsgi_pass dynamicweb2:8000;
+ include /etc/nginx/uwsgi_params;
+ }
+
+ location /static/ {
+ # Serve static files from the Django app
+ alias /app/static/;
+ }
+ }
+}
diff --git a/opennebula_api/__init__.py b/opennebula_api/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/opennebula_api/admin.py b/opennebula_api/admin.py
new file mode 100755
index 0000000..4185d36
--- /dev/null
+++ b/opennebula_api/admin.py
@@ -0,0 +1,3 @@
+# from django.contrib import admin
+
+# Register your models here.
diff --git a/opennebula_api/apps.py b/opennebula_api/apps.py
new file mode 100755
index 0000000..c70ffbd
--- /dev/null
+++ b/opennebula_api/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class OpennebulaApiConfig(AppConfig):
+ name = 'opennebula_api'
diff --git a/opennebula_api/exceptions.py b/opennebula_api/exceptions.py
new file mode 100755
index 0000000..e9d3c0f
--- /dev/null
+++ b/opennebula_api/exceptions.py
@@ -0,0 +1,10 @@
+class KeyExistsError(Exception):
+ pass
+
+
+class UserExistsError(Exception):
+ pass
+
+
+class UserCredentialError(Exception):
+ pass
diff --git a/opennebula_api/opennebula_manager.py b/opennebula_api/opennebula_manager.py
new file mode 100755
index 0000000..b3e21ec
--- /dev/null
+++ b/opennebula_api/opennebula_manager.py
@@ -0,0 +1,643 @@
+import logging
+import socket
+
+import oca
+from django.conf import settings
+from oca.exceptions import OpenNebulaException
+from oca.pool import WrongNameError, WrongIdError
+
+from hosting.models import HostingOrder
+from utils.models import CustomUser
+from utils.tasks import save_ssh_key, save_ssh_key_error_handler
+from .exceptions import KeyExistsError, UserExistsError, UserCredentialError
+
+logger = logging.getLogger(__name__)
+
+
+class OpenNebulaManager():
+ """This class represents an opennebula manager."""
+
+ def __init__(self, email=None, password=None):
+ self.email = email
+ self.password = password
+ # Get oneadmin client
+ self.oneadmin_client = None if settings.BYPASS_OPENNEBULA else self._get_opennebula_client(
+ settings.OPENNEBULA_USERNAME,
+ settings.OPENNEBULA_PASSWORD
+ )
+
+ # Get or create oppenebula user using given credentials
+ try:
+ self.opennebula_user = self._get_or_create_user(
+ email,
+ password
+ )
+ # If opennebula user was created/obtained, get his client
+ self.client = self._get_opennebula_client(
+ email,
+ password
+ )
+ except:
+ pass
+
+ def _get_client(self, user):
+ """Get a opennebula client object for a CustomUser object
+
+ Args:
+ user (CustomUser): dynamicweb CustomUser object
+
+ Returns:
+ oca.Client: Opennebula client object
+
+ Raise:
+ ConnectionError: If the connection to the opennebula server can't be
+ established
+ """
+ return self._get_opennebula_client(user.email, user.password)
+
+ def _get_opennebula_client(self, username, password):
+ return None if settings.BYPASS_OPENNEBULA else oca.Client(
+ "{0}:{1}".format(username, password),
+ "{protocol}://{domain}:{port}{endpoint}".format(
+ protocol=settings.OPENNEBULA_PROTOCOL,
+ domain=settings.OPENNEBULA_DOMAIN,
+ port=settings.OPENNEBULA_PORT,
+ endpoint=settings.OPENNEBULA_ENDPOINT
+ )
+ )
+
+ def _get_user(self, user):
+ """Get the corresponding opennebula user for a CustomUser object
+
+ Args:
+ user (CustomUser): dynamicweb CustomUser object
+
+ Returns:
+ oca.User: Opennebula user object
+
+ Raise:
+ WrongNameError: If no openebula user with this credentials exists
+ ConnectionError: If the connection to the opennebula server can't be
+ established
+ """
+ user_pool = self._get_user_pool()
+ return user_pool.get_by_name(user.email)
+
+ def create_user(self, user: CustomUser):
+ """Create a new opennebula user or a corresponding CustomUser object
+
+
+ Args:
+ user (CustomUser): dynamicweb CustomUser object
+
+ Returns:
+ int: Return the opennebula user id
+
+ Raises:
+ ConnectionError: If the connection to the opennebula server can't be
+ established
+ UserExistsError: If a user with this credeintals already exits on the
+ server
+ UserCredentialError: If a user with this email exists but the
+ password is worng
+
+ """
+ try:
+ self._get_user(user)
+ try:
+ self._get_client(self, user)
+ logger.debug('User already exists')
+ raise UserExistsError()
+ except OpenNebulaException as err:
+ logger.error('OpenNebulaException error: {0}'.format(err))
+ logger.error('User exists but password is wrong')
+ raise UserCredentialError()
+
+ except WrongNameError:
+ user_id = self.oneadmin_client.call(oca.User.METHODS['allocate'],
+ user.email, user.password,
+ 'core')
+ logger.debug(
+ 'Created a user for CustomObject: {user} with user id = {u_id}',
+ user=user,
+ u_id=user_id
+ )
+ return user_id
+ except ConnectionRefusedError:
+ logger.error(
+ 'Could not connect to host: {host} via protocol {protocol}'.format(
+ host=settings.OPENNEBULA_DOMAIN,
+ protocol=settings.OPENNEBULA_PROTOCOL)
+ )
+ raise ConnectionRefusedError
+
+ def _get_or_create_user(self, email, password):
+ try:
+ user_pool = self._get_user_pool()
+ opennebula_user = user_pool.get_by_name(email)
+ return opennebula_user
+ except WrongNameError as wrong_name_err:
+ opennebula_user = self.oneadmin_client.call(
+ oca.User.METHODS['allocate'], email,
+ password, 'core')
+ logger.debug(
+ "User {} does not exist. Created the user. User id = {}".format(
+ email,
+ opennebula_user
+ )
+ )
+ return opennebula_user
+ except ConnectionRefusedError:
+ logger.error(
+ 'Could not connect to host: {host} via protocol {protocol}'.format(
+ host=settings.OPENNEBULA_DOMAIN,
+ protocol=settings.OPENNEBULA_PROTOCOL)
+ )
+ raise ConnectionRefusedError
+ except Exception as ex:
+ logger.error(str(ex))
+
+ def _get_user_pool(self):
+ try:
+ user_pool = oca.UserPool(self.oneadmin_client)
+ user_pool.info()
+ except ConnectionRefusedError:
+ logger.error(
+ 'Could not connect to host: {host} via protocol {protocol}'.format(
+ host=settings.OPENNEBULA_DOMAIN,
+ protocol=settings.OPENNEBULA_PROTOCOL)
+ )
+ raise
+ return user_pool
+
+ def _get_vm_pool(self, infoextended=True):
+ """
+ # filter:
+ # -4: Resources belonging to the user’s primary group
+ # -3: Resources belonging to the user
+ # -2: All resources
+ # -1: Resources belonging to the user and any of his groups
+ # >= 0: UID User’s Resources
+
+ # vm states:
+ # *-2 Any state, including DONE
+ # *-1 Any state, except DONE (Default)
+ # *0 INIT
+ # *1 PENDING
+ # *2 HOLD
+ # *3 ACTIVE
+ # *4 STOPPED
+ # *5 SUSPENDED
+ # *6 DONE
+ # *7 FAILED
+ # *8 POWEROFF
+ # *9 UNDEPLOYED
+
+ :param infoextended: When True calls infoextended api method introduced
+ in OpenNebula 5.8 else falls back to info which has limited attributes
+ of a VM
+
+ :return: the oca VirtualMachinePool object
+ """
+ try:
+ vm_pool = oca.VirtualMachinePool(self.client)
+ if infoextended:
+ vm_pool.infoextended(
+ filter=-1, # User's resources and any of his groups
+ vm_state=-1 # Look for VMs in any state, except DONE
+ )
+ else:
+ vm_pool.info()
+ return vm_pool
+ except AttributeError as ae:
+ logger.error("AttributeError : %s" % str(ae))
+ except ConnectionRefusedError:
+ logger.error(
+ 'Could not connect to host: {host} via protocol {protocol}'.format(
+ host=settings.OPENNEBULA_DOMAIN,
+ protocol=settings.OPENNEBULA_PROTOCOL)
+ )
+ raise ConnectionRefusedError
+ # For now we'll just handle all other errors as connection errors
+ except:
+ raise ConnectionRefusedError
+
+ def get_vms(self):
+ try:
+ return self._get_vm_pool()
+ except ConnectionRefusedError:
+ raise ConnectionRefusedError
+
+ def get_vm(self, vm_id):
+ vm_id = int(vm_id)
+ try:
+ vm_pool = self._get_vm_pool()
+ return vm_pool.get_by_id(vm_id)
+ except WrongIdError:
+ raise WrongIdError
+ except:
+ raise ConnectionRefusedError
+
+ def get_ipv6(self, vm_id):
+ """
+ Returns the first IPv6 of the given vm.
+
+ :return: An IPv6 address string, if it exists else returns None
+ """
+ ipv6_list = self.get_all_ipv6_addresses(vm_id)
+ if len(ipv6_list) > 0:
+ return ipv6_list[0]
+ else:
+ return None
+
+ def get_all_ipv6_addresses(self, vm_id):
+ """
+ Returns a list of IPv6 addresses of the given vm
+
+ :param vm_id: The ID of the vm
+ :return:
+ """
+ ipv6_list = []
+ vm = self.get_vm(vm_id)
+ for nic in vm.template.nics:
+ if hasattr(nic, 'ip6_global'):
+ ipv6_list.append(nic.ip6_global)
+ return ipv6_list
+
+ def create_vm(self, template_id, specs, ssh_key=None, vm_name=None):
+
+ template = self.get_template(template_id)
+ vm_specs_formatter = """
+ {memory}
+ {vcpu}
+ {cpu}
+ """
+ try:
+ disk = template.template.disks[0]
+ image_id = disk.image_id
+ vm_specs = vm_specs_formatter.format(
+ vcpu=int(specs['cpu']),
+ cpu=0.1 * int(specs['cpu']),
+ memory=(512 if specs['memory'] == 0.5 else
+ 1024 * int(specs['memory'])),
+ )
+ vm_specs += """
+ fs
+ {size}
+ vd
+ {image_id}
+
+ """.format(size=1024 * int(specs['disk_size']),
+ image_id=image_id)
+
+ except:
+ disk = template.template.disks[0]
+ image = disk.image
+ image_uname = disk.image_uname
+
+ vm_specs = vm_specs_formatter.format(
+ vcpu=int(specs['cpu']),
+ cpu=0.1 * int(specs['cpu']),
+ memory=(512 if specs['memory'] == 0.5 else
+ 1024 * int(specs['memory'])),
+ )
+ vm_specs += """
+ fs
+ {size}
+ vd
+ {image}
+ {image_uname}
+
+ """.format(size=1024 * int(specs['disk_size']),
+ image=image,
+ image_uname=image_uname)
+
+ vm_specs += ""
+ if ssh_key:
+ vm_specs += "{ssh} ".format(
+ ssh=ssh_key)
+ vm_specs += """YES
+
+
+ """
+ try:
+ vm_id = self.client.call(
+ oca.VmTemplate.METHODS['instantiate'], template.id, '', True,
+ vm_specs, False
+ )
+ except OpenNebulaException as err:
+ logger.error("OpenNebulaException: {0}".format(err))
+ return None
+
+ self.oneadmin_client.call(
+ oca.VirtualMachine.METHODS['action'],
+ 'release',
+ vm_id
+ )
+
+ if vm_name is not None:
+ self.oneadmin_client.call(
+ 'vm.rename',
+ vm_id,
+ vm_name
+ )
+ return vm_id
+
+ def delete_vm(self, vm_id):
+ TERMINATE_ACTION = 'terminate-hard'
+ vm_terminated = False
+ try:
+ self.oneadmin_client.call(
+ oca.VirtualMachine.METHODS['action'],
+ TERMINATE_ACTION,
+ int(vm_id),
+ )
+ vm_terminated = True
+ except socket.timeout as socket_err:
+ logger.error("Socket timeout error: {0}".format(socket_err))
+ except OpenNebulaException as opennebula_err:
+ logger.error(
+ "OpenNebulaException error: {0}".format(opennebula_err))
+ except OSError as os_err:
+ logger.error("OSError : {0}".format(os_err))
+ except ValueError as value_err:
+ logger.error("ValueError : {0}".format(value_err))
+
+ return vm_terminated
+
+ def save_key_in_opennebula_user(self, ssh_key, update_type=1):
+ """
+ Save the given ssh key in OpenNebula user
+
+ # Update type: 0: Replace the whole template.
+ 1: Merge new template with the existing one.
+ :param ssh_key: The ssh key to be saved
+ :param update_type: The update type as explained above
+
+ :return:
+ """
+ return_value = self.oneadmin_client.call(
+ 'user.update',
+ self.opennebula_user if type(self.opennebula_user) == int else self.opennebula_user.id,
+ '%s ' % ssh_key,
+ update_type
+ )
+ if type(return_value) == int:
+ logger.debug(
+ "Saved the key in opennebula successfully : %s" % return_value)
+ else:
+ logger.error(
+ "Could not save the key in opennebula. %s" % return_value)
+ return
+
+ def _get_template_pool(self):
+ try:
+ template_pool = oca.VmTemplatePool(self.oneadmin_client)
+ template_pool.info()
+ return template_pool
+ except ConnectionRefusedError:
+ logger.error(
+ """Could not connect to host: {host} via protocol
+ {protocol}""".format(
+ host=settings.OPENNEBULA_DOMAIN,
+ protocol=settings.OPENNEBULA_PROTOCOL)
+ )
+ raise ConnectionRefusedError
+ except:
+ raise ConnectionRefusedError
+
+ def get_templates(self, prefix='public-'):
+ try:
+ public_templates = [
+ template
+ for template in self._get_template_pool()
+ if template.name.startswith(prefix)
+ ]
+ return public_templates
+ except Exception as e:
+ logger.debug(e)
+ return []
+
+ def try_get_templates(self):
+ try:
+ return self.get_templates()
+ except:
+ return []
+
+ def get_template(self, template_id):
+ template_id = int(template_id)
+ try:
+ template_pool = self._get_template_pool()
+ if template_id in settings.UPDATED_TEMPLATES_DICT.keys():
+ template_id = settings.UPDATED_TEMPLATES_DICT[template_id]
+ return template_pool.get_by_id(template_id)
+ except Exception as ex:
+ logger.debug("Template Id we are looking for : %s" % template_id)
+ logger.error(str(ex))
+ raise ConnectionRefusedError
+
+ def create_template(self, name, cores, memory, disk_size, core_price,
+ memory_price,
+ disk_size_price, ssh=''):
+ """Create and add a new template to opennebula.
+ :param name: A string representation describing the template.
+ Used as label in view.
+ :param cores: Amount of virtual cpu cores for the VM.
+ :param memory: Amount of RAM for the VM (GB)
+ :param disk_size: Amount of disk space for VM (GB)
+ :param core_price: Price of virtual cpu for the VM per core.
+ :param memory_price: Price of RAM for the VM per GB
+ :param disk_size_price: Price of disk space for VM per GB
+ :param ssh: User public ssh key
+ """
+ template_string_formatter = """
+ {name}
+ {memory}
+ {vcpu}
+ {cpu}
+
+ fs
+ {size}
+ vd
+
+ {cpu_cost}
+ {memory_cost}
+ {disk_cost}
+ {ssh}
+
+ """
+ template_id = oca.VmTemplate.allocate(
+ self.oneadmin_client,
+ template_string_formatter.format(
+ name=name,
+ vcpu=cores,
+ cpu=0.1 * cores,
+ size=1024 * disk_size,
+ memory=1024 * memory,
+ # * 10 because we set cpu to *0.1
+ cpu_cost=10 * core_price,
+ memory_cost=memory_price,
+ disk_cost=disk_size_price,
+ ssh=ssh
+ )
+ )
+
+ return template_id
+
+ def delete_template(self, template_id):
+ self.oneadmin_client.call(
+ oca.VmTemplate.METHODS['delete'], template_id, False
+ )
+
+ def change_user_password(self, passwd_hash):
+ if type(self.opennebula_user) == int:
+ logger.debug("opennebula_user is int and has value = %s" %
+ self.opennebula_user)
+ else:
+ logger.debug("opennebula_user is object and corresponding id is %s"
+ % self.opennebula_user.id)
+ self.oneadmin_client.call(
+ oca.User.METHODS['passwd'],
+ self.opennebula_user if type(self.opennebula_user) == int else self.opennebula_user.id,
+ passwd_hash
+ )
+
+ def add_public_key(self, user, public_key='', merge=False):
+ """
+
+ Args:
+ user (CustomUser): Dynamicweb user
+ public_key (string): Public key to add to the user
+ merge (bool): Optional if True the new public key replaces the old
+
+ Raises:
+ KeyExistsError: If replace is False and the user already has a
+ public key
+ WrongNameError: If no openebula user with this credentials exists
+ ConnectionError: If the connection to the opennebula server can't be
+ established
+
+ Returns:
+ True if public_key was added
+
+ """
+ # TODO: Check if we can remove this first try because we basically just
+ # raise the possible Errors
+ try:
+ open_user = self._get_user(user)
+ try:
+ old_key = open_user.template.ssh_public_key
+ if not merge:
+ raise KeyExistsError()
+ public_key += '\n{key}'.format(key=old_key)
+
+ except AttributeError:
+ pass
+ self.oneadmin_client.call('user.update', open_user.id,
+ '{key} '
+ .format(key=public_key))
+ return True
+ except WrongNameError:
+ raise
+
+ except ConnectionError:
+ raise
+
+ def remove_public_key(self, user, public_key=''):
+ """
+
+ Args:
+ user (CustomUser): Dynamicweb user
+ public_key (string): Public key to be removed to the user
+
+ Raises:
+ KeyDoesNotExistsError: If replace is False and the user already has a
+ public key
+ WrongNameError: If no openebula user with this credentials exists
+ ConnectionError: If the connection to the opennebula server can't be
+ established
+
+ Returns:
+ True if public_key was removed
+
+ """
+
+ try:
+ open_user = self._get_user(user)
+ try:
+ old_key = open_user.template.ssh_public_key
+ if public_key not in old_key:
+ return False
+ # raise KeyDoesNotExistsError()
+ if '\n{}'.format(public_key) in old_key:
+ public_key = old_key.replace('\n{}'.format(public_key), '')
+ else:
+ public_key = old_key.replace(public_key, '')
+
+ except AttributeError:
+ return False
+ # raise KeyDoesNotExistsError()
+
+ self.oneadmin_client.call('user.update', open_user.id,
+ '{key} '
+ .format(key=public_key))
+ return True
+ except WrongNameError:
+ raise
+
+ except ConnectionError:
+ raise
+
+ def manage_public_key(self, keys, hosts=None, countdown=0):
+ """
+ A function that manages the supplied keys in the
+ authorized_keys file of the given list of hosts. If hosts
+ parameter is not supplied, all hosts of this customer
+ will be configured with the supplied keys
+
+ :param keys: A list of ssh keys that are to be added/removed
+ A key should be a dict of the form
+ {
+ 'value': 'sha-.....', # public key as string
+ 'state': True # whether key is to be added or
+ } # removed
+ :param hosts: A list of hosts IPv6 addresses
+ :param countdown: Parameter to be passed to celery apply_async
+ Allows to delay a task by `countdown` number of seconds
+ :return:
+ """
+ if hosts is None:
+ hosts = self.get_all_hosts()
+
+ if len(hosts) > 0 and len(keys) > 0:
+ save_ssh_key.apply_async((hosts, keys), countdown=countdown,
+ link_error=save_ssh_key_error_handler.s())
+ else:
+ logger.debug(
+ "Keys and/or hosts are empty, so not managing any keys"
+ )
+
+ def get_all_hosts(self):
+ """
+ A utility function to obtain all hosts of this owner
+ :return: A list of IPv6 addresses of all the hosts of this customer or
+ an empty list if none exist
+ """
+ owner = CustomUser.objects.filter(
+ email=self.email).first()
+ all_orders = HostingOrder.objects.filter(customer__user=owner)
+ hosts = []
+ if len(all_orders) > 0:
+ logger.debug("The user {} has 1 or more VMs. We need to configure "
+ "the ssh keys.".format(self.email))
+ for order in all_orders:
+ try:
+ ip = self.get_ipv6(order.vm_id)
+ hosts.append(ip)
+ except WrongIdError:
+ logger.debug(
+ "VM with ID {} does not exist".format(order.vm_id))
+ else:
+ logger.debug("The user {} has no VMs. We don't need to configure "
+ "the ssh keys.".format(self.email))
+ return hosts
diff --git a/opennebula_api/serializers.py b/opennebula_api/serializers.py
new file mode 100755
index 0000000..5681720
--- /dev/null
+++ b/opennebula_api/serializers.py
@@ -0,0 +1,204 @@
+import ipaddress
+
+from builtins import hasattr
+from rest_framework import serializers
+
+from oca import OpenNebulaException
+
+from .opennebula_manager import OpenNebulaManager
+
+
+class VirtualMachineTemplateSerializer(serializers.Serializer):
+ """Serializer to map the virtual machine template instance into JSON format."""
+ id = serializers.IntegerField(read_only=True)
+ name = serializers.SerializerMethodField()
+ cores = serializers.SerializerMethodField()
+ disk_size = serializers.SerializerMethodField()
+ memory = serializers.SerializerMethodField()
+
+ def get_cores(self, obj):
+ if hasattr(obj.template, 'vcpu'):
+ return obj.template.vcpu
+
+ return ''
+
+ def get_disk_size(self, obj):
+ template = obj.template
+ disk_size = 0
+ try:
+ for disk in template.disks:
+ disk_size += int(disk.size)
+ return disk_size / 1024
+ except:
+ return 0
+
+ def get_memory(self, obj):
+ return int(obj.template.memory) / 1024
+
+ def get_name(self, obj):
+ if obj.name.startswith('public-'):
+ return obj.name.lstrip('public-')
+ else:
+ return obj.name
+
+
+class VirtualMachineSerializer(serializers.Serializer):
+ """Serializer to map the virtual machine instance into JSON format."""
+
+ name = serializers.SerializerMethodField()
+ cores = serializers.IntegerField(source='template.vcpu')
+ disk = serializers.IntegerField(write_only=True)
+ set_memory = serializers.IntegerField(write_only=True, label='Memory')
+ memory = serializers.SerializerMethodField()
+
+ disk_size = serializers.SerializerMethodField()
+ hdd_size = serializers.SerializerMethodField()
+ ssd_size = serializers.SerializerMethodField()
+ ipv4 = serializers.SerializerMethodField()
+ ipv6 = serializers.SerializerMethodField()
+ vm_id = serializers.IntegerField(read_only=True, source='id')
+ state = serializers.CharField(read_only=True, source='str_state')
+ price = serializers.SerializerMethodField()
+ ssh_key = serializers.CharField(write_only=True)
+ configuration = serializers.SerializerMethodField()
+
+ template_id = serializers.ChoiceField(
+ choices=[(key.id, key.name) for key in
+ OpenNebulaManager().try_get_templates()
+ ],
+ source='template.template_id',
+ write_only=True,
+ default=[]
+ )
+
+ def create(self, validated_data):
+ owner = validated_data['owner']
+ ssh_key = validated_data['ssh_key']
+ cores = validated_data['template']['vcpu']
+ memory = validated_data['set_memory']
+ disk = validated_data['disk']
+
+ template_id = validated_data['template']['template_id']
+ specs = {
+ 'cpu': cores,
+ 'disk_size': disk,
+ 'memory': memory,
+ }
+
+ try:
+ manager = OpenNebulaManager(email=owner.username,
+ password=owner.password,
+ )
+ opennebula_id = manager.create_vm(template_id=template_id,
+ ssh_key=ssh_key,
+ specs=specs)
+ except OpenNebulaException as err:
+ raise serializers.ValidationError(
+ "OpenNebulaException occured. {0}".format(err)
+ )
+
+ return manager.get_vm(opennebula_id)
+
+ def get_memory(self, obj):
+ return int(obj.template.memory) / 1024
+
+ def get_disk_size(self, obj):
+ template = obj.template
+ disk_size = 0
+ for disk in template.disks:
+ disk_size += int(disk.size)
+ return disk_size / 1024
+
+ def get_ssd_size(self, obj):
+ template = obj.template
+ disk_size = 0
+ for disk in template.disks:
+ if disk.datastore == 'cephds':
+ disk_size += int(disk.size)
+ return disk_size / 1024
+
+ def get_hdd_size(self, obj):
+ template = obj.template
+ disk_size = 0
+ for disk in template.disks:
+ if disk.datastore == 'ceph_hdd_ds':
+ disk_size += int(disk.size)
+ return disk_size / 1024
+
+ def get_price(self, obj):
+ template = obj.template
+ price = float(template.vcpu) * 5.0
+ price += (int(template.memory) / 1024 * 2.0)
+ for disk in template.disks:
+ price += int(disk.size) / 1024 * 0.6
+ return price
+
+ def get_configuration(self, obj):
+ template_id = obj.template.template_id
+ template = OpenNebulaManager().get_template(template_id)
+ if template.name.startswith('public-'):
+ return template.name.lstrip('public-')
+ else:
+ return template.name
+
+ def get_ipv4(self, obj):
+ """
+ Get the IPv4s from the given VM
+
+ :param obj: The VM in contention
+ :return: Returns csv string of all IPv4s added to this VM otherwise returns "-" if no IPv4 is available
+ """
+ ipv4 = []
+ for nic in obj.template.nics:
+ if hasattr(nic, 'ip'):
+ ipv4.append(nic.ip)
+ if len(ipv4) > 0:
+ return ', '.join(ipv4)
+ else:
+ return '-'
+
+ def get_ipv6(self, obj):
+ ipv6 = []
+ for nic in obj.template.nics:
+ if hasattr(nic, 'ip6_global'):
+ ipv6.append(nic.ip6_global)
+ if len(ipv6) > 0:
+ return ', '.join(ipv6)
+ else:
+ return '-'
+
+ def get_name(self, obj):
+ if obj.name.startswith('public-'):
+ return obj.name.lstrip('public-')
+ else:
+ return obj.name
+
+
+class VMTemplateSerializer(serializers.Serializer):
+ """Serializer to map the VMTemplate instance into JSON format."""
+ id = serializers.IntegerField(
+ read_only=True, source='opennebula_vm_template_id'
+ )
+ name = serializers.CharField(read_only=True)
+
+
+def hexstr2int(string):
+ return int(string.replace(':', ''), 16)
+
+
+FIRST_MAC = hexstr2int('02:00:b3:39:79:4d')
+FIRST_V4 = ipaddress.ip_address('185.203.112.2')
+COUNT = 1000
+
+
+def v4_from_mac(mac):
+ """Calculates the IPv4 address from a MAC address.
+
+ mac: string (the colon-separated representation)
+ returns: ipaddress.ip_address object with the v4 address
+ """
+ return FIRST_V4 + (hexstr2int(mac) - FIRST_MAC)
+
+
+def is_in_v4_range(mac):
+ return FIRST_MAC <= hexstr2int(mac) < FIRST_MAC + 1000
diff --git a/opennebula_api/tests.py b/opennebula_api/tests.py
new file mode 100755
index 0000000..911b498
--- /dev/null
+++ b/opennebula_api/tests.py
@@ -0,0 +1,151 @@
+import random
+import string
+
+from django.conf import settings
+from django.test import TestCase
+from unittest import skipIf
+
+from .opennebula_manager import OpenNebulaManager
+from .serializers import VirtualMachineSerializer
+from utils.models import CustomUser
+
+
+@skipIf(
+ settings.OPENNEBULA_DOMAIN is None or
+ settings.OPENNEBULA_DOMAIN == "test_domain",
+ """OpenNebula details unavailable, so skipping
+ OpenNebulaManagerTestCases"""
+)
+class OpenNebulaManagerTestCases(TestCase):
+ """This class defines the test suite for the opennebula manager model."""
+
+ def setUp(self):
+ """Define the test client and other test variables."""
+ self.email = '{}@ungleich.ch'.format(''.join(random.choices(string.ascii_uppercase, k=10)))
+ self.password = ''.join(random.choices(string.ascii_uppercase + string.digits, k=20))
+
+ self.user = CustomUser.objects.create(name='test', email=self.email,
+ password=self.password)
+
+ self.vm_specs = {}
+ self.vm_specs['cpu'] = 1
+ self.vm_specs['memory'] = 2
+ self.vm_specs['disk_size'] = 10
+
+ self.manager = OpenNebulaManager()
+
+ def test_connect_to_server(self):
+ """Test the opennebula manager can connect to a server."""
+ try:
+ ver = self.manager.oneadmin_client.version()
+ except:
+ ver = None
+ self.assertTrue(ver is not None)
+
+ def test_get_user(self):
+ """Test the opennebula manager can get a existing user."""
+ self.manager.create_user(self.user)
+ user = self.manager._get_user(self.user)
+ name = user.name
+ self.assertNotEqual(name, None)
+
+ def test_create_and_delete_user(self):
+ """Test the opennebula manager can create and delete a new user."""
+ old_count = len(self.manager._get_user_pool())
+ self.manager = OpenNebulaManager(email=self.email,
+ password=self.password)
+ user_pool = self.manager._get_user_pool()
+ new_count = len(user_pool)
+ # Remove the user afterwards
+ user = user_pool.get_by_name(self.email)
+ user.delete()
+
+ self.assertNotEqual(old_count, new_count)
+
+ def test_user_can_login(self):
+ """ Test the manager can login to a new created user"""
+ self.manager.create_user(self.user)
+ user = self.manager._get_user(self.user)
+ client = self.manager._get_client(self.user)
+ version = client.version()
+
+ # Cleanup
+ user.delete()
+ self.assertNotEqual(version, None)
+
+ def test_add_public_key_to_user(self):
+ """ Test the manager can add a new public key to an user """
+ self.manager.create_user(self.user)
+ user = self.manager._get_user(self.user)
+ public_key = 'test'
+ self.manager.add_public_key(self.user, public_key)
+ # Fetch new user information from opennebula
+ user.info()
+ user_public_key = user.template.ssh_public_key
+ # Cleanup
+ user.delete()
+
+ self.assertEqual(user_public_key, public_key)
+
+ def test_append_public_key_to_user(self):
+ """ Test the manager can append a new public key to an user """
+ self.manager.create_user(self.user)
+ user = self.manager._get_user(self.user)
+ public_key = 'test'
+ self.manager.add_public_key(self.user, public_key)
+ # Fetch new user information from opennebula
+ user.info()
+ old_public_key = user.template.ssh_public_key
+ self.manager.add_public_key(self.user, public_key, merge=True)
+ user.info()
+ new_public_key = user.template.ssh_public_key
+ # Cleanup
+ user.delete()
+
+ self.assertEqual(new_public_key, '{}\n{}'.format(old_public_key,
+ public_key))
+
+ def test_remove_public_key_to_user(self):
+ """ Test the manager can remove a public key from an user """
+ self.manager.create_user(self.user)
+ user = self.manager._get_user(self.user)
+ public_key = 'test'
+ self.manager.add_public_key(self.user, public_key)
+ self.manager.add_public_key(self.user, public_key, merge=True)
+ user.info()
+ old_public_key = user.template.ssh_public_key
+ self.manager.remove_public_key(self.user, public_key)
+ user.info()
+ new_public_key = user.template.ssh_public_key
+ # Cleanup
+ user.delete()
+
+ self.assertEqual(new_public_key,
+ old_public_key.replace('{}\n'.format(public_key), '', 1))
+
+ def test_requires_ssh_key_for_new_vm(self):
+ """Test the opennebula manager requires the user to have a ssh key when
+ creating a new vm"""
+
+
+@skipIf(
+ settings.OPENNEBULA_DOMAIN is None or
+ settings.OPENNEBULA_DOMAIN == "test_domain",
+ """OpenNebula details unavailable, so skipping
+ VirtualMachineSerializerTestCase"""
+)
+class VirtualMachineSerializerTestCase(TestCase):
+ def setUp(self):
+ """Define the test client and other test variables."""
+ self.manager = OpenNebulaManager(email=None, password=None)
+
+ def test_serializer_strips_of_public(self):
+ """ Test the serialized virtual machine object contains no
+ 'public-'."""
+
+ for vm in self.manager.get_vms():
+ serialized = VirtualMachineSerializer(vm)
+ self.assertEqual(
+ serialized.data.get('name'), vm.name.lstrip('public-')
+ )
+ break
diff --git a/opennebula_api/urls.py b/opennebula_api/urls.py
new file mode 100755
index 0000000..aa9c77e
--- /dev/null
+++ b/opennebula_api/urls.py
@@ -0,0 +1,11 @@
+from django.urls import re_path, include
+from rest_framework.urlpatterns import format_suffix_patterns
+from .views import VmCreateView, VmDetailsView
+
+urlpatterns = {
+ re_path(r'^auth/', include('rest_framework.urls', namespace='rest_framework')),
+ re_path(r'^vms/$', VmCreateView.as_view(), name="vm_create"),
+ re_path(r'^vms/(?P[0-9]+)/$', VmDetailsView.as_view(), name="vm_details"),
+}
+
+urlpatterns = format_suffix_patterns(urlpatterns)
diff --git a/opennebula_api/views.py b/opennebula_api/views.py
new file mode 100755
index 0000000..5b837c7
--- /dev/null
+++ b/opennebula_api/views.py
@@ -0,0 +1,76 @@
+from rest_framework import generics
+from rest_framework import permissions
+
+from .serializers import VirtualMachineSerializer
+from .opennebula_manager import OpenNebulaManager
+from rest_framework.exceptions import APIException
+
+
+class ServiceUnavailable(APIException):
+ status_code = 503
+ default_detail = 'Service temporarily unavailable, try again later.'
+ default_code = 'service_unavailable'
+
+
+class VmCreateView(generics.ListCreateAPIView):
+ """This class handles the GET and POST requests."""
+ serializer_class = VirtualMachineSerializer
+ permission_classes = (permissions.IsAuthenticated, )
+
+ def get_queryset(self):
+ owner = self.request.user
+ manager = OpenNebulaManager(email=owner.username,
+ password=owner.password)
+ # We may have ConnectionRefusedError if we don't have a
+ # connection to OpenNebula. For now, we raise ServiceUnavailable
+ try:
+ vms = manager.get_vms()
+ except ConnectionRefusedError:
+ raise ServiceUnavailable
+ return vms
+
+ def perform_create(self, serializer):
+ """Save the post data when creating a new template."""
+ serializer.save(owner=self.request.user)
+
+
+class VmDetailsView(generics.RetrieveUpdateDestroyAPIView):
+ """This class handles the http GET, PUT and DELETE requests."""
+ permission_classes = (permissions.IsAuthenticated, )
+
+ serializer_class = VirtualMachineSerializer
+
+ def get_queryset(self):
+ owner = self.request.user
+ manager = OpenNebulaManager(email=owner.username,
+ password=owner.password)
+ # We may have ConnectionRefusedError if we don't have a
+ # connection to OpenNebula. For now, we raise ServiceUnavailable
+ try:
+ vms = manager.get_vms()
+ except ConnectionRefusedError:
+ raise ServiceUnavailable
+ return vms
+
+ def get_object(self):
+ owner = self.request.user
+ manager = OpenNebulaManager(email=owner.username,
+ password=owner.password)
+ # We may have ConnectionRefusedError if we don't have a
+ # connection to OpenNebula. For now, we raise ServiceUnavailable
+ try:
+ vm = manager.get_vm(self.kwargs.get('pk'))
+ except ConnectionRefusedError:
+ raise ServiceUnavailable
+ return vm
+
+ def perform_destroy(self, instance):
+ owner = self.request.user
+ manager = OpenNebulaManager(email=owner.username,
+ password=owner.password)
+ # We may have ConnectionRefusedError if we don't have a
+ # connection to OpenNebula. For now, we raise ServiceUnavailable
+ try:
+ manager.delete_vm(instance.id)
+ except ConnectionRefusedError:
+ raise ServiceUnavailable
diff --git a/postgres/Dockerfile b/postgres/Dockerfile
new file mode 100644
index 0000000..78bd358
--- /dev/null
+++ b/postgres/Dockerfile
@@ -0,0 +1,9 @@
+# Use the official PostgreSQL image from the Docker Hub
+FROM postgres:latest
+
+# Copy custom configuration file to PostgreSQL configuration directory
+COPY ./postgresql.conf /etc/postgresql/postgresql.conf
+
+# Set the Unix socket directory
+RUN echo "unix_socket_directories = '/var/run/postgresql'" >> /etc/postgresql/postgresql.conf
+
diff --git a/postgres/postgresql.conf b/postgres/postgresql.conf
new file mode 100644
index 0000000..e69de29
diff --git a/requirements.txt b/requirements.txt
index aa3031b..bbef7d4 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,21 +1,64 @@
+amqp==5.2.0
asgiref==3.7.2
beautifulsoup4==4.12.2
+billiard==4.2.0
+cdist==7.0.0
+celery==5.3.6
certifi==2023.11.17
charset-normalizer==3.3.2
+click==8.1.7
+click-didyoumean==0.3.0
+click-plugins==1.1.1
+click-repl==0.3.0
+cssselect2==0.7.0
Django==4.2.7
+django-appconf==1.0.6
django-bootstrap3==23.4
+django-classy-tags==4.1.0
+django-cms==3.11.4
+django-compressor==4.4
+django-filer==3.1.1
+django-formtools==2.4.1
django-guardian==2.4.0
+django-polymorphic==3.1.0
+django-sekizai==4.1.0
+django-stored-messages==1.4.0
+django-treebeard==4.7
+djangocms-admin-style==3.2.6
+djangocms-text-ckeditor==5.1.5
+djangorestframework==3.14.0
+easy-thumbnails==2.8.5
+html5lib==1.1
idna==3.4
Jinja2==3.1.2
+kombu==5.3.4
ldap3==2.9.1
+lxml==4.9.3
MarkupSafe==2.1.3
+oca @ git+https://code.ungleich.ch/ungleich-public/python-oca.git@b202172a30e944705d6e3591707a2928bd90b08e
+packaging==23.2
+Pillow==10.1.0
+prompt-toolkit==3.0.41
+psycopg2-binary==2.9.9
pyasn1==0.5.1
pycryptodome==3.19.0
+python-dateutil==2.8.2
python-dotenv==1.0.0
+pytz==2023.3.post1
PyYAML==6.0.1
+rcssmin==1.1.1
+reportlab==4.0.7
requests==2.31.0
+rjsmin==1.2.1
+six==1.16.0
soupsieve==2.5
sqlparse==0.4.4
stripe==7.5.0
+svglib==1.5.1
+tinycss2==1.2.1
typing_extensions==4.8.0
+tzdata==2023.3
urllib3==2.1.0
+vine==5.1.0
+wcwidth==0.2.12
+webencodings==0.5.1
diff --git a/ungleich_page/__init__.py b/ungleich_page/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/ungleich_page/admin.py b/ungleich_page/admin.py
new file mode 100755
index 0000000..4185d36
--- /dev/null
+++ b/ungleich_page/admin.py
@@ -0,0 +1,3 @@
+# from django.contrib import admin
+
+# Register your models here.
diff --git a/ungleich_page/apps.py b/ungleich_page/apps.py
new file mode 100755
index 0000000..4385d1c
--- /dev/null
+++ b/ungleich_page/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class UngleichPageConfig(AppConfig):
+ name = 'ungleich_page'
diff --git a/ungleich_page/cms_menus.py b/ungleich_page/cms_menus.py
new file mode 100755
index 0000000..ec28e01
--- /dev/null
+++ b/ungleich_page/cms_menus.py
@@ -0,0 +1,63 @@
+from cms.models import Placeholder
+from menus.base import NavigationNode
+from menus.menu_pool import menu_pool
+from django.utils.translation import gettext_lazy as _
+from cms.menu_bases import CMSAttachMenu
+# from cms.templatetags.cms_tags import _get_placeholder
+from cms.utils.plugins import get_plugins
+
+
+class GlasfaserMenu(CMSAttachMenu):
+
+ name = _("Glasfaser menu")
+
+ def get_nodes(self, request):
+ nodes = []
+ glasfaser_cms = 'ungleich_page/glasfaser_cms_page.html'
+ if (request and request.current_page and
+ request.current_page.get_template() == glasfaser_cms):
+ template_context = {
+ "request": request,
+ }
+ placeholder_name_list = [
+ 'Top Section', 'Middle Section', 'Glasfaser Services',
+ 'Glasfaser About', 'Contact Section'
+ ]
+ plugins_list = [
+ 'SectionWithImage', 'UngelichContactUsSection',
+ 'UngelichTextSection', 'Service', 'About'
+ ]
+ for placeholder_name in placeholder_name_list:
+ # Get the placeholder
+ placeholder = Placeholder.objects.get(slot=placeholder_name)
+
+ plugins = get_plugins(
+ request, placeholder, request.current_page.get_template()
+ )
+ for plugin in plugins:
+ if type(plugin).__name__ in plugins_list:
+ section_hash = request.build_absolute_uri()
+ if hasattr(plugin, 'menu_text'):
+ menu_text = plugin.menu_text
+ if menu_text.strip() == '':
+ continue
+ menu_words = menu_text.split()
+ if len(menu_words) > 0:
+ section_hash = '{}#{}'.format(
+ section_hash,
+ menu_words[0]
+ )
+ else:
+ continue
+ newnode = NavigationNode(
+ menu_text,
+ url=section_hash,
+ id="{}-{}".format(
+ request.current_page.id, plugin.id
+ )
+ )
+ nodes.append(newnode)
+ return nodes
+
+
+menu_pool.register_menu(GlasfaserMenu)
diff --git a/ungleich_page/cms_plugins.py b/ungleich_page/cms_plugins.py
new file mode 100755
index 0000000..660a363
--- /dev/null
+++ b/ungleich_page/cms_plugins.py
@@ -0,0 +1,313 @@
+from cms.plugin_base import CMSPluginBase
+from cms.plugin_pool import plugin_pool
+
+from .models import (
+ UngelichContactUsSection, UngelichTextSection, Service, ServiceItem,
+ About, AboutItem, SectionWithImage, UngleichServiceItem,
+ UngleichProductItem, UngleichProduct, UngleichCustomer,
+ UngleichCustomerItem, UngleichHTMLOnly,
+ UngleichHeaderWithBackgroundImageSlider,
+ UngleichHeaderWithBackgroundVideoSliderItem,
+ UngleichFooter
+)
+
+
+def get_section_id(plugin_instance, default):
+ """
+ A helper function to get the section id from a given menu text
+ :param plugin_instance:
+ :param default: The default section id to return in case a section id
+ is not found
+ :return: The section id for the plugin_instance
+ """
+ section_id = default
+ if hasattr(plugin_instance, 'menu_text'):
+ menu_words = plugin_instance.menu_text.split()
+ if len(menu_words) > 0:
+ section_id = menu_words[0]
+ return section_id
+
+
+@plugin_pool.register_plugin
+class SectionWithImagePlugin(CMSPluginBase):
+ model = SectionWithImage
+ render_template = "ungleich_page/glasfaser/section_with_image.html"
+ cache = False
+
+ def render(self, context, instance, placeholder):
+ context.update({
+ 'image': instance.image,
+ 'object': instance,
+ 'placeholder': placeholder
+ })
+ return context
+
+
+@plugin_pool.register_plugin
+class SectionContact(CMSPluginBase):
+ model = UngelichContactUsSection
+ render_template = "ungleich_page/glasfaser/section_contact.html"
+ cache = False
+
+ def render(self, context, instance, placeholder):
+ context = super(SectionContact, self).render(
+ context, instance, placeholder
+ )
+ context['instance'] = instance
+ context['section_id'] = get_section_id(instance, 'contact')
+ return context
+
+
+@plugin_pool.register_plugin
+class SectionTextParagraphDCL(CMSPluginBase):
+ model = UngelichTextSection
+ render_template = "ungleich_page/glasfaser/section_text_dcl.html"
+ cache = False
+
+ def render(self, context, instance, placeholder):
+ context = super(SectionTextParagraphDCL, self).render(
+ context, instance, placeholder
+ )
+ context['instance'] = instance
+ context['section_id'] = get_section_id(instance, 'your')
+ return context
+
+
+@plugin_pool.register_plugin
+class SectionTextParagraphGlasfaser(CMSPluginBase):
+ model = UngelichTextSection
+ render_template = "ungleich_page/glasfaser/section_text_glasfaser.html"
+ cache = False
+
+ def render(self, context, instance, placeholder):
+ context = super(SectionTextParagraphGlasfaser, self).render(
+ context, instance, placeholder
+ )
+ context['instance'] = instance
+ context['section_id'] = get_section_id(instance, 'our')
+ return context
+
+
+@plugin_pool.register_plugin
+class GlasfaserServicesPlugin(CMSPluginBase):
+ name = "Glasfaser Services Plugin"
+ model = Service
+ render_template = "ungleich_page/glasfaser/section_services.html"
+ cache = False
+ allow_children = True
+ child_classes = ['GlasfaserServicesItemPlugin']
+
+ def render(self, context, instance, placeholder):
+ context['service_instance'] = instance
+ context['section_id'] = get_section_id(instance, 'services')
+ return context
+
+
+@plugin_pool.register_plugin
+class GlasfaserServicesItemPlugin(CMSPluginBase):
+ name = "Glasfaser Service Item Plugin"
+ model = ServiceItem
+ render_template = "ungleich_page/glasfaser/_services_item.html"
+ cache = False
+ require_parent = True
+ parent_classes = ['GlasfaserServicesPlugin']
+
+ def render(self, context, instance, placeholder):
+ context = super(GlasfaserServicesItemPlugin, self).render(
+ context, instance, placeholder
+ )
+ context['instance'] = instance
+ return context
+
+
+@plugin_pool.register_plugin
+class GlasfaserAboutPlugin(CMSPluginBase):
+ name = "Glasfaser About Plugin"
+ model = About
+ render_template = "ungleich_page/glasfaser/section_about.html"
+ cache = False
+ allow_children = True
+ child_classes = ['GlasfaserAboutItemPlugin']
+
+ def render(self, context, instance, placeholder):
+ context['about_instance'] = instance
+ context['section_id'] = get_section_id(instance, 'about')
+ return context
+
+
+@plugin_pool.register_plugin
+class GlasfaserAboutItemPlugin(CMSPluginBase):
+ name = "Glasfaser About Item Plugin"
+ model = AboutItem
+ render_template = "ungleich_page/glasfaser/_about_item.html"
+ cache = False
+ require_parent = True
+ parent_classes = ['GlasfaserAboutPlugin']
+
+ def render(self, context, instance, placeholder):
+ context = super(GlasfaserAboutItemPlugin, self).render(
+ context, instance, placeholder
+ )
+ context['instance'] = instance
+ return context
+
+
+@plugin_pool.register_plugin
+class UngleichServicesPlugin(CMSPluginBase):
+ name = "ungleich Services Plugin"
+ model = Service
+ render_template = "ungleich_page/ungleich/section_services.html"
+ cache = False
+ allow_children = True
+ child_classes = ['UngleichServicesItemPlugin']
+
+ def render(self, context, instance, placeholder):
+ context['service_instance'] = instance
+ context['section_id'] = get_section_id(instance, 'services')
+ return context
+
+
+@plugin_pool.register_plugin
+class UngleichServicesItemPlugin(CMSPluginBase):
+ name = "ungleich Service Item Plugin"
+ model = UngleichServiceItem
+ render_template = "ungleich_page/ungleich/_services_item.html"
+ cache = False
+ require_parent = True
+ parent_classes = ['UngleichServicesPlugin']
+
+ def render(self, context, instance, placeholder):
+ context = super(UngleichServicesItemPlugin, self).render(
+ context, instance, placeholder
+ )
+ context['instance'] = instance
+ return context
+
+
+@plugin_pool.register_plugin
+class UngleichHeaderBackgroundImageAndTextSliderPlugin(CMSPluginBase):
+ name = "ungleich Header with Background and Image Slider Plugin"
+ model = UngleichHeaderWithBackgroundImageSlider
+ render_template = (
+ 'ungleich_page/ungleich/header_with_background_image_slider.html'
+ )
+ cache = False
+ allow_children = True
+ child_classes = [
+ 'UngleichHeaderBackgroundVideoItemPlugin',
+ ]
+
+ def render(self, context, instance, placeholder):
+ context['instance'] = instance
+ return context
+
+
+@plugin_pool.register_plugin
+class UngleichHeaderBackgroundVideoItemPlugin(CMSPluginBase):
+ name = "ungleich Header Background Video Item Plugin"
+ model = UngleichHeaderWithBackgroundVideoSliderItem
+ render_template = "ungleich_page/ungleich/_header_with_background_video_slider_item.html"
+ cache = False
+ require_parent = True
+ parent_classes = ['UngleichHeaderBackgroundImageAndTextSliderPlugin']
+
+ def render(self, context, instance, placeholder):
+ context = super(UngleichHeaderBackgroundVideoItemPlugin, self).render(
+ context, instance, placeholder
+ )
+ context['instance'] = instance
+ return context
+
+
+@plugin_pool.register_plugin
+class UngleichProductsPlugin(CMSPluginBase):
+ name = "ungleich Products Plugin"
+ model = UngleichProduct
+ render_template = "ungleich_page/ungleich/section_products.html"
+ cache = False
+ allow_children = True
+ child_classes = ['UngleichProductsItemPlugin']
+
+ def render(self, context, instance, placeholder):
+ context['product_instance'] = instance
+ context['section_id'] = get_section_id(instance, 'products')
+ return context
+
+
+@plugin_pool.register_plugin
+class UngleichProductsItemPlugin(CMSPluginBase):
+ name = "ungleich Product Item Plugin"
+ model = UngleichProductItem
+ render_template = "ungleich_page/ungleich/_products_item.html"
+ cache = False
+ require_parent = True
+ parent_classes = ['UngleichProductsPlugin']
+
+ def render(self, context, instance, placeholder):
+ context = super(UngleichProductsItemPlugin, self).render(
+ context, instance, placeholder
+ )
+ context['instance'] = instance
+ return context
+
+
+@plugin_pool.register_plugin
+class UngleichCustomerSectionPlugin(CMSPluginBase):
+ name = "ungleich Customer Section Plugin"
+ model = UngleichCustomer
+ render_template = "ungleich_page/ungleich/section_customers.html"
+ cache = False
+ allow_children = True
+ child_classes = ['UngleichCustomerItemPlugin']
+
+ def render(self, context, instance, placeholder):
+ context['customer_instance'] = instance
+ context['section_id'] = get_section_id(instance, 'customer')
+ return context
+
+
+@plugin_pool.register_plugin
+class UngleichCustomerItemPlugin(CMSPluginBase):
+ name = "ungleich Customer Item Plugin"
+ model = UngleichCustomerItem
+ render_template = "ungleich_page/ungleich/_customer_item.html"
+ cache = False
+ require_parent = True
+ parent_classes = ['UngleichCustomerSectionPlugin']
+
+ def render(self, context, instance, placeholder):
+ context = super(UngleichCustomerItemPlugin, self).render(
+ context, instance, placeholder
+ )
+ context['instance'] = instance
+ return context
+
+
+@plugin_pool.register_plugin
+class UngleichHTMLPlugin(CMSPluginBase):
+ name = "ungleich HTML Plugin"
+ model = UngleichHTMLOnly
+ render_template = "ungleich_page/ungleich/html_block.html"
+ cache = False
+
+ def render(self, context, instance, placeholder):
+ context = super(UngleichHTMLPlugin, self).render(
+ context, instance, placeholder
+ )
+ context['instance'] = instance
+ return context
+
+
+@plugin_pool.register_plugin
+class UngleichFooterPlugin(CMSPluginBase):
+ name = "ungleich Footer Plugin"
+ model = UngleichFooter
+ render_template = "ungleich_page/ungleich/_footer.html"
+ cache = False
+
+ def render(self, context, instance, placeholder):
+ context = super(UngleichFooterPlugin, self).render(
+ context, instance, placeholder
+ )
+ context['instance'] = instance
+ return context
diff --git a/ungleich_page/locale/de/LC_MESSAGES/django.mo b/ungleich_page/locale/de/LC_MESSAGES/django.mo
new file mode 100755
index 0000000..5bb68ff
Binary files /dev/null and b/ungleich_page/locale/de/LC_MESSAGES/django.mo differ
diff --git a/ungleich_page/locale/de/LC_MESSAGES/django.po b/ungleich_page/locale/de/LC_MESSAGES/django.po
new file mode 100755
index 0000000..9a4efa9
--- /dev/null
+++ b/ungleich_page/locale/de/LC_MESSAGES/django.po
@@ -0,0 +1,487 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR , YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-12-03 10:44+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: LANGUAGE \n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ungleich_page/cms_menus.py:12
+msgid "Glasfaser menu"
+msgstr ""
+
+#: ungleich_page/templates/ungleich_page/404.html:43
+msgid "\"Sorry, we could not find the page you are looking for!\""
+msgstr "\"Leider konnten wir die von dir gesuchte Seite nicht finden!\""
+
+#: ungleich_page/templates/ungleich_page/glasfaser.html:49
+#: ungleich_page/templates/ungleich_page/glasfaser_cms_page.html:53
+msgid "Toggle navigation"
+msgstr "Umschalten"
+
+#: ungleich_page/templates/ungleich_page/glasfaser.html:67
+#: ungleich_page/templates/ungleich_page/landing.html:80
+msgid "CONTACT"
+msgstr "KONTAKT"
+
+#: ungleich_page/templates/ungleich_page/glasfaser.html:82
+msgid "HIGH SPEED INTERNET"
+msgstr ""
+
+#: ungleich_page/templates/ungleich_page/glasfaser.html:242
+#: ungleich_page/templates/ungleich_page/glasfaser/section_contact.html:32
+msgid "Thank you for contacting us."
+msgstr "Nachricht gesendet."
+
+#: ungleich_page/templates/ungleich_page/glasfaser.html:245
+#: ungleich_page/templates/ungleich_page/glasfaser/section_contact.html:35
+msgid "Your message was successfully sent to our team."
+msgstr "Vielen Dank für Deine Nachricht."
+
+#: ungleich_page/templates/ungleich_page/glasfaser.html:260
+#: ungleich_page/templates/ungleich_page/glasfaser/section_contact.html:50
+msgid "Name"
+msgstr ""
+
+#: ungleich_page/templates/ungleich_page/glasfaser.html:262
+#: ungleich_page/templates/ungleich_page/glasfaser/section_contact.html:52
+msgid "Please enter your name."
+msgstr "Bitte gib Deinen Namen ein."
+
+#: ungleich_page/templates/ungleich_page/glasfaser.html:267
+#: ungleich_page/templates/ungleich_page/glasfaser/section_contact.html:57
+msgid "Email"
+msgstr "E-Mail-Adresse"
+
+#: ungleich_page/templates/ungleich_page/glasfaser.html:269
+#: ungleich_page/templates/ungleich_page/glasfaser/section_contact.html:59
+msgid "Please enter a valid email address."
+msgstr "Bitte gib eine gültige E-Mailadresse ein."
+
+#: ungleich_page/templates/ungleich_page/glasfaser.html:274
+#: ungleich_page/templates/ungleich_page/glasfaser/section_contact.html:64
+msgid "Message"
+msgstr "Nachricht"
+
+#: ungleich_page/templates/ungleich_page/glasfaser.html:282
+#: ungleich_page/templates/ungleich_page/glasfaser/section_contact.html:72
+msgid "Sorry, there was an unexpected error. Kindly retry."
+msgstr ""
+"Bitte entschuldige, es scheint ein unerwarteter Fehler aufgetreten zu sein. "
+"Versuche es doch bitte noch einmal."
+
+#: ungleich_page/templates/ungleich_page/glasfaser.html:283
+#: ungleich_page/templates/ungleich_page/glasfaser/section_contact.html:73
+msgid "SUBMIT"
+msgstr "ABSENDEN"
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:6
+msgid "ABOUT"
+msgstr "Über ungleich"
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:7
+msgid "The timeline of ungleich"
+msgstr "Die Chronik von ungleich"
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:19
+msgid "The first incarnation of ungleich"
+msgstr "Die erste Inkarnation von ungleich"
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:20
+msgid "in Germany."
+msgstr "in Deutschland."
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:33
+msgid "ungleich founded"
+msgstr "ungleich gegründet"
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:34
+msgid "in Switzerland."
+msgstr "in der Schweiz."
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:47
+msgid "ungleich present at various conferences"
+msgstr "ungleich präsent an mehreren Konferenzen"
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:61
+msgid "ungleich introduces HA-Hosting"
+msgstr "ungleich führt HA-Hosting ein"
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:62
+msgid "and introduces affordable 24X7 support."
+msgstr "und führt kostengünstigen 24X7 Support ein."
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:64
+msgid "ungleich launches"
+msgstr "ungleich lanciert"
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:65
+msgid "Digital Glarus project"
+msgstr "Digital Glarus Projekt"
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:79
+msgid ""
+"ungleich launches Alplora , an "
+"animal tracking service with LoraWAN technology."
+msgstr ""
+"ungleich startet das Projekt AlpLora"
+"a>, mit dem Tiere via LoRaWAN geortet werden können"
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:92
+msgid "ungleich starts to give basic computer courses for refugees."
+msgstr "ungleich bietet einen PC-Grundkurs für Flüchtlinge an."
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:105
+msgid ""
+"ungleich starts computer learning club for locals, \"Digitale Building "
+"ungleich\"."
+msgstr ""
+"ungleich gründet den Verein Digitale Bildung ungleich für Ortsansässige."
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:106
+msgid ""
+"ungleich sells Alplora to an IoT "
+"startup in canton Zürich."
+msgstr ""
+"ungleich verkauft das Projekt AlpLora an ein IoT-Startup aus dem Kanton Zürich."
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:107
+msgid ""
+"ungleich showcases the most affordable Swiss VM hosting, Data Center Light."
+msgstr ""
+"ungleich stellt der Öffentlichkeit das modernste Schweizer Hosting vor, das "
+"Data Center Light."
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:116
+msgid "and"
+msgstr "und"
+
+#: ungleich_page/templates/ungleich_page/includes/_about.html:116
+msgid "the story continues!"
+msgstr "Die Geschichte geht weiter!"
+
+#: ungleich_page/templates/ungleich_page/includes/_contact_us.html:16
+#: ungleich_page/templates/ungleich_page/includes/_contact_us.html:28
+#: ungleich_page/views.py:35
+msgid "Contact Us"
+msgstr "Kontaktieren Sie uns"
+
+#: ungleich_page/templates/ungleich_page/includes/_contact_us.html:18
+msgid "Join us at"
+msgstr "Schliessen Sie sich uns an"
+
+#: ungleich_page/templates/ungleich_page/includes/_contact_us.html:18
+msgid "Digital Glarus"
+msgstr "Digital Glarus"
+
+#: ungleich_page/templates/ungleich_page/includes/_contact_us.html:18
+msgid "a great co-working space in the middle of Alps!"
+msgstr "ein wunderschöner Co-Working Space mitten in den Alpen"
+
+#: ungleich_page/templates/ungleich_page/includes/_contact_us.html:19
+msgid "You can contact us at"
+msgstr "Sie können uns kontaktieren unter"
+
+#: ungleich_page/templates/ungleich_page/includes/_contact_us.html:26
+msgid "or"
+msgstr "oder"
+
+#: ungleich_page/templates/ungleich_page/includes/_contact_us.html:60
+msgid "Submit"
+msgstr "Absenden"
+
+#: ungleich_page/templates/ungleich_page/includes/_footer.html:8
+msgid "Copyright © ungleich GmbH "
+msgstr "Copyright © ungleich GmbH"
+
+#: ungleich_page/templates/ungleich_page/includes/_footer.html:26
+msgid "ungleich Home"
+msgstr "ungleich Home"
+
+#: ungleich_page/templates/ungleich_page/includes/_header.html:21
+#: ungleich_page/templates/ungleich_page/includes/_services.html:18
+msgid "Hosting"
+msgstr "Hosting"
+
+#: ungleich_page/templates/ungleich_page/includes/_header.html:22
+#: ungleich_page/templates/ungleich_page/includes/_services.html:19
+msgid ""
+"Ruby on Rails. Java hosting, Django hosting, we make it everything run "
+"smooth and safe."
+msgstr ""
+"Ruby on Rails. Java hosting, Django hosting, wir garantieren einen "
+"reibungslosen Ablauf."
+
+#: ungleich_page/templates/ungleich_page/includes/_header.html:33
+#: ungleich_page/templates/ungleich_page/includes/_services.html:27
+msgid "Configuration as a Service"
+msgstr "Konfiguration als Service"
+
+#: ungleich_page/templates/ungleich_page/includes/_header.html:34
+#: ungleich_page/templates/ungleich_page/includes/_services.html:28
+msgid ""
+"Ruby on Rails, Django, Java, Webserver, Mailserver, any infrastructure that "
+"needs to configured, we provide comprehensive solutions. Amazon, rackspace "
+"or bare metal servers, we configure for you."
+msgstr ""
+"Ruby on Rails, Django, Java, Webserver, Mailserver, jegliche Infrastruktur "
+"welche eine Konfiguration braucht, wir offerieren umfassende Lösungen, "
+"Amazon, Rackspace oder Bare Metal Servers, wir konfigurieren alles."
+
+#: ungleich_page/templates/ungleich_page/includes/_header.html:45
+#: ungleich_page/templates/ungleich_page/includes/_services.html:36
+msgid "Linux System Engineering"
+msgstr "Linux System Engineering"
+
+#: ungleich_page/templates/ungleich_page/includes/_header.html:46
+#: ungleich_page/templates/ungleich_page/includes/_services.html:37
+msgid ""
+"Let your developers develop! We take care of your system administration. "
+"Gentoo, Archlinux, Debian, Ubuntu, and many more."
+msgstr ""
+"Lassen sie ihre Entwickler entwickeln! Wir kümmern uns um ihre "
+"Systemadministration. Gentoo, Archlinux, Debian, Ubuntu und viele mehr."
+
+#: ungleich_page/templates/ungleich_page/includes/_portfolio.html:7
+msgid "Our Products"
+msgstr "Unsere Produkte"
+
+#: ungleich_page/templates/ungleich_page/includes/_portfolio.html:8
+msgid ""
+"Our products include an innovative datacenter, affordable VM hosting, and "
+"high speed fiber internet for canton Glarus."
+msgstr ""
+"Zu unseren Produkten gehört ein innovatives Rechenzentrum, modernes VM-"
+"Hosting und Glasfaser-Internet für den Kanton Glarus."
+
+#: ungleich_page/templates/ungleich_page/includes/_portfolio.html:14
+msgid "Data Center Light"
+msgstr ""
+
+#: ungleich_page/templates/ungleich_page/includes/_portfolio.html:15
+#, python-format
+msgid ""
+"We offer the most affordable hosting in Switzerland. Data Center Light has "
+"full FOSS stack, 100%% IPv6 and 100%% SSD. Choose any configuration among "
+"CentOS, Debian, Ubuntu, Devuan, and FreeBSD."
+msgstr ""
+"Wir bieten Ihnen ein erschwingliches Hosting in der Schweiz. Data Center "
+"Light basiert auf FOSS Software, 100%% IPv6 und 100%% SSD. Wählen Sie eine "
+"beliebige Konfiguration unter CentOS, Debian, Ubuntu, Devuan oder FreeBSD."
+
+#: ungleich_page/templates/ungleich_page/includes/_portfolio.html:21
+msgid "Rails Hosting"
+msgstr "Rails Hosting"
+
+#: ungleich_page/templates/ungleich_page/includes/_portfolio.html:22
+msgid ""
+"Ready to go live with your Ruby on Rails application? We offer you ready-to-"
+"deploy virtual machines or configure your existing infrastructure for Ruby "
+"on Rails."
+msgstr "Sind bereit mit ihrem Ruby on Rails Applikation live zu gehen?"
+
+#: ungleich_page/templates/ungleich_page/includes/_portfolio.html:28
+msgid "High Speed Internet"
+msgstr ""
+
+#: ungleich_page/templates/ungleich_page/includes/_portfolio.html:29
+msgid ""
+"We offer high speed fiber internet in Glarus Süd, Glarus and Glarus Nord. "
+"Experience 100 Mbit/s and see how speed can change everything."
+msgstr ""
+"Wir bieten außerdem Hochgeschwindigkeitsfaser Internet in Glarus Süd, Glarus "
+"und Glarus Nord. Surfen Sie mit 100 Mbit/s und erleben Sie, wie "
+"Geschwindigkeit alles ändern kann."
+
+#: ungleich_page/templates/ungleich_page/includes/_services.html:7
+msgid "our services"
+msgstr "Unsere Dienstleistungen"
+
+#: ungleich_page/templates/ungleich_page/includes/_services.html:9
+msgid "We support our clients in all areas of Unix infrastructure."
+msgstr ""
+"Wir unterstützen unsere Klienten in allen Bereichen der Unix Infrastruktur."
+
+#: ungleich_page/templates/ungleich_page/includes/_services.html:10
+msgid ""
+"Our top notch configuration management is refreshingly simple and reliable."
+msgstr ""
+"Unser erstklassiges Konfigurationsmanagement ist erfrischend einfach und "
+"zuverlässig."
+
+#: ungleich_page/templates/ungleich_page/includes/_team.html:7
+msgid "Why ungleich?*"
+msgstr "Warum ungleich?"
+
+#: ungleich_page/templates/ungleich_page/includes/_team.html:8
+msgid "What our customers say"
+msgstr "Was unsere Kunden sagen"
+
+#: ungleich_page/templates/ungleich_page/includes/_team.html:27
+msgid ""
+"\n"
+"\t\t\t \"ungleich helped us getting started with our internal\n"
+"\t\t\t infrastructure, hosted on physical servers in a\n"
+"\t\t\t co-location data centre in Zurich. From planning the\n"
+"\t\t\t network layout and virtualisation setup,\n"
+"\t\t\t inviting offers and securing a great deal from a\n"
+"\t\t\t hardware vendor, all the way to the installation of\n"
+"\t\t\t basic services like DNS, VPN and firewalls using the\n"
+"\t\t\t configuration management software cdist, we could\n"
+"\t\t\t count on the support of ungleich. At the end, we got\n"
+"\t\t\t a high availability infrastructure setup enabling our\n"
+"\t\t\t engineers to work more efficiently and comfortable\n"
+"\t\t\t than before.\"\n"
+"\t\t\t "
+msgstr ""
+"\n"
+" ungleich half uns mit unserer internen Infrastruktur, gehostet auf "
+"physikalischen Servern, in einer gemeinsamen Unterbringung in einem "
+"Datenzentrum in Zürich. Von der Planung des Netzwerk-Layouts und der "
+"Virtualisierung der Einrichtung, Offertanfragen und Sicherstellung eines "
+"sehr guten Angebots von einem Hardwarelieferanten bis hin zur "
+"Installisierung von einfachen Dienstleistungen, wie DNS, VPN und Firewalls "
+"durch den Gebrauch der Konfigurationsmanagement-Software cdist, wir konnten "
+"auf den Support von ungleich zählen. Am Ende haben wir eine hochverfügbare "
+"Infrastruktur-Einrichtung erhalten, welche es unseren Technikern ermöglicht "
+"effizienter und bequemer zu arbeiten als zuvor."
+
+#: ungleich_page/templates/ungleich_page/includes/_team.html:49
+msgid ""
+"\n"
+"\t\t\t \"Thanks to ungleich team, who has designed and\n"
+"\t\t\t configured our company's Linux infrastructure, our\n"
+"\t\t\t systems are very easy to maintain. Their innovative\n"
+"\t\t\t configuration management system cdist helped us\n"
+"\t\t\t significantly not only in cost but also in time\n"
+"\t\t\t saving, which is crucial for IT companies like ours.\"\n"
+"\t\t\t \t"
+msgstr ""
+"\n"
+" Vielen Dank an das ungleich Team, welches unsere Firmen-Linux-Infrastruktur "
+"konfiguriert hat, unsere Systeme sind sehr einfach zu verwalten. Ihr "
+"innovatives Konfigurationsmanagement-System cdist half uns signifikant nicht "
+"nur in der Kosteneinsparung aber auch zur Zeiteinsparung, was für IT-Firmen "
+"sehr wichtig ist."
+
+#: ungleich_page/templates/ungleich_page/includes/_team.html:65
+msgid ""
+"\n"
+"\t\t\t \"ungleich provided an excellent service in designing\n"
+"\t\t\t our system architecture and created secure and stable\n"
+"\t\t\t appliance. For us it is important to have an enduring\n"
+"\t\t\t stability in our system, and ungleich's configuration\n"
+"\t\t\t management system cdist is easy to adapt for our\n"
+"\t\t\t system administrators. We had a successful\n"
+"\t\t\t collaboration with ungleich in the time of very\n"
+"\t\t\t high workload, and their project leading was\n"
+"\t\t\t high-skilled and very reliable. I would definitely\n"
+"\t\t\t recommend them to any companies with high demand in\n"
+"\t\t\t solid infrastructures.\"\n"
+"\t\t\t "
+msgstr ""
+"\n"
+" ungleich bietete einen exzellenten Service bei der Gestaltung unserer "
+"System-Architektur und erstellte sichere und stabile Geräte. Für uns ist es "
+"wichtig eine dauerhafte Stabilität in unserem System zu haben und das "
+"Konfigurationsmanagement-System cdist ist sehr einfach zu bedienen für die "
+"Systemadministration. Wir hatten eine erfolgreiche Kollaboration mit "
+"ungleich während einer Zeit mit einer sehr hohen Arbeitsauslastung und ihre "
+"Projektführung war hochqualifiziert und sehr zuverlässig. Ich würde sie "
+"allen Firmen empfehlen, bei denen eine solide Infrastruktur stark gefragt "
+"ist."
+
+#: ungleich_page/templates/ungleich_page/includes/_team.html:80
+msgid ""
+"\n"
+"\t\t\t - Sebastian Plattner, \n"
+"\t\t\t Teamleader Development Cyber Security Products at RUAG\n"
+"\t\t\t "
+msgstr ""
+
+#: ungleich_page/templates/ungleich_page/includes/_team.html:93
+msgid "*ungleich means not equal to (≠) U+2260."
+msgstr "*ungleich bedeutet nicht gleich wie (≠) U+2260."
+
+#: ungleich_page/templates/ungleich_page/landing.html:65
+msgid "Services"
+msgstr "Dienstleistungen"
+
+#: ungleich_page/templates/ungleich_page/landing.html:68
+msgid "products"
+msgstr "PRODUKTE"
+
+#: ungleich_page/templates/ungleich_page/landing.html:71
+msgid "About"
+msgstr "Über"
+
+#: ungleich_page/templates/ungleich_page/landing.html:74
+msgid "WHY UNGLEICH?"
+msgstr "WARUM UNGLEICH?"
+
+#: ungleich_page/templates/ungleich_page/landing.html:77
+msgid "BLOG"
+msgstr "BLOG"
+
+#: ungleich_page/templates/ungleich_page/ungleich/_header_with_background_video_slider_item.html:25
+msgid "Learn More"
+msgstr "erfahren Sie mehr"
+
+#: ungleich_page/urls.py:8
+msgid "contact/$"
+msgstr "kontakt/$"
+
+#: ungleich_page/views.py:25
+msgid "Message Successfully Sent"
+msgstr "Nachricht erfolgreich versendet"
+
+#: ungleich_page/views.py:36
+msgid "If you have any question, just send us an email."
+msgstr ""
+"Wenn Sie irgendwelche Fragen haben, schicken Sie uns einfach eine E-Mail."
+
+#~ msgid "We Design, Configure & Maintain Your Linux Infrastructure "
+#~ msgstr "Wir designen, erstellen und warten Ihre Linux-Infrastruktur"
+
+#~ msgid "Hosting Products "
+#~ msgstr "Hosting Produkte"
+
+#~ msgid "HA Hosting"
+#~ msgstr "HA Hosting"
+
+#~ msgid ""
+#~ "We offer high availablity hosting (HA) in Germany and in Switzerland. Our "
+#~ "infrastructure is powered by Free and Open Source Software like "
+#~ "OpenNebula, Qemu and GlusterFS."
+#~ msgstr ""
+#~ "Wir offerieren hohe Verfügbarkeit für das Hosting in Deutschland und in "
+#~ "der Schweiz. Unsere Infrastruktur ist unterstützt durch Free and Open "
+#~ "Source Software wie OpenNebula."
+
+#~ msgid " Configuration as a Service"
+#~ msgstr "Konfiguration als Service"
+
+#~ msgid ""
+#~ "You are in need for a configuration? With ungleich you have found an "
+#~ "experienced team that configure your systems to provide service like DNS, "
+#~ "E-Mail, Databases or Webservers."
+#~ msgstr ""
+#~ "Sie brauchen eine Konfiguration? Mit ungleich haben sie ein erfahrenes "
+#~ "Team gefunden, dass ihnen die Konfiguration von DNS, E-Mail, Datenbanken "
+#~ "oder Webservern für ihr System anbietet"
+
+#~ msgid "Contact"
+#~ msgstr "Kontaktieren Sie uns"
diff --git a/ungleich_page/models.py b/ungleich_page/models.py
new file mode 100755
index 0000000..53a433b
--- /dev/null
+++ b/ungleich_page/models.py
@@ -0,0 +1,210 @@
+from cms.models.pluginmodel import CMSPlugin
+from django.db import models
+from djangocms_text_ckeditor.fields import HTMLField
+from filer.fields.image import FilerImageField, FilerFileField
+
+
+class UngelichPicture(CMSPlugin):
+ image = FilerImageField(
+ null=True,
+ blank=True,
+ related_name="image",
+ on_delete=models.SET_NULL
+ )
+ title = HTMLField()
+
+
+class SectionWithImage(UngelichPicture):
+ menu_text = models.CharField(max_length=100, default="", blank=True)
+ price_tag_image = FilerImageField(
+ null=True,
+ blank=True,
+ related_name="price_tag_image",
+ on_delete=models.SET_NULL
+ )
+ price_tag_url = models.URLField(max_length=300, default="", blank=True)
+
+
+class UngelichContactUsSection(CMSPlugin):
+ menu_text = models.CharField(max_length=100, default="", blank=True)
+ email = models.EmailField(max_length=200, default="info@ungleich.ch")
+ contact_text = models.CharField(
+ max_length=100, default="Contact", blank=True
+ )
+ organization_name = models.CharField(
+ max_length=100, default="ungleich GmbH", blank=True
+ )
+ address = models.CharField(
+ max_length=100, default="In der Au 7, Schwanden 8762", blank=True
+ )
+ country = models.CharField(
+ max_length=100, default="Switzerland", blank=True
+ )
+ contact_form_header_text = models.CharField(
+ max_length=100, default="Send us a message.", blank=True
+ )
+
+
+class UngelichTextSection(CMSPlugin):
+ menu_text = models.CharField(max_length=100, default="", blank=True)
+ title = models.CharField(max_length=200)
+ description = HTMLField()
+
+
+class Service(CMSPlugin):
+ menu_text = models.CharField(max_length=100, default="", blank=True)
+ title = models.CharField(max_length=200)
+ sub_title = HTMLField()
+
+ def __str__(self):
+ return self.title
+
+
+class ServiceItem(CMSPlugin):
+ image = FilerImageField(
+ null=True,
+ blank=True,
+ related_name="service_item_image",
+ on_delete=models.SET_NULL
+ )
+ title = models.CharField(max_length=200)
+ description = HTMLField()
+
+ def __str__(self):
+ return self.title
+
+
+class About(Service):
+ pass
+
+
+class AboutItem(UngelichPicture):
+ inverted = models.BooleanField(default=False)
+ link_url = models.URLField(max_length=300, default="", blank=True)
+
+ def __str__(self):
+ alignment = "Right" if self.inverted else "Left"
+ return "{alignment} - {title}".format(
+ alignment=alignment, title=self.title
+ )
+
+
+class UngleichServiceItem(ServiceItem):
+ data_replaced_image = FilerImageField(
+ null=True,
+ blank=True,
+ related_name="service_item_data_replaced_image",
+ on_delete=models.SET_NULL
+ )
+
+
+class UngleichHeaderWithBackgroundImageSlider(CMSPlugin):
+ carousel_data_interval = models.IntegerField(default=2000)
+
+
+class UngleichHeaderWithBackgroundVideoSliderItem(CMSPlugin):
+ image = FilerImageField(
+ null=True,
+ blank=True,
+ related_name="ungleich_header_item_poster",
+ on_delete=models.SET_NULL,
+ help_text='The background image or poster image for video.'
+ )
+ video = FilerFileField(
+ null=True,
+ blank=True,
+ related_name="ungleich_header_item_video",
+ on_delete=models.SET_NULL,
+ help_text='Leaving this blank will make the image as the background.'
+ )
+ heading = models.CharField(
+ blank=True, null=True, max_length=100,
+ help_text='An optional title for this slide.',
+ )
+ description = models.TextField(
+ blank=True, null=True,
+ help_text='An optional description for this slide.'
+ )
+ btn_link = models.CharField(
+ max_length=100, blank=True, null=True,
+ help_text=(
+ 'Url or #id to navigate on click. If this field is left empty, no '
+ 'button would be displayed.'
+ )
+ )
+ btn_text = models.CharField(
+ blank=True, null=True, max_length=50,
+ help_text='Text for the button, if a link is provided.'
+ )
+
+
+class UngleichProductItem(ServiceItem):
+ url = models.URLField(max_length=300, default="", blank=True)
+
+
+class UngleichProduct(Service):
+ section_class = models.CharField(max_length=100, default="", blank=True)
+ animate = models.BooleanField(default=True)
+
+
+class UngleichCustomer(Service):
+ section_class = models.CharField(max_length=100, default="", blank=True)
+ carousel_data_interval = models.IntegerField(default=3000)
+ bottom_text = HTMLField(
+ default='*ungleich means '
+ 'not equal to (≠) U+2260. '
+ )
+
+
+class UngleichCustomerItem(CMSPlugin):
+ image = FilerImageField(
+ null=True,
+ blank=True,
+ related_name="customer_item_image",
+ on_delete=models.SET_NULL
+ )
+ url = models.URLField(max_length=300, default="", blank=True)
+ description = HTMLField()
+
+
+class UngleichHTMLOnly(CMSPlugin):
+ name = models.CharField(max_length=50, default="", blank=True)
+ HTML = HTMLField()
+
+ def __str__(self):
+ return self.name
+
+
+class UngleichFooter(CMSPlugin):
+ copyright_label = models.CharField(
+ max_length=100, default='', blank=True,
+ help_text='Name of the company alongside the copyright year'
+ )
+ link_text = models.CharField(
+ max_length=100, blank=True, null=True,
+ help_text='Text for the link on the right part of footer'
+ )
+ link_url = models.URLField(
+ blank=True, null=True,
+ help_text='Url to the link in footer'
+ )
+ twitter_url = models.URLField(
+ blank=True, null=True,
+ help_text='If empty, twitter btn will not be visible'
+ )
+ linkedin_url = models.URLField(
+ blank=True, null=True,
+ help_text='If empty, linkedin btn will not be visible'
+ )
+ github_url = models.URLField(
+ blank=True, null=True,
+ help_text='If empty, github btn will not be visible'
+ )
+ facebook_url = models.URLField(
+ blank=True, null=True,
+ help_text='If empty, facebook btn will not be visible'
+ )
+ youtube_url = models.URLField(
+ blank=True, null=True,
+ help_text='If empty, youtube btn will not be visible'
+ )
diff --git a/ungleich_page/static/ungleich_page/css/404.css b/ungleich_page/static/ungleich_page/css/404.css
new file mode 100755
index 0000000..2528973
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/css/404.css
@@ -0,0 +1,28 @@
+.error {
+ margin: 0 auto;
+ text-align: center;
+}
+
+.error-code {
+ bottom: 60%;
+ color: #2d353c;
+ font-size: 96px;
+ line-height: 100px;
+}
+
+.error-desc {
+ font-size: 12px;
+ color: #647788;
+}
+
+.m-b-10 {
+ margin-bottom: 10px!important;
+}
+
+.m-b-20 {
+ margin-bottom: 20px!important;
+}
+
+.m-t-20 {
+ margin-top: 20px!important;
+}
diff --git a/ungleich_page/static/ungleich_page/css/agency.css b/ungleich_page/static/ungleich_page/css/agency.css
new file mode 100755
index 0000000..2b40158
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/css/agency.css
@@ -0,0 +1,994 @@
+/*!
+ * Start Bootstrap - Agency Bootstrap Theme (http://startbootstrap.com)
+ * Code licensed under the Apache License v2.0.
+ * For details, see http://www.apache.org/licenses/LICENSE-2.0.
+ */
+
+html {
+ overflow-x: hidden;
+}
+
+body {
+ overflow-x: hidden;
+ font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
+}
+
+.row-eq-height {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.text-muted {
+ color: #494949;
+ font-family: 'Raleway' , "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+
+.text-primary {
+ color: #fed136;
+}
+
+p {
+ font-size: 14px;
+ line-height: 1.75;
+ color: #494949;
+ font-family: "Raleway" , "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+
+p.large {
+ font-size: 16px;
+}
+
+a,
+a:hover,
+a:focus,
+a:active,
+a.active {
+ outline: 0;
+}
+
+a {
+ color: #428bca;
+}
+
+a:hover,
+a:focus,
+a:active,
+a.active {
+ color: #fec503;
+ font-style: normal;
+ text-transform: none;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ text-transform: uppercase;
+ font-family:'Raleway', Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
+ font-weight: 700;
+ color: #494949;
+ font-size: 18px;
+}
+
+.img-centered {
+ margin: 0 auto;
+}
+
+.bg-light-gray {
+ background-color: #f7f7f7;
+}
+
+.bg-darkest-gray {
+ background-color: #222;
+}
+
+.btn-primary {
+ border-color: #fed136;
+ text-transform: uppercase;
+ font-family: Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
+ font-weight: 700;
+ color: #fff;
+ background-color: #fed136;
+}
+
+.btn-primary:hover,
+.btn-primary:focus,
+.btn-primary:active,
+.btn-primary.active,
+.open .dropdown-toggle.btn-primary {
+ border-color: #f6bf01;
+ color: #fff;
+ background-color: #fec503;
+}
+
+.btn-primary:active,
+.btn-primary.active,
+.open .dropdown-toggle.btn-primary {
+ background-image: none;
+}
+
+.btn-primary.disabled,
+.btn-primary[disabled],
+fieldset[disabled] .btn-primary,
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled:active,
+.btn-primary[disabled]:active,
+fieldset[disabled] .btn-primary:active,
+.btn-primary.disabled.active,
+.btn-primary[disabled].active,
+fieldset[disabled] .btn-primary.active {
+ border-color: #fed136;
+ background-color: #fed136;
+}
+
+.btn-primary .badge {
+ color: #fed136;
+ background-color: #fff;
+}
+
+.btn-xl {
+ padding: 20px 40px;
+ border-color: #fed136;
+ border-radius: 3px;
+ text-transform: uppercase;
+ font-family: Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
+ font-size: 18px;
+ font-weight: 700;
+ color: #fff;
+ background-color: #fed136;
+}
+
+.btn-xl:hover,
+.btn-xl:focus,
+.btn-xl:active,
+.btn-xl.active,
+.open .dropdown-toggle.btn-xl {
+ border-color: #f6bf01;
+ color: #fff;
+ background-color: #fec503;
+}
+
+.btn-xl:active,
+.btn-xl.active,
+.open .dropdown-toggle.btn-xl {
+ background-image: none;
+}
+
+.btn-xl.disabled,
+.btn-xl[disabled],
+fieldset[disabled] .btn-xl,
+.btn-xl.disabled:hover,
+.btn-xl[disabled]:hover,
+fieldset[disabled] .btn-xl:hover,
+.btn-xl.disabled:focus,
+.btn-xl[disabled]:focus,
+fieldset[disabled] .btn-xl:focus,
+.btn-xl.disabled:active,
+.btn-xl[disabled]:active,
+fieldset[disabled] .btn-xl:active,
+.btn-xl.disabled.active,
+.btn-xl[disabled].active,
+fieldset[disabled] .btn-xl.active {
+ border-color: #fed136;
+ background-color: #fed136;
+}
+
+.btn-xl .badge {
+ color: #fed136;
+ background-color: #fff;
+}
+
+.navbar-default {
+ border-color: transparent;
+ background-color: #222;
+}
+
+.navbar-default .navbar-brand {
+ font-family: "Helvetica Neue", Helvetica, Arial, cursive;
+ color: #fed136;
+}
+
+.navbar-default .navbar-brand:hover,
+.navbar-default .navbar-brand:focus,
+.navbar-default .navbar-brand:active,
+.navbar-default .navbar-brand.active {
+ color: #fec503;
+}
+
+.navbar-default .navbar-collapse {
+ border-color: rgba(255,255,255,.02);
+}
+
+.navbar-default .navbar-toggle .icon-bar {
+ background-color: #fff;
+}
+
+.navbar-default .navbar-toggle:hover,
+.navbar-default .navbar-toggle:focus {
+ background-color: transparent;
+}
+
+.navbar-default .nav li a {
+ text-transform: uppercase;
+ font-family: Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
+ font-weight: 400;
+ letter-spacing: 1px;
+ color: #fff;
+}
+
+.navbar-default .nav li a:hover,
+.navbar-default .nav li a:focus {
+ outline: 0;
+ color: #fed136;
+}
+
+.navbar-default .navbar-nav>.active>a {
+ border-radius: 0;
+ color: #fff;
+ background-color: #fed136;
+}
+
+.navbar-default .navbar-nav>.active>a:hover,
+.navbar-default .navbar-nav>.active>a:focus {
+ color: #fff;
+ background-color: #fec503;
+}
+
+.navbar-default .navbar-brand {
+ padding: 12px;
+}
+
+@media(min-width:768px) {
+ .navbar-default {
+ padding: 25px 0;
+ border: 0;
+ background-color: transparent;
+ -webkit-transition: padding .3s;
+ -moz-transition: padding .3s;
+ transition: padding .3s;
+ }
+
+ .navbar-default .navbar-brand {
+ font-size: 2em;
+ -webkit-transition: all .3s;
+ -moz-transition: all .3s;
+ transition: all .3s;
+ }
+
+ .navbar-default .navbar-nav>.active>a {
+ border-radius: 3px;
+ }
+
+ .navbar-default.navbar-shrink {
+ padding: 10px 0;
+ background-color: #222;
+ }
+
+ .navbar-default .navbar-brand {
+ padding: 8px 8px;
+ }
+ .navbar-default.navbar-shrink .navbar-brand {
+ padding: 6px 8px 10px;
+ }
+}
+
+.navbar-default .navbar-brand > img {
+ height: 100%;
+}
+
+header {
+ text-align: center;
+ color: #fff;
+ background: rgba(0,0,0,0.25);
+}
+
+header .intro-text {
+ padding-top: 100px;
+ padding-bottom: 50px;
+}
+
+header .intro-text .intro-lead-in {
+ margin-bottom: 25px;
+ font-family: 'Raleway', "Droid Serif","Helvetica Neue",Helvetica,Arial,sans-serif;
+ font-size: 22px;
+ font-style: italic;
+ line-height: 22px;
+}
+
+header .intro-text .intro-heading {
+ margin-bottom: 25px;
+ text-transform: uppercase;
+ font-family: 'Raleway', Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
+ font-size: 50px;
+ font-weight: 700;
+ line-height: 50px;
+}
+
+@media(min-width:768px) {
+ header .intro-text {
+ padding-top: 200px;
+ padding-bottom: 200px;
+ }
+
+ header .intro-text .intro-lead-in {
+ margin-bottom: 25px;
+ font-family: "Open Sans Extrabold", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 40px;
+ line-height: 40px;
+ font-style: normal;
+ }
+
+ header .intro-text .intro-heading {
+ margin-bottom: 50px;
+ text-transform: uppercase;
+ font-family: Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
+ font-size: 75px;
+ font-weight: 700;
+ line-height: 75px;
+ }
+}
+
+section {
+ padding: 75px 0;
+ border-bottom: 1px solid #f3f4f5;
+}
+
+@media(max-width:767px) {
+ section {
+ padding: 50px 0;
+ }
+}
+
+section .section-heading-contain {
+ margin-bottom: 50px;
+}
+
+@media(min-width:767px) {
+ section .section-heading-contain {
+ margin-bottom: 75px;
+ }
+}
+
+section h2.section-heading {
+ margin-top: 0;
+ margin-bottom: 15px;
+ font-size: 26px;
+ color: #494949;
+ letter-spacing: -1px;
+ font-weight: 400;
+}
+
+section h3.section-subheading {
+ text-transform: none;
+ font-family: 'Raleway', "Helvetica Neue", "Open Sans", "Droid Serif", Helvetica, Arial, sans-serif;
+ font-size: 16px;
+ font-weight: 400;
+ color: #494949;
+ line-height: 1.4;
+}
+
+@media(min-width:768px) {
+ section h2.section-heading {
+ font-size: 40px;
+ }
+ section h3.section-subheading {
+ font-size: 18px;
+ }
+}
+
+.service-heading {
+ margin: 15px 0;
+ text-transform: none;
+ font-family: 'Raleway Semi-Bold 600', "Open Sans Extrabold", Montserrat, "Helvetica Neue", Helvetica, Arial, sans-serif;
+ color: #7f8c8c;
+}
+
+#portfolio .portfolio-item {
+ right: 0;
+ margin: 0 0 15px;
+ text-align: center;
+}
+
+#portfolio .portfolio-item .portfolio-link {
+ display: block;
+ position: relative;
+ margin: 0 auto;
+ max-width: 400px;
+}
+
+#portfolio .portfolio-item .portfolio-link .portfolio-hover {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ opacity: 0;
+ background: rgba(254,209,54,.9);
+ -webkit-transition: all ease .5s;
+ -moz-transition: all ease .5s;
+ transition: all ease .5s;
+}
+
+#portfolio .portfolio-item .portfolio-link .portfolio-hover:hover {
+ opacity: 1;
+}
+
+#portfolio .portfolio-item .portfolio-link .portfolio-hover .portfolio-hover-content {
+ position: absolute;
+ top: 50%;
+ width: 100%;
+ height: 20px;
+ margin-top: -12px;
+ text-align: center;
+ font-size: 20px;
+ color: #fff;
+}
+
+#portfolio .portfolio-item .portfolio-link .portfolio-hover .portfolio-hover-content i {
+ margin-top: -12px;
+}
+
+#portfolio .portfolio-item .portfolio-link .portfolio-hover .portfolio-hover-content h3,
+#portfolio .portfolio-item .portfolio-link .portfolio-hover .portfolio-hover-content h4 {
+ margin: 0;
+}
+
+#portfolio .portfolio-item .portfolio-caption {
+ padding: 25px;
+ max-width: 400px;
+ text-align: center;
+ background-color: #fff;
+ width: 100%;
+}
+
+#portfolio .portfolio-item .portfolio-caption h4 {
+ margin: 0 0 17px;
+ text-transform: none;
+ color: #494949;
+}
+
+#portfolio .portfolio-item .portfolio-caption p {
+ margin: 0;
+ font-family: "Raleway", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+}
+
+#portfolio * {
+ z-index: 2;
+}
+
+.inline-block {
+ display: inline-block
+}
+
+@media(min-width:768px) {
+ #portfolio .portfolio-item {
+ margin: 0 0 30px;
+ }
+}
+
+.timeline {
+ position: relative;
+ padding: 0;
+ list-style: none;
+}
+
+.timeline:before {
+ content: "";
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 40px;
+ width: 2px;
+ margin-left: -1.5px;
+ background-color: #f1f1f1;
+}
+
+.timeline>li {
+ position: relative;
+ margin-bottom: 50px;
+ min-height: 50px;
+}
+
+.timeline>li:before,
+.timeline>li:after {
+ content: " ";
+ display: table;
+}
+
+.timeline>li:after {
+ clear: both;
+}
+
+.timeline>li .timeline-panel {
+ float: right;
+ position: relative;
+ width: 100%;
+ padding: 0 20px 0 100px;
+ text-align: left;
+}
+
+.timeline>li .timeline-panel:before {
+ right: auto;
+ left: -15px;
+ border-right-width: 15px;
+ border-left-width: 0;
+}
+
+.timeline>li .timeline-panel:after {
+ right: auto;
+ left: -14px;
+ border-right-width: 14px;
+ border-left-width: 0;
+}
+
+.timeline>li .timeline-image {
+ z-index: 100;
+ position: absolute;
+ left: 0;
+ width: 80px;
+ height: 80px;
+ margin-left: 0;
+ border: 7px solid #f1f1f1;
+ border-radius: 100%;
+ text-align: center;
+ color: #fff;
+ background-color: #fed136;
+}
+
+.timeline>li .timeline-image h4 {
+ margin-top: 12px;
+ font-size: 10px;
+ line-height: 14px;
+}
+
+.timeline>li.timeline-inverted>.timeline-panel {
+ float: right;
+ padding: 0 20px 0 100px;
+ text-align: left;
+}
+
+.timeline>li.timeline-inverted>.timeline-panel:before {
+ right: auto;
+ left: -15px;
+ border-right-width: 15px;
+ border-left-width: 0;
+}
+
+.timeline>li.timeline-inverted>.timeline-panel:after {
+ right: auto;
+ left: -14px;
+ border-right-width: 14px;
+ border-left-width: 0;
+}
+
+.timeline>li:last-child {
+ margin-bottom: 0;
+}
+
+.timeline .timeline-heading h4 {
+ margin-top: 0;
+ color: inherit;
+}
+
+.timeline .timeline-heading h4 {
+ margin-bottom: 7px;
+}
+
+.timeline .timeline-heading h4.subheading {
+ text-transform: none;
+}
+
+.timeline .timeline-body>p,
+.timeline .timeline-body>ul {
+ margin-bottom: 0;
+}
+
+@media(min-width:768px) {
+ .timeline:before {
+ left: 50%;
+ }
+
+ .timeline>li {
+ margin-bottom: 75px;
+ min-height: 100px;
+ }
+
+ .timeline>li .timeline-panel {
+ float: left;
+ width: 41%;
+ padding: 0 20px 20px;
+ text-align: right;
+ }
+
+ .timeline>li .timeline-image {
+ left: 50%;
+ width: 100px;
+ height: 100px;
+ margin-left: -50px;
+ }
+
+ .timeline>li .timeline-image h4 {
+ margin-top: 16px;
+ font-size: 12px;
+ line-height: 18px;
+ }
+
+ .timeline>li.timeline-inverted>.timeline-panel {
+ float: right;
+ padding: 0 20px 20px;
+ text-align: left;
+ }
+}
+
+@media(min-width:992px) {
+ .timeline>li {
+ min-height: 150px;
+ }
+
+ .timeline>li .timeline-panel {
+ padding: 10px 20px 20px;
+ }
+
+ .timeline>li .timeline-image {
+ width: 150px;
+ height: 150px;
+ margin-left: -75px;
+ }
+
+ .timeline>li .timeline-image h4 {
+ margin-top: 30px;
+ font-size: 18px;
+ line-height: 26px;
+ }
+
+ .timeline>li.timeline-inverted>.timeline-panel {
+ padding: 10px 20px 20px;
+ }
+}
+
+@media(min-width:1200px) {
+ .timeline>li {
+ min-height: 170px;
+ }
+
+ .timeline>li .timeline-panel {
+ padding: 10px 20px 20px 100px;
+ }
+
+ .timeline>li .timeline-image {
+ width: 170px;
+ height: 170px;
+ margin-left: -85px;
+ }
+
+ .timeline>li .timeline-image h4 {
+ margin-top: 40px;
+ }
+
+ .timeline>li.timeline-inverted>.timeline-panel {
+ padding: 0 100px 20px 20px;
+ }
+}
+
+.team-member {
+ margin-bottom: 25px;
+ text-align: center;
+}
+
+.team-member img {
+ margin: 0 auto;
+ border: 7px solid #fff;
+}
+
+.team-member h4 {
+ margin-top: 15px;
+ margin-bottom: 15px;
+ text-transform: none;
+}
+
+@media(max-width:767px) {
+ .team-member .team-member-caption p {
+ line-height: 1.5;
+ }
+ .team-member {
+ max-width: 400px;
+ margin-left: auto;
+ margin-right: auto;
+ }
+}
+
+@media(min-width:768px) {
+ .team-member h4 {
+ margin-top: 20px;
+ margin-bottom: 20px;
+ }
+}
+
+.team-member p {
+ margin-top: 0;
+}
+
+aside.clients img {
+ margin: 50px auto;
+}
+
+section#contact {
+ position: relative;
+ background: rgba(0,0,0,0.75);
+}
+
+section#contact .bg_img {
+ filter: blur(1px);
+}
+
+section#contact a {
+ color: #79bcf7;
+}
+
+section#contact .section-heading {
+ color: #fff;
+ font-size: 32px;
+}
+
+@media(max-width:767px) {
+ aside.clients img {
+ margin: 20px auto;
+ }
+ section#contact .section-heading {
+ font-size: 26px;
+ }
+ section#contact .intro-smallcap {
+ font-size: 18px;
+ }
+}
+
+section#contact .form-group {
+ color:white;
+ margin-bottom: 25px;
+ text-align: left;
+}
+
+section#contact .form-group input,
+section#contact .form-group textarea {
+ padding: 20px;
+}
+
+section#contact .form-group input.form-control {
+ height: auto;
+}
+
+section#contact .form-group textarea.form-control {
+ height: 236px;
+}
+
+section#contact .form-control:focus {
+ border-color: #fed136;
+ box-shadow: none;
+}
+
+section#contact::-webkit-input-placeholder {
+ text-transform: uppercase;
+ font-family: Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
+ font-weight: 700;
+ color: #bbb;
+}
+
+section#contact:-moz-placeholder {
+ text-transform: uppercase;
+ font-family: Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
+ font-weight: 700;
+ color: #bbb;
+}
+
+section#contact::-moz-placeholder {
+ text-transform: uppercase;
+ font-family: Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
+ font-weight: 700;
+ color: #bbb;
+}
+
+section#contact:-ms-input-placeholder {
+ text-transform: uppercase;
+ font-family: Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
+ font-weight: 700;
+ color: #bbb;
+}
+
+section#contact .text-danger {
+ color: #e74c3c;
+}
+
+footer {
+ padding: 25px 0;
+ text-align: center;
+}
+
+footer span.copyright {
+ text-transform: uppercase;
+ text-transform: none;
+ font-family: Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
+ line-height: 40px;
+}
+
+footer ul.quicklinks {
+ margin-bottom: 0;
+ text-transform: uppercase;
+ text-transform: none;
+ font-family: Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
+ line-height: 40px;
+}
+
+ul.social-buttons {
+ margin-bottom: 0;
+}
+
+ul.social-buttons li a {
+ display: block;
+ width: 40px;
+ height: 40px;
+ border-radius: 100%;
+ font-size: 20px;
+ line-height: 40px;
+ outline: 0;
+ color: #fff;
+ background-color: #222;
+ -webkit-transition: all .3s;
+ -moz-transition: all .3s;
+ transition: all .3s;
+}
+
+ul.social-buttons li a:hover,
+ul.social-buttons li a:focus,
+ul.social-buttons li a:active {
+ background-color: #fed136;
+}
+
+.btn:focus,
+.btn:active,
+.btn.active,
+.btn:active:focus {
+ outline: 0;
+}
+
+.portfolio-modal .modal-content {
+ padding: 100px 0;
+ min-height: 100%;
+ border: 0;
+ border-radius: 0;
+ text-align: center;
+ background-clip: border-box;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.portfolio-modal .modal-content h2 {
+ margin-bottom: 15px;
+ font-size: 3em;
+}
+
+.portfolio-modal .modal-content p {
+ margin-bottom: 30px;
+}
+
+.portfolio-modal .modal-content p.item-intro {
+ margin: 20px 0 30px;
+ font-family: "Droid Serif","Helvetica Neue",Helvetica,Arial,sans-serif;
+ font-size: 16px;
+ font-style: italic;
+}
+
+.portfolio-modal .modal-content ul.list-inline {
+ margin-top: 0;
+ margin-bottom: 30px;
+}
+
+.portfolio-modal .modal-content img {
+ margin-bottom: 30px;
+}
+
+.portfolio-modal .close-modal {
+ position: absolute;
+ top: 25px;
+ right: 25px;
+ width: 75px;
+ height: 75px;
+ background-color: transparent;
+ cursor: pointer;
+}
+
+.portfolio-modal .close-modal:hover {
+ opacity: .3;
+}
+
+.portfolio-modal .close-modal .lr {
+ z-index: 1051;
+ width: 1px;
+ height: 75px;
+ margin-left: 35px;
+ background-color: #222;
+ -webkit-transform: rotate(45deg);
+ -ms-transform: rotate(45deg);
+ transform: rotate(45deg);
+}
+
+.portfolio-modal .close-modal .lr .rl {
+ z-index: 1052;
+ width: 1px;
+ height: 75px;
+ background-color: #222;
+ -webkit-transform: rotate(90deg);
+ -ms-transform: rotate(90deg);
+ transform: rotate(90deg);
+}
+
+::-moz-selection {
+ text-shadow: none;
+ background: #fed136;
+}
+
+::selection {
+ text-shadow: none;
+ background: #fed136;
+}
+
+img::selection {
+ background: 0 0;
+}
+
+img::-moz-selection {
+ background: 0 0;
+}
+
+body {
+ webkit-tap-highlight-color: #fed136;
+}
+
+section h3.section-comment {
+ margin-bottom: 75px;
+ text-transform: none;
+ font-family: "Open Sans", "Droid Serif", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-style:italic
+ font-size: 18px;
+ font-weight: 400;
+ color: #494949;
+}
+
+.carousel-indicators li.active, .text-carousel .carousel-indicators li.active {
+ border: 0;
+ background-color: #fed136;
+}
+
+@media (min-width: 740px) {
+ .carousel-inner, .text-carousel .carousel-inner {
+ min-height: 225px;
+ }
+}
+
+.carousel-text {
+ text-transform : none;
+ font-family:'Raleway' , Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
+ font-size : 20px;
+ font-weight : 100;
+ color : #666;
+ text-align : center;
+}
+
+@media (max-width: 767px) {
+ .ungleich-gallery-text-carousel .carousel-text {
+ height: 220px;
+ overflow-y: scroll;
+ text-align: left;
+ }
+ .carousel-author {
+ height: 72px;
+ }
+}
diff --git a/ungleich_page/static/ungleich_page/css/bootstrap.css b/ungleich_page/static/ungleich_page/css/bootstrap.css
new file mode 100755
index 0000000..4165d41
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/css/bootstrap.css
@@ -0,0 +1,6358 @@
+/*!
+ * Bootstrap v3.3.0 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
+html {
+ font-family: sans-serif;
+ -webkit-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%;
+}
+body {
+ margin: 0;
+}
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+ display: block;
+}
+audio,
+canvas,
+progress,
+video {
+ display: inline-block;
+ vertical-align: baseline;
+}
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+[hidden],
+template {
+ display: none;
+}
+a {
+ background-color: transparent;
+}
+a:active,
+a:hover {
+ outline: 0;
+}
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+b,
+strong {
+ font-weight: bold;
+}
+dfn {
+ font-style: italic;
+}
+h1 {
+ margin: .67em 0;
+ font-size: 2em;
+}
+mark {
+ color: #000;
+ background: #ff0;
+}
+small {
+ font-size: 80%;
+}
+sub,
+sup {
+ position: relative;
+ font-size: 75%;
+ line-height: 0;
+ vertical-align: baseline;
+}
+sup {
+ top: -.5em;
+}
+sub {
+ bottom: -.25em;
+}
+img {
+ border: 0;
+}
+svg:not(:root) {
+ overflow: hidden;
+}
+figure {
+ margin: 1em 40px;
+}
+hr {
+ height: 0;
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+pre {
+ overflow: auto;
+}
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, monospace;
+ font-size: 1em;
+}
+button,
+input,
+optgroup,
+select,
+textarea {
+ margin: 0;
+ font: inherit;
+ color: inherit;
+}
+button {
+ overflow: visible;
+}
+button,
+select {
+ text-transform: none;
+}
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button;
+ cursor: pointer;
+}
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
+input {
+ line-height: normal;
+}
+input[type="checkbox"],
+input[type="radio"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ padding: 0;
+}
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+input[type="search"] {
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ -webkit-appearance: textfield;
+}
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+fieldset {
+ padding: .35em .625em .75em;
+ margin: 0 2px;
+ border: 1px solid #c0c0c0;
+}
+legend {
+ padding: 0;
+ border: 0;
+}
+textarea {
+ overflow: auto;
+}
+optgroup {
+ font-weight: bold;
+}
+table {
+ border-spacing: 0;
+ border-collapse: collapse;
+}
+td,
+th {
+ padding: 0;
+}
+/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
+@media print {
+ *,
+ *:before,
+ *:after {
+ color: #000 !important;
+ text-shadow: none !important;
+ background: transparent !important;
+ -webkit-box-shadow: none !important;
+ box-shadow: none !important;
+ }
+ a,
+ a:visited {
+ text-decoration: underline;
+ }
+ a[href]:after {
+ content: " (" attr(href) ")";
+ }
+ abbr[title]:after {
+ content: " (" attr(title) ")";
+ }
+ a[href^="#"]:after,
+ a[href^="javascript:"]:after {
+ content: "";
+ }
+ pre,
+ blockquote {
+ border: 1px solid #999;
+
+ page-break-inside: avoid;
+ }
+ thead {
+ display: table-header-group;
+ }
+ tr,
+ img {
+ page-break-inside: avoid;
+ }
+ img {
+ max-width: 100% !important;
+ }
+ p,
+ h2,
+ h3 {
+ orphans: 3;
+ widows: 3;
+ }
+ h2,
+ h3 {
+ page-break-after: avoid;
+ }
+ select {
+ background: #fff !important;
+ }
+ .navbar {
+ display: none;
+ }
+ .btn > .caret,
+ .dropup > .btn > .caret {
+ border-top-color: #000 !important;
+ }
+ .label {
+ border: 1px solid #000;
+ }
+ .table {
+ border-collapse: collapse !important;
+ }
+ .table td,
+ .table th {
+ background-color: #fff !important;
+ }
+ .table-bordered th,
+ .table-bordered td {
+ border: 1px solid #ddd !important;
+ }
+}
+@font-face {
+ font-family: 'Glyphicons Halflings';
+
+ src: url('../fonts/glyphicons-halflings-regular.eot');
+ src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+}
+.glyphicon {
+ position: relative;
+ top: 1px;
+ display: inline-block;
+ font-family: 'Glyphicons Halflings';
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1;
+
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.glyphicon-asterisk:before {
+ content: "\2a";
+}
+.glyphicon-plus:before {
+ content: "\2b";
+}
+.glyphicon-euro:before,
+.glyphicon-eur:before {
+ content: "\20ac";
+}
+.glyphicon-minus:before {
+ content: "\2212";
+}
+.glyphicon-cloud:before {
+ content: "\2601";
+}
+.glyphicon-envelope:before {
+ content: "\2709";
+}
+.glyphicon-pencil:before {
+ content: "\270f";
+}
+.glyphicon-glass:before {
+ content: "\e001";
+}
+.glyphicon-music:before {
+ content: "\e002";
+}
+.glyphicon-search:before {
+ content: "\e003";
+}
+.glyphicon-heart:before {
+ content: "\e005";
+}
+.glyphicon-star:before {
+ content: "\e006";
+}
+.glyphicon-star-empty:before {
+ content: "\e007";
+}
+.glyphicon-user:before {
+ content: "\e008";
+}
+.glyphicon-film:before {
+ content: "\e009";
+}
+.glyphicon-th-large:before {
+ content: "\e010";
+}
+.glyphicon-th:before {
+ content: "\e011";
+}
+.glyphicon-th-list:before {
+ content: "\e012";
+}
+.glyphicon-ok:before {
+ content: "\e013";
+}
+.glyphicon-remove:before {
+ content: "\e014";
+}
+.glyphicon-zoom-in:before {
+ content: "\e015";
+}
+.glyphicon-zoom-out:before {
+ content: "\e016";
+}
+.glyphicon-off:before {
+ content: "\e017";
+}
+.glyphicon-signal:before {
+ content: "\e018";
+}
+.glyphicon-cog:before {
+ content: "\e019";
+}
+.glyphicon-trash:before {
+ content: "\e020";
+}
+.glyphicon-home:before {
+ content: "\e021";
+}
+.glyphicon-file:before {
+ content: "\e022";
+}
+.glyphicon-time:before {
+ content: "\e023";
+}
+.glyphicon-road:before {
+ content: "\e024";
+}
+.glyphicon-download-alt:before {
+ content: "\e025";
+}
+.glyphicon-download:before {
+ content: "\e026";
+}
+.glyphicon-upload:before {
+ content: "\e027";
+}
+.glyphicon-inbox:before {
+ content: "\e028";
+}
+.glyphicon-play-circle:before {
+ content: "\e029";
+}
+.glyphicon-repeat:before {
+ content: "\e030";
+}
+.glyphicon-refresh:before {
+ content: "\e031";
+}
+.glyphicon-list-alt:before {
+ content: "\e032";
+}
+.glyphicon-lock:before {
+ content: "\e033";
+}
+.glyphicon-flag:before {
+ content: "\e034";
+}
+.glyphicon-headphones:before {
+ content: "\e035";
+}
+.glyphicon-volume-off:before {
+ content: "\e036";
+}
+.glyphicon-volume-down:before {
+ content: "\e037";
+}
+.glyphicon-volume-up:before {
+ content: "\e038";
+}
+.glyphicon-qrcode:before {
+ content: "\e039";
+}
+.glyphicon-barcode:before {
+ content: "\e040";
+}
+.glyphicon-tag:before {
+ content: "\e041";
+}
+.glyphicon-tags:before {
+ content: "\e042";
+}
+.glyphicon-book:before {
+ content: "\e043";
+}
+.glyphicon-bookmark:before {
+ content: "\e044";
+}
+.glyphicon-print:before {
+ content: "\e045";
+}
+.glyphicon-camera:before {
+ content: "\e046";
+}
+.glyphicon-font:before {
+ content: "\e047";
+}
+.glyphicon-bold:before {
+ content: "\e048";
+}
+.glyphicon-italic:before {
+ content: "\e049";
+}
+.glyphicon-text-height:before {
+ content: "\e050";
+}
+.glyphicon-text-width:before {
+ content: "\e051";
+}
+.glyphicon-align-left:before {
+ content: "\e052";
+}
+.glyphicon-align-center:before {
+ content: "\e053";
+}
+.glyphicon-align-right:before {
+ content: "\e054";
+}
+.glyphicon-align-justify:before {
+ content: "\e055";
+}
+.glyphicon-list:before {
+ content: "\e056";
+}
+.glyphicon-indent-left:before {
+ content: "\e057";
+}
+.glyphicon-indent-right:before {
+ content: "\e058";
+}
+.glyphicon-facetime-video:before {
+ content: "\e059";
+}
+.glyphicon-picture:before {
+ content: "\e060";
+}
+.glyphicon-map-marker:before {
+ content: "\e062";
+}
+.glyphicon-adjust:before {
+ content: "\e063";
+}
+.glyphicon-tint:before {
+ content: "\e064";
+}
+.glyphicon-edit:before {
+ content: "\e065";
+}
+.glyphicon-share:before {
+ content: "\e066";
+}
+.glyphicon-check:before {
+ content: "\e067";
+}
+.glyphicon-move:before {
+ content: "\e068";
+}
+.glyphicon-step-backward:before {
+ content: "\e069";
+}
+.glyphicon-fast-backward:before {
+ content: "\e070";
+}
+.glyphicon-backward:before {
+ content: "\e071";
+}
+.glyphicon-play:before {
+ content: "\e072";
+}
+.glyphicon-pause:before {
+ content: "\e073";
+}
+.glyphicon-stop:before {
+ content: "\e074";
+}
+.glyphicon-forward:before {
+ content: "\e075";
+}
+.glyphicon-fast-forward:before {
+ content: "\e076";
+}
+.glyphicon-step-forward:before {
+ content: "\e077";
+}
+.glyphicon-eject:before {
+ content: "\e078";
+}
+.glyphicon-chevron-left:before {
+ content: "\e079";
+}
+.glyphicon-chevron-right:before {
+ content: "\e080";
+}
+.glyphicon-plus-sign:before {
+ content: "\e081";
+}
+.glyphicon-minus-sign:before {
+ content: "\e082";
+}
+.glyphicon-remove-sign:before {
+ content: "\e083";
+}
+.glyphicon-ok-sign:before {
+ content: "\e084";
+}
+.glyphicon-question-sign:before {
+ content: "\e085";
+}
+.glyphicon-info-sign:before {
+ content: "\e086";
+}
+.glyphicon-screenshot:before {
+ content: "\e087";
+}
+.glyphicon-remove-circle:before {
+ content: "\e088";
+}
+.glyphicon-ok-circle:before {
+ content: "\e089";
+}
+.glyphicon-ban-circle:before {
+ content: "\e090";
+}
+.glyphicon-arrow-left:before {
+ content: "\e091";
+}
+.glyphicon-arrow-right:before {
+ content: "\e092";
+}
+.glyphicon-arrow-up:before {
+ content: "\e093";
+}
+.glyphicon-arrow-down:before {
+ content: "\e094";
+}
+.glyphicon-share-alt:before {
+ content: "\e095";
+}
+.glyphicon-resize-full:before {
+ content: "\e096";
+}
+.glyphicon-resize-small:before {
+ content: "\e097";
+}
+.glyphicon-exclamation-sign:before {
+ content: "\e101";
+}
+.glyphicon-gift:before {
+ content: "\e102";
+}
+.glyphicon-leaf:before {
+ content: "\e103";
+}
+.glyphicon-fire:before {
+ content: "\e104";
+}
+.glyphicon-eye-open:before {
+ content: "\e105";
+}
+.glyphicon-eye-close:before {
+ content: "\e106";
+}
+.glyphicon-warning-sign:before {
+ content: "\e107";
+}
+.glyphicon-plane:before {
+ content: "\e108";
+}
+.glyphicon-calendar:before {
+ content: "\e109";
+}
+.glyphicon-random:before {
+ content: "\e110";
+}
+.glyphicon-comment:before {
+ content: "\e111";
+}
+.glyphicon-magnet:before {
+ content: "\e112";
+}
+.glyphicon-chevron-up:before {
+ content: "\e113";
+}
+.glyphicon-chevron-down:before {
+ content: "\e114";
+}
+.glyphicon-retweet:before {
+ content: "\e115";
+}
+.glyphicon-shopping-cart:before {
+ content: "\e116";
+}
+.glyphicon-folder-close:before {
+ content: "\e117";
+}
+.glyphicon-folder-open:before {
+ content: "\e118";
+}
+.glyphicon-resize-vertical:before {
+ content: "\e119";
+}
+.glyphicon-resize-horizontal:before {
+ content: "\e120";
+}
+.glyphicon-hdd:before {
+ content: "\e121";
+}
+.glyphicon-bullhorn:before {
+ content: "\e122";
+}
+.glyphicon-bell:before {
+ content: "\e123";
+}
+.glyphicon-certificate:before {
+ content: "\e124";
+}
+.glyphicon-thumbs-up:before {
+ content: "\e125";
+}
+.glyphicon-thumbs-down:before {
+ content: "\e126";
+}
+.glyphicon-hand-right:before {
+ content: "\e127";
+}
+.glyphicon-hand-left:before {
+ content: "\e128";
+}
+.glyphicon-hand-up:before {
+ content: "\e129";
+}
+.glyphicon-hand-down:before {
+ content: "\e130";
+}
+.glyphicon-circle-arrow-right:before {
+ content: "\e131";
+}
+.glyphicon-circle-arrow-left:before {
+ content: "\e132";
+}
+.glyphicon-circle-arrow-up:before {
+ content: "\e133";
+}
+.glyphicon-circle-arrow-down:before {
+ content: "\e134";
+}
+.glyphicon-globe:before {
+ content: "\e135";
+}
+.glyphicon-wrench:before {
+ content: "\e136";
+}
+.glyphicon-tasks:before {
+ content: "\e137";
+}
+.glyphicon-filter:before {
+ content: "\e138";
+}
+.glyphicon-briefcase:before {
+ content: "\e139";
+}
+.glyphicon-fullscreen:before {
+ content: "\e140";
+}
+.glyphicon-dashboard:before {
+ content: "\e141";
+}
+.glyphicon-paperclip:before {
+ content: "\e142";
+}
+.glyphicon-heart-empty:before {
+ content: "\e143";
+}
+.glyphicon-link:before {
+ content: "\e144";
+}
+.glyphicon-phone:before {
+ content: "\e145";
+}
+.glyphicon-pushpin:before {
+ content: "\e146";
+}
+.glyphicon-usd:before {
+ content: "\e148";
+}
+.glyphicon-gbp:before {
+ content: "\e149";
+}
+.glyphicon-sort:before {
+ content: "\e150";
+}
+.glyphicon-sort-by-alphabet:before {
+ content: "\e151";
+}
+.glyphicon-sort-by-alphabet-alt:before {
+ content: "\e152";
+}
+.glyphicon-sort-by-order:before {
+ content: "\e153";
+}
+.glyphicon-sort-by-order-alt:before {
+ content: "\e154";
+}
+.glyphicon-sort-by-attributes:before {
+ content: "\e155";
+}
+.glyphicon-sort-by-attributes-alt:before {
+ content: "\e156";
+}
+.glyphicon-unchecked:before {
+ content: "\e157";
+}
+.glyphicon-expand:before {
+ content: "\e158";
+}
+.glyphicon-collapse-down:before {
+ content: "\e159";
+}
+.glyphicon-collapse-up:before {
+ content: "\e160";
+}
+.glyphicon-log-in:before {
+ content: "\e161";
+}
+.glyphicon-flash:before {
+ content: "\e162";
+}
+.glyphicon-log-out:before {
+ content: "\e163";
+}
+.glyphicon-new-window:before {
+ content: "\e164";
+}
+.glyphicon-record:before {
+ content: "\e165";
+}
+.glyphicon-save:before {
+ content: "\e166";
+}
+.glyphicon-open:before {
+ content: "\e167";
+}
+.glyphicon-saved:before {
+ content: "\e168";
+}
+.glyphicon-import:before {
+ content: "\e169";
+}
+.glyphicon-export:before {
+ content: "\e170";
+}
+.glyphicon-send:before {
+ content: "\e171";
+}
+.glyphicon-floppy-disk:before {
+ content: "\e172";
+}
+.glyphicon-floppy-saved:before {
+ content: "\e173";
+}
+.glyphicon-floppy-remove:before {
+ content: "\e174";
+}
+.glyphicon-floppy-save:before {
+ content: "\e175";
+}
+.glyphicon-floppy-open:before {
+ content: "\e176";
+}
+.glyphicon-credit-card:before {
+ content: "\e177";
+}
+.glyphicon-transfer:before {
+ content: "\e178";
+}
+.glyphicon-cutlery:before {
+ content: "\e179";
+}
+.glyphicon-header:before {
+ content: "\e180";
+}
+.glyphicon-compressed:before {
+ content: "\e181";
+}
+.glyphicon-earphone:before {
+ content: "\e182";
+}
+.glyphicon-phone-alt:before {
+ content: "\e183";
+}
+.glyphicon-tower:before {
+ content: "\e184";
+}
+.glyphicon-stats:before {
+ content: "\e185";
+}
+.glyphicon-sd-video:before {
+ content: "\e186";
+}
+.glyphicon-hd-video:before {
+ content: "\e187";
+}
+.glyphicon-subtitles:before {
+ content: "\e188";
+}
+.glyphicon-sound-stereo:before {
+ content: "\e189";
+}
+.glyphicon-sound-dolby:before {
+ content: "\e190";
+}
+.glyphicon-sound-5-1:before {
+ content: "\e191";
+}
+.glyphicon-sound-6-1:before {
+ content: "\e192";
+}
+.glyphicon-sound-7-1:before {
+ content: "\e193";
+}
+.glyphicon-copyright-mark:before {
+ content: "\e194";
+}
+.glyphicon-registration-mark:before {
+ content: "\e195";
+}
+.glyphicon-cloud-download:before {
+ content: "\e197";
+}
+.glyphicon-cloud-upload:before {
+ content: "\e198";
+}
+.glyphicon-tree-conifer:before {
+ content: "\e199";
+}
+.glyphicon-tree-deciduous:before {
+ content: "\e200";
+}
+* {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+*:before,
+*:after {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+html {
+ font-size: 10px;
+
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+body {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #333;
+ background-color: #fff;
+}
+input,
+button,
+select,
+textarea {
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+a {
+ color: #428bca;
+ text-decoration: none;
+}
+a:hover,
+a:focus {
+ color: #2a6496;
+ text-decoration: underline;
+}
+a:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+figure {
+ margin: 0;
+}
+img {
+ vertical-align: middle;
+}
+.img-responsive,
+.thumbnail > img,
+.thumbnail a > img,
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+}
+.img-rounded {
+ border-radius: 6px;
+}
+.img-thumbnail {
+ display: inline-block;
+ max-width: 100%;
+ height: auto;
+ padding: 4px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ -webkit-transition: all .2s ease-in-out;
+ -o-transition: all .2s ease-in-out;
+ transition: all .2s ease-in-out;
+}
+.img-circle {
+ border-radius: 50%;
+}
+hr {
+ margin-top: 20px;
+ margin-bottom: 20px;
+ border: 0;
+ border-top: 1px solid #eee;
+}
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0;
+}
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6 {
+ font-family: inherit;
+ font-weight: 500;
+ line-height: 1.1;
+ color: inherit;
+}
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small,
+.h1 small,
+.h2 small,
+.h3 small,
+.h4 small,
+.h5 small,
+.h6 small,
+h1 .small,
+h2 .small,
+h3 .small,
+h4 .small,
+h5 .small,
+h6 .small,
+.h1 .small,
+.h2 .small,
+.h3 .small,
+.h4 .small,
+.h5 .small,
+.h6 .small {
+ font-weight: normal;
+ line-height: 1;
+ color: #777;
+}
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3 {
+ margin-top: 20px;
+ margin-bottom: 10px;
+}
+h1 small,
+.h1 small,
+h2 small,
+.h2 small,
+h3 small,
+.h3 small,
+h1 .small,
+.h1 .small,
+h2 .small,
+.h2 .small,
+h3 .small,
+.h3 .small {
+ font-size: 65%;
+}
+h4,
+.h4,
+h5,
+.h5,
+h6,
+.h6 {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+h4 small,
+.h4 small,
+h5 small,
+.h5 small,
+h6 small,
+.h6 small,
+h4 .small,
+.h4 .small,
+h5 .small,
+.h5 .small,
+h6 .small,
+.h6 .small {
+ font-size: 75%;
+}
+h1,
+.h1 {
+ font-size: 36px;
+}
+h2,
+.h2 {
+ font-size: 30px;
+}
+h3,
+.h3 {
+ font-size: 24px;
+}
+h4,
+.h4 {
+ font-size: 18px;
+}
+h5,
+.h5 {
+ font-size: 14px;
+}
+h6,
+.h6 {
+ font-size: 12px;
+}
+p {
+ margin: 0 0 10px;
+}
+.lead {
+ margin-bottom: 20px;
+ font-size: 16px;
+ font-weight: 300;
+ line-height: 1.4;
+}
+@media (min-width: 768px) {
+ .lead {
+ font-size: 21px;
+ }
+}
+small,
+.small {
+ font-size: 85%;
+}
+mark,
+.mark {
+ padding: .2em;
+ background-color: #fcf8e3;
+}
+.text-left {
+ text-align: left;
+}
+.text-right {
+ text-align: right;
+}
+.text-center {
+ text-align: center;
+}
+.text-justify {
+ text-align: justify;
+}
+.text-nowrap {
+ white-space: nowrap;
+}
+.text-lowercase {
+ text-transform: lowercase;
+}
+.text-uppercase {
+ text-transform: uppercase;
+}
+.text-capitalize {
+ text-transform: capitalize;
+}
+.text-muted {
+ color: #777;
+}
+.text-primary {
+ color: #428bca;
+}
+a.text-primary:hover {
+ color: #3071a9;
+}
+.text-success {
+ color: #3c763d;
+}
+a.text-success:hover {
+ color: #2b542c;
+}
+.text-info {
+ color: #31708f;
+}
+a.text-info:hover {
+ color: #245269;
+}
+.text-warning {
+ color: #8a6d3b;
+}
+a.text-warning:hover {
+ color: #66512c;
+}
+.text-danger {
+ color: #a94442;
+}
+a.text-danger:hover {
+ color: #843534;
+}
+.bg-primary {
+ color: #fff;
+ background-color: #428bca;
+}
+a.bg-primary:hover {
+ background-color: #3071a9;
+}
+.bg-success {
+ background-color: #dff0d8;
+}
+a.bg-success:hover {
+ background-color: #c1e2b3;
+}
+.bg-info {
+ background-color: #d9edf7;
+}
+a.bg-info:hover {
+ background-color: #afd9ee;
+}
+.bg-warning {
+ background-color: #fcf8e3;
+}
+a.bg-warning:hover {
+ background-color: #f7ecb5;
+}
+.bg-danger {
+ background-color: #f2dede;
+}
+a.bg-danger:hover {
+ background-color: #e4b9b9;
+}
+.page-header {
+ padding-bottom: 9px;
+ margin: 40px 0 20px;
+ border-bottom: 1px solid #eee;
+}
+ul,
+ol {
+ margin-top: 0;
+ margin-bottom: 10px;
+}
+ul ul,
+ol ul,
+ul ol,
+ol ol {
+ margin-bottom: 0;
+}
+.list-unstyled {
+ padding-left: 0;
+ list-style: none;
+}
+.list-inline {
+ padding-left: 0;
+ margin-left: -5px;
+ list-style: none;
+}
+.list-inline > li {
+ display: inline-block;
+ padding-right: 5px;
+ padding-left: 5px;
+}
+dl {
+ margin-top: 0;
+ margin-bottom: 20px;
+}
+dt,
+dd {
+ line-height: 1.42857143;
+}
+dt {
+ font-weight: bold;
+}
+dd {
+ margin-left: 0;
+}
+@media (min-width: 768px) {
+ .dl-horizontal dt {
+ float: left;
+ width: 160px;
+ overflow: hidden;
+ clear: left;
+ text-align: right;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+ .dl-horizontal dd {
+ margin-left: 180px;
+ }
+}
+abbr[title],
+abbr[data-original-title] {
+ cursor: help;
+ border-bottom: 1px dotted #777;
+}
+.initialism {
+ font-size: 90%;
+ text-transform: uppercase;
+}
+blockquote {
+ padding: 10px 20px;
+ margin: 0 0 20px;
+ font-size: 17.5px;
+ border-left: 5px solid #eee;
+}
+blockquote p:last-child,
+blockquote ul:last-child,
+blockquote ol:last-child {
+ margin-bottom: 0;
+}
+blockquote footer,
+blockquote small,
+blockquote .small {
+ display: block;
+ font-size: 80%;
+ line-height: 1.42857143;
+ color: #777;
+}
+blockquote footer:before,
+blockquote small:before,
+blockquote .small:before {
+ content: '\2014 \00A0';
+}
+.blockquote-reverse,
+blockquote.pull-right {
+ padding-right: 15px;
+ padding-left: 0;
+ text-align: right;
+ border-right: 5px solid #eee;
+ border-left: 0;
+}
+.blockquote-reverse footer:before,
+blockquote.pull-right footer:before,
+.blockquote-reverse small:before,
+blockquote.pull-right small:before,
+.blockquote-reverse .small:before,
+blockquote.pull-right .small:before {
+ content: '';
+}
+.blockquote-reverse footer:after,
+blockquote.pull-right footer:after,
+.blockquote-reverse small:after,
+blockquote.pull-right small:after,
+.blockquote-reverse .small:after,
+blockquote.pull-right .small:after {
+ content: '\00A0 \2014';
+}
+address {
+ margin-bottom: 20px;
+ font-style: normal;
+ line-height: 1.42857143;
+}
+code,
+kbd,
+pre,
+samp {
+ font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+}
+code {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #c7254e;
+ background-color: #f9f2f4;
+ border-radius: 4px;
+}
+kbd {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #fff;
+ background-color: #333;
+ border-radius: 3px;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+}
+kbd kbd {
+ padding: 0;
+ font-size: 100%;
+ font-weight: bold;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+pre {
+ display: block;
+ padding: 9.5px;
+ margin: 0 0 10px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ color: #333;
+ word-break: break-all;
+ word-wrap: break-word;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+}
+pre code {
+ padding: 0;
+ font-size: inherit;
+ color: inherit;
+ white-space: pre-wrap;
+ background-color: transparent;
+ border-radius: 0;
+}
+.pre-scrollable {
+ max-height: 340px;
+ overflow-y: scroll;
+}
+.container {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto;
+}
+@media (min-width: 768px) {
+ .container {
+ width: 750px;
+ }
+}
+@media (min-width: 992px) {
+ .container {
+ width: 970px;
+ }
+}
+@media (min-width: 1200px) {
+ .container {
+ width: 1170px;
+ }
+}
+.container-fluid {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto;
+}
+.row {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
+ position: relative;
+ min-height: 1px;
+ padding-right: 15px;
+ padding-left: 15px;
+}
+.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
+ float: left;
+}
+.col-xs-12 {
+ width: 100%;
+}
+.col-xs-11 {
+ width: 91.66666667%;
+}
+.col-xs-10 {
+ width: 83.33333333%;
+}
+.col-xs-9 {
+ width: 75%;
+}
+.col-xs-8 {
+ width: 66.66666667%;
+}
+.col-xs-7 {
+ width: 58.33333333%;
+}
+.col-xs-6 {
+ width: 50%;
+}
+.col-xs-5 {
+ width: 41.66666667%;
+}
+.col-xs-4 {
+ width: 33.33333333%;
+}
+.col-xs-3 {
+ width: 25%;
+}
+.col-xs-2 {
+ width: 16.66666667%;
+}
+.col-xs-1 {
+ width: 8.33333333%;
+}
+.col-xs-pull-12 {
+ right: 100%;
+}
+.col-xs-pull-11 {
+ right: 91.66666667%;
+}
+.col-xs-pull-10 {
+ right: 83.33333333%;
+}
+.col-xs-pull-9 {
+ right: 75%;
+}
+.col-xs-pull-8 {
+ right: 66.66666667%;
+}
+.col-xs-pull-7 {
+ right: 58.33333333%;
+}
+.col-xs-pull-6 {
+ right: 50%;
+}
+.col-xs-pull-5 {
+ right: 41.66666667%;
+}
+.col-xs-pull-4 {
+ right: 33.33333333%;
+}
+.col-xs-pull-3 {
+ right: 25%;
+}
+.col-xs-pull-2 {
+ right: 16.66666667%;
+}
+.col-xs-pull-1 {
+ right: 8.33333333%;
+}
+.col-xs-pull-0 {
+ right: auto;
+}
+.col-xs-push-12 {
+ left: 100%;
+}
+.col-xs-push-11 {
+ left: 91.66666667%;
+}
+.col-xs-push-10 {
+ left: 83.33333333%;
+}
+.col-xs-push-9 {
+ left: 75%;
+}
+.col-xs-push-8 {
+ left: 66.66666667%;
+}
+.col-xs-push-7 {
+ left: 58.33333333%;
+}
+.col-xs-push-6 {
+ left: 50%;
+}
+.col-xs-push-5 {
+ left: 41.66666667%;
+}
+.col-xs-push-4 {
+ left: 33.33333333%;
+}
+.col-xs-push-3 {
+ left: 25%;
+}
+.col-xs-push-2 {
+ left: 16.66666667%;
+}
+.col-xs-push-1 {
+ left: 8.33333333%;
+}
+.col-xs-push-0 {
+ left: auto;
+}
+.col-xs-offset-12 {
+ margin-left: 100%;
+}
+.col-xs-offset-11 {
+ margin-left: 91.66666667%;
+}
+.col-xs-offset-10 {
+ margin-left: 83.33333333%;
+}
+.col-xs-offset-9 {
+ margin-left: 75%;
+}
+.col-xs-offset-8 {
+ margin-left: 66.66666667%;
+}
+.col-xs-offset-7 {
+ margin-left: 58.33333333%;
+}
+.col-xs-offset-6 {
+ margin-left: 50%;
+}
+.col-xs-offset-5 {
+ margin-left: 41.66666667%;
+}
+.col-xs-offset-4 {
+ margin-left: 33.33333333%;
+}
+.col-xs-offset-3 {
+ margin-left: 25%;
+}
+.col-xs-offset-2 {
+ margin-left: 16.66666667%;
+}
+.col-xs-offset-1 {
+ margin-left: 8.33333333%;
+}
+.col-xs-offset-0 {
+ margin-left: 0;
+}
+@media (min-width: 768px) {
+ .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
+ float: left;
+ }
+ .col-sm-12 {
+ width: 100%;
+ }
+ .col-sm-11 {
+ width: 91.66666667%;
+ }
+ .col-sm-10 {
+ width: 83.33333333%;
+ }
+ .col-sm-9 {
+ width: 75%;
+ }
+ .col-sm-8 {
+ width: 66.66666667%;
+ }
+ .col-sm-7 {
+ width: 58.33333333%;
+ }
+ .col-sm-6 {
+ width: 50%;
+ }
+ .col-sm-5 {
+ width: 41.66666667%;
+ }
+ .col-sm-4 {
+ width: 33.33333333%;
+ }
+ .col-sm-3 {
+ width: 25%;
+ }
+ .col-sm-2 {
+ width: 16.66666667%;
+ }
+ .col-sm-1 {
+ width: 8.33333333%;
+ }
+ .col-sm-pull-12 {
+ right: 100%;
+ }
+ .col-sm-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-sm-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-sm-pull-9 {
+ right: 75%;
+ }
+ .col-sm-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-sm-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-sm-pull-6 {
+ right: 50%;
+ }
+ .col-sm-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-sm-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-sm-pull-3 {
+ right: 25%;
+ }
+ .col-sm-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-sm-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-sm-pull-0 {
+ right: auto;
+ }
+ .col-sm-push-12 {
+ left: 100%;
+ }
+ .col-sm-push-11 {
+ left: 91.66666667%;
+ }
+ .col-sm-push-10 {
+ left: 83.33333333%;
+ }
+ .col-sm-push-9 {
+ left: 75%;
+ }
+ .col-sm-push-8 {
+ left: 66.66666667%;
+ }
+ .col-sm-push-7 {
+ left: 58.33333333%;
+ }
+ .col-sm-push-6 {
+ left: 50%;
+ }
+ .col-sm-push-5 {
+ left: 41.66666667%;
+ }
+ .col-sm-push-4 {
+ left: 33.33333333%;
+ }
+ .col-sm-push-3 {
+ left: 25%;
+ }
+ .col-sm-push-2 {
+ left: 16.66666667%;
+ }
+ .col-sm-push-1 {
+ left: 8.33333333%;
+ }
+ .col-sm-push-0 {
+ left: auto;
+ }
+ .col-sm-offset-12 {
+ margin-left: 100%;
+ }
+ .col-sm-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-sm-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-sm-offset-9 {
+ margin-left: 75%;
+ }
+ .col-sm-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-sm-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-sm-offset-6 {
+ margin-left: 50%;
+ }
+ .col-sm-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-sm-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-sm-offset-3 {
+ margin-left: 25%;
+ }
+ .col-sm-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-sm-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-sm-offset-0 {
+ margin-left: 0;
+ }
+}
+@media (min-width: 992px) {
+ .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
+ float: left;
+ }
+ .col-md-12 {
+ width: 100%;
+ }
+ .col-md-11 {
+ width: 91.66666667%;
+ }
+ .col-md-10 {
+ width: 83.33333333%;
+ }
+ .col-md-9 {
+ width: 75%;
+ }
+ .col-md-8 {
+ width: 66.66666667%;
+ }
+ .col-md-7 {
+ width: 58.33333333%;
+ }
+ .col-md-6 {
+ width: 50%;
+ }
+ .col-md-5 {
+ width: 41.66666667%;
+ }
+ .col-md-4 {
+ width: 33.33333333%;
+ }
+ .col-md-3 {
+ width: 25%;
+ }
+ .col-md-2 {
+ width: 16.66666667%;
+ }
+ .col-md-1 {
+ width: 8.33333333%;
+ }
+ .col-md-pull-12 {
+ right: 100%;
+ }
+ .col-md-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-md-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-md-pull-9 {
+ right: 75%;
+ }
+ .col-md-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-md-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-md-pull-6 {
+ right: 50%;
+ }
+ .col-md-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-md-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-md-pull-3 {
+ right: 25%;
+ }
+ .col-md-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-md-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-md-pull-0 {
+ right: auto;
+ }
+ .col-md-push-12 {
+ left: 100%;
+ }
+ .col-md-push-11 {
+ left: 91.66666667%;
+ }
+ .col-md-push-10 {
+ left: 83.33333333%;
+ }
+ .col-md-push-9 {
+ left: 75%;
+ }
+ .col-md-push-8 {
+ left: 66.66666667%;
+ }
+ .col-md-push-7 {
+ left: 58.33333333%;
+ }
+ .col-md-push-6 {
+ left: 50%;
+ }
+ .col-md-push-5 {
+ left: 41.66666667%;
+ }
+ .col-md-push-4 {
+ left: 33.33333333%;
+ }
+ .col-md-push-3 {
+ left: 25%;
+ }
+ .col-md-push-2 {
+ left: 16.66666667%;
+ }
+ .col-md-push-1 {
+ left: 8.33333333%;
+ }
+ .col-md-push-0 {
+ left: auto;
+ }
+ .col-md-offset-12 {
+ margin-left: 100%;
+ }
+ .col-md-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-md-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-md-offset-9 {
+ margin-left: 75%;
+ }
+ .col-md-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-md-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-md-offset-6 {
+ margin-left: 50%;
+ }
+ .col-md-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-md-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-md-offset-3 {
+ margin-left: 25%;
+ }
+ .col-md-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-md-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-md-offset-0 {
+ margin-left: 0;
+ }
+}
+@media (min-width: 1200px) {
+ .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
+ float: left;
+ }
+ .col-lg-12 {
+ width: 100%;
+ }
+ .col-lg-11 {
+ width: 91.66666667%;
+ }
+ .col-lg-10 {
+ width: 83.33333333%;
+ }
+ .col-lg-9 {
+ width: 75%;
+ }
+ .col-lg-8 {
+ width: 66.66666667%;
+ }
+ .col-lg-7 {
+ width: 58.33333333%;
+ }
+ .col-lg-6 {
+ width: 50%;
+ }
+ .col-lg-5 {
+ width: 41.66666667%;
+ }
+ .col-lg-4 {
+ width: 33.33333333%;
+ }
+ .col-lg-3 {
+ width: 25%;
+ }
+ .col-lg-2 {
+ width: 16.66666667%;
+ }
+ .col-lg-1 {
+ width: 8.33333333%;
+ }
+ .col-lg-pull-12 {
+ right: 100%;
+ }
+ .col-lg-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-lg-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-lg-pull-9 {
+ right: 75%;
+ }
+ .col-lg-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-lg-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-lg-pull-6 {
+ right: 50%;
+ }
+ .col-lg-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-lg-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-lg-pull-3 {
+ right: 25%;
+ }
+ .col-lg-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-lg-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-lg-pull-0 {
+ right: auto;
+ }
+ .col-lg-push-12 {
+ left: 100%;
+ }
+ .col-lg-push-11 {
+ left: 91.66666667%;
+ }
+ .col-lg-push-10 {
+ left: 83.33333333%;
+ }
+ .col-lg-push-9 {
+ left: 75%;
+ }
+ .col-lg-push-8 {
+ left: 66.66666667%;
+ }
+ .col-lg-push-7 {
+ left: 58.33333333%;
+ }
+ .col-lg-push-6 {
+ left: 50%;
+ }
+ .col-lg-push-5 {
+ left: 41.66666667%;
+ }
+ .col-lg-push-4 {
+ left: 33.33333333%;
+ }
+ .col-lg-push-3 {
+ left: 25%;
+ }
+ .col-lg-push-2 {
+ left: 16.66666667%;
+ }
+ .col-lg-push-1 {
+ left: 8.33333333%;
+ }
+ .col-lg-push-0 {
+ left: auto;
+ }
+ .col-lg-offset-12 {
+ margin-left: 100%;
+ }
+ .col-lg-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-lg-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-lg-offset-9 {
+ margin-left: 75%;
+ }
+ .col-lg-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-lg-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-lg-offset-6 {
+ margin-left: 50%;
+ }
+ .col-lg-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-lg-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-lg-offset-3 {
+ margin-left: 25%;
+ }
+ .col-lg-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-lg-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-lg-offset-0 {
+ margin-left: 0;
+ }
+}
+table {
+ background-color: transparent;
+}
+caption {
+ padding-top: 8px;
+ padding-bottom: 8px;
+ color: #777;
+ text-align: left;
+}
+th {
+ text-align: left;
+}
+.table {
+ width: 100%;
+ max-width: 100%;
+ margin-bottom: 20px;
+}
+.table > thead > tr > th,
+.table > tbody > tr > th,
+.table > tfoot > tr > th,
+.table > thead > tr > td,
+.table > tbody > tr > td,
+.table > tfoot > tr > td {
+ padding: 8px;
+ line-height: 1.42857143;
+ vertical-align: top;
+ border-top: 1px solid #ddd;
+}
+.table > thead > tr > th {
+ vertical-align: bottom;
+ border-bottom: 2px solid #ddd;
+}
+.table > caption + thead > tr:first-child > th,
+.table > colgroup + thead > tr:first-child > th,
+.table > thead:first-child > tr:first-child > th,
+.table > caption + thead > tr:first-child > td,
+.table > colgroup + thead > tr:first-child > td,
+.table > thead:first-child > tr:first-child > td {
+ border-top: 0;
+}
+.table > tbody + tbody {
+ border-top: 2px solid #ddd;
+}
+.table .table {
+ background-color: #fff;
+}
+.table-condensed > thead > tr > th,
+.table-condensed > tbody > tr > th,
+.table-condensed > tfoot > tr > th,
+.table-condensed > thead > tr > td,
+.table-condensed > tbody > tr > td,
+.table-condensed > tfoot > tr > td {
+ padding: 5px;
+}
+.table-bordered {
+ border: 1px solid #ddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > tbody > tr > th,
+.table-bordered > tfoot > tr > th,
+.table-bordered > thead > tr > td,
+.table-bordered > tbody > tr > td,
+.table-bordered > tfoot > tr > td {
+ border: 1px solid #ddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > thead > tr > td {
+ border-bottom-width: 2px;
+}
+.table-striped > tbody > tr:nth-child(odd) {
+ background-color: #f9f9f9;
+}
+.table-hover > tbody > tr:hover {
+ background-color: #f5f5f5;
+}
+table col[class*="col-"] {
+ position: static;
+ display: table-column;
+ float: none;
+}
+table td[class*="col-"],
+table th[class*="col-"] {
+ position: static;
+ display: table-cell;
+ float: none;
+}
+.table > thead > tr > td.active,
+.table > tbody > tr > td.active,
+.table > tfoot > tr > td.active,
+.table > thead > tr > th.active,
+.table > tbody > tr > th.active,
+.table > tfoot > tr > th.active,
+.table > thead > tr.active > td,
+.table > tbody > tr.active > td,
+.table > tfoot > tr.active > td,
+.table > thead > tr.active > th,
+.table > tbody > tr.active > th,
+.table > tfoot > tr.active > th {
+ background-color: #f5f5f5;
+}
+.table-hover > tbody > tr > td.active:hover,
+.table-hover > tbody > tr > th.active:hover,
+.table-hover > tbody > tr.active:hover > td,
+.table-hover > tbody > tr:hover > .active,
+.table-hover > tbody > tr.active:hover > th {
+ background-color: #e8e8e8;
+}
+.table > thead > tr > td.success,
+.table > tbody > tr > td.success,
+.table > tfoot > tr > td.success,
+.table > thead > tr > th.success,
+.table > tbody > tr > th.success,
+.table > tfoot > tr > th.success,
+.table > thead > tr.success > td,
+.table > tbody > tr.success > td,
+.table > tfoot > tr.success > td,
+.table > thead > tr.success > th,
+.table > tbody > tr.success > th,
+.table > tfoot > tr.success > th {
+ background-color: #dff0d8;
+}
+.table-hover > tbody > tr > td.success:hover,
+.table-hover > tbody > tr > th.success:hover,
+.table-hover > tbody > tr.success:hover > td,
+.table-hover > tbody > tr:hover > .success,
+.table-hover > tbody > tr.success:hover > th {
+ background-color: #d0e9c6;
+}
+.table > thead > tr > td.info,
+.table > tbody > tr > td.info,
+.table > tfoot > tr > td.info,
+.table > thead > tr > th.info,
+.table > tbody > tr > th.info,
+.table > tfoot > tr > th.info,
+.table > thead > tr.info > td,
+.table > tbody > tr.info > td,
+.table > tfoot > tr.info > td,
+.table > thead > tr.info > th,
+.table > tbody > tr.info > th,
+.table > tfoot > tr.info > th {
+ background-color: #d9edf7;
+}
+.table-hover > tbody > tr > td.info:hover,
+.table-hover > tbody > tr > th.info:hover,
+.table-hover > tbody > tr.info:hover > td,
+.table-hover > tbody > tr:hover > .info,
+.table-hover > tbody > tr.info:hover > th {
+ background-color: #c4e3f3;
+}
+.table > thead > tr > td.warning,
+.table > tbody > tr > td.warning,
+.table > tfoot > tr > td.warning,
+.table > thead > tr > th.warning,
+.table > tbody > tr > th.warning,
+.table > tfoot > tr > th.warning,
+.table > thead > tr.warning > td,
+.table > tbody > tr.warning > td,
+.table > tfoot > tr.warning > td,
+.table > thead > tr.warning > th,
+.table > tbody > tr.warning > th,
+.table > tfoot > tr.warning > th {
+ background-color: #fcf8e3;
+}
+.table-hover > tbody > tr > td.warning:hover,
+.table-hover > tbody > tr > th.warning:hover,
+.table-hover > tbody > tr.warning:hover > td,
+.table-hover > tbody > tr:hover > .warning,
+.table-hover > tbody > tr.warning:hover > th {
+ background-color: #faf2cc;
+}
+.table > thead > tr > td.danger,
+.table > tbody > tr > td.danger,
+.table > tfoot > tr > td.danger,
+.table > thead > tr > th.danger,
+.table > tbody > tr > th.danger,
+.table > tfoot > tr > th.danger,
+.table > thead > tr.danger > td,
+.table > tbody > tr.danger > td,
+.table > tfoot > tr.danger > td,
+.table > thead > tr.danger > th,
+.table > tbody > tr.danger > th,
+.table > tfoot > tr.danger > th {
+ background-color: #f2dede;
+}
+.table-hover > tbody > tr > td.danger:hover,
+.table-hover > tbody > tr > th.danger:hover,
+.table-hover > tbody > tr.danger:hover > td,
+.table-hover > tbody > tr:hover > .danger,
+.table-hover > tbody > tr.danger:hover > th {
+ background-color: #ebcccc;
+}
+.table-responsive {
+ min-height: .01%;
+ overflow-x: auto;
+}
+@media screen and (max-width: 767px) {
+ .table-responsive {
+ width: 100%;
+ margin-bottom: 15px;
+ overflow-y: hidden;
+ -ms-overflow-style: -ms-autohiding-scrollbar;
+ border: 1px solid #ddd;
+ }
+ .table-responsive > .table {
+ margin-bottom: 0;
+ }
+ .table-responsive > .table > thead > tr > th,
+ .table-responsive > .table > tbody > tr > th,
+ .table-responsive > .table > tfoot > tr > th,
+ .table-responsive > .table > thead > tr > td,
+ .table-responsive > .table > tbody > tr > td,
+ .table-responsive > .table > tfoot > tr > td {
+ white-space: nowrap;
+ }
+ .table-responsive > .table-bordered {
+ border: 0;
+ }
+ .table-responsive > .table-bordered > thead > tr > th:first-child,
+ .table-responsive > .table-bordered > tbody > tr > th:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+ .table-responsive > .table-bordered > thead > tr > td:first-child,
+ .table-responsive > .table-bordered > tbody > tr > td:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+ }
+ .table-responsive > .table-bordered > thead > tr > th:last-child,
+ .table-responsive > .table-bordered > tbody > tr > th:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+ .table-responsive > .table-bordered > thead > tr > td:last-child,
+ .table-responsive > .table-bordered > tbody > tr > td:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+ }
+ .table-responsive > .table-bordered > tbody > tr:last-child > th,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > th,
+ .table-responsive > .table-bordered > tbody > tr:last-child > td,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+ border-bottom: 0;
+ }
+}
+fieldset {
+ min-width: 0;
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+legend {
+ display: block;
+ width: 100%;
+ padding: 0;
+ margin-bottom: 20px;
+ font-size: 21px;
+ line-height: inherit;
+ color: #333;
+ border: 0;
+ border-bottom: 1px solid #e5e5e5;
+}
+label {
+ display: inline-block;
+ max-width: 100%;
+ margin-bottom: 5px;
+ font-weight: bold;
+}
+input[type="search"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+input[type="radio"],
+input[type="checkbox"] {
+ margin: 4px 0 0;
+ margin-top: 1px \9;
+ line-height: normal;
+}
+input[type="file"] {
+ display: block;
+}
+input[type="range"] {
+ display: block;
+ width: 100%;
+}
+select[multiple],
+select[size] {
+ height: auto;
+}
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+output {
+ display: block;
+ padding-top: 7px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555;
+}
+.form-control {
+ display: block;
+ width: 100%;
+ height: 34px;
+ padding: 6px 12px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555;
+ background-color: #fff;
+ background-image: none;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
+ -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+.form-control:focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
+}
+.form-control::-moz-placeholder {
+ color: #999;
+ opacity: 1;
+}
+.form-control:-ms-input-placeholder {
+ color: #999;
+}
+.form-control::-webkit-input-placeholder {
+ color: #999;
+}
+.form-control[disabled],
+.form-control[readonly],
+fieldset[disabled] .form-control {
+ cursor: not-allowed;
+ background-color: #eee;
+ opacity: 1;
+}
+textarea.form-control {
+ height: auto;
+}
+input[type="search"] {
+ -webkit-appearance: none;
+}
+input[type="date"],
+input[type="time"],
+input[type="datetime-local"],
+input[type="month"] {
+ line-height: 34px;
+ line-height: 1.42857143 \0;
+}
+input[type="date"].input-sm,
+input[type="time"].input-sm,
+input[type="datetime-local"].input-sm,
+input[type="month"].input-sm {
+ line-height: 30px;
+ line-height: 1.5 \0;
+}
+input[type="date"].input-lg,
+input[type="time"].input-lg,
+input[type="datetime-local"].input-lg,
+input[type="month"].input-lg {
+ line-height: 46px;
+ line-height: 1.33 \0;
+}
+_:-ms-fullscreen,
+:root input[type="date"],
+_:-ms-fullscreen,
+:root input[type="time"],
+_:-ms-fullscreen,
+:root input[type="datetime-local"],
+_:-ms-fullscreen,
+:root input[type="month"] {
+ line-height: 1.42857143;
+}
+_:-ms-fullscreen.input-sm,
+:root input[type="date"].input-sm,
+_:-ms-fullscreen.input-sm,
+:root input[type="time"].input-sm,
+_:-ms-fullscreen.input-sm,
+:root input[type="datetime-local"].input-sm,
+_:-ms-fullscreen.input-sm,
+:root input[type="month"].input-sm {
+ line-height: 1.5;
+}
+_:-ms-fullscreen.input-lg,
+:root input[type="date"].input-lg,
+_:-ms-fullscreen.input-lg,
+:root input[type="time"].input-lg,
+_:-ms-fullscreen.input-lg,
+:root input[type="datetime-local"].input-lg,
+_:-ms-fullscreen.input-lg,
+:root input[type="month"].input-lg {
+ line-height: 1.33;
+}
+.form-group {
+ margin-bottom: 15px;
+}
+.radio,
+.checkbox {
+ position: relative;
+ display: block;
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+.radio label,
+.checkbox label {
+ min-height: 20px;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ cursor: pointer;
+}
+.radio input[type="radio"],
+.radio-inline input[type="radio"],
+.checkbox input[type="checkbox"],
+.checkbox-inline input[type="checkbox"] {
+ position: absolute;
+ margin-top: 4px \9;
+ margin-left: -20px;
+}
+.radio + .radio,
+.checkbox + .checkbox {
+ margin-top: -5px;
+}
+.radio-inline,
+.checkbox-inline {
+ display: inline-block;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ vertical-align: middle;
+ cursor: pointer;
+}
+.radio-inline + .radio-inline,
+.checkbox-inline + .checkbox-inline {
+ margin-top: 0;
+ margin-left: 10px;
+}
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+input[type="radio"].disabled,
+input[type="checkbox"].disabled,
+fieldset[disabled] input[type="radio"],
+fieldset[disabled] input[type="checkbox"] {
+ cursor: not-allowed;
+}
+.radio-inline.disabled,
+.checkbox-inline.disabled,
+fieldset[disabled] .radio-inline,
+fieldset[disabled] .checkbox-inline {
+ cursor: not-allowed;
+}
+.radio.disabled label,
+.checkbox.disabled label,
+fieldset[disabled] .radio label,
+fieldset[disabled] .checkbox label {
+ cursor: not-allowed;
+}
+.form-control-static {
+ padding-top: 7px;
+ padding-bottom: 7px;
+ margin-bottom: 0;
+}
+.form-control-static.input-lg,
+.form-control-static.input-sm {
+ padding-right: 0;
+ padding-left: 0;
+}
+.input-sm,
+.form-group-sm .form-control {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+select.input-sm,
+select.form-group-sm .form-control {
+ height: 30px;
+ line-height: 30px;
+}
+textarea.input-sm,
+textarea.form-group-sm .form-control,
+select[multiple].input-sm,
+select[multiple].form-group-sm .form-control {
+ height: auto;
+}
+.input-lg,
+.form-group-lg .form-control {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.33;
+ border-radius: 6px;
+}
+select.input-lg,
+select.form-group-lg .form-control {
+ height: 46px;
+ line-height: 46px;
+}
+textarea.input-lg,
+textarea.form-group-lg .form-control,
+select[multiple].input-lg,
+select[multiple].form-group-lg .form-control {
+ height: auto;
+}
+.has-feedback {
+ position: relative;
+}
+.has-feedback .form-control {
+ padding-right: 42.5px;
+}
+.form-control-feedback {
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: 2;
+ display: block;
+ width: 34px;
+ height: 34px;
+ line-height: 34px;
+ text-align: center;
+ pointer-events: none;
+}
+.input-lg + .form-control-feedback {
+ width: 46px;
+ height: 46px;
+ line-height: 46px;
+}
+.input-sm + .form-control-feedback {
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+}
+.has-success .help-block,
+.has-success .control-label,
+.has-success .radio,
+.has-success .checkbox,
+.has-success .radio-inline,
+.has-success .checkbox-inline,
+.has-success.radio label,
+.has-success.checkbox label,
+.has-success.radio-inline label,
+.has-success.checkbox-inline label {
+ color: #3c763d;
+}
+.has-success .form-control {
+ border-color: #3c763d;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-success .form-control:focus {
+ border-color: #2b542c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+}
+.has-success .input-group-addon {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #3c763d;
+}
+.has-success .form-control-feedback {
+ color: #3c763d;
+}
+.has-warning .help-block,
+.has-warning .control-label,
+.has-warning .radio,
+.has-warning .checkbox,
+.has-warning .radio-inline,
+.has-warning .checkbox-inline,
+.has-warning.radio label,
+.has-warning.checkbox label,
+.has-warning.radio-inline label,
+.has-warning.checkbox-inline label {
+ color: #8a6d3b;
+}
+.has-warning .form-control {
+ border-color: #8a6d3b;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-warning .form-control:focus {
+ border-color: #66512c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
+}
+.has-warning .input-group-addon {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #8a6d3b;
+}
+.has-warning .form-control-feedback {
+ color: #8a6d3b;
+}
+.has-error .help-block,
+.has-error .control-label,
+.has-error .radio,
+.has-error .checkbox,
+.has-error .radio-inline,
+.has-error .checkbox-inline,
+.has-error.radio label,
+.has-error.checkbox label,
+.has-error.radio-inline label,
+.has-error.checkbox-inline label {
+ color: #a94442;
+}
+.has-error .form-control {
+ border-color: #a94442;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-error .form-control:focus {
+ border-color: #843534;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
+}
+.has-error .input-group-addon {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #a94442;
+}
+.has-error .form-control-feedback {
+ color: #a94442;
+}
+.has-feedback label ~ .form-control-feedback {
+ top: 25px;
+}
+.has-feedback label.sr-only ~ .form-control-feedback {
+ top: 0;
+}
+.help-block {
+ display: block;
+ margin-top: 5px;
+ margin-bottom: 10px;
+ color: #737373;
+}
+@media (min-width: 768px) {
+ .form-inline .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+ .form-inline .form-control-static {
+ display: inline-block;
+ }
+ .form-inline .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+ .form-inline .input-group .input-group-addon,
+ .form-inline .input-group .input-group-btn,
+ .form-inline .input-group .form-control {
+ width: auto;
+ }
+ .form-inline .input-group > .form-control {
+ width: 100%;
+ }
+ .form-inline .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .radio,
+ .form-inline .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .radio label,
+ .form-inline .checkbox label {
+ padding-left: 0;
+ }
+ .form-inline .radio input[type="radio"],
+ .form-inline .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+ .form-inline .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox,
+.form-horizontal .radio-inline,
+.form-horizontal .checkbox-inline {
+ padding-top: 7px;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox {
+ min-height: 27px;
+}
+.form-horizontal .form-group {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+@media (min-width: 768px) {
+ .form-horizontal .control-label {
+ padding-top: 7px;
+ margin-bottom: 0;
+ text-align: right;
+ }
+}
+.form-horizontal .has-feedback .form-control-feedback {
+ right: 15px;
+}
+@media (min-width: 768px) {
+ .form-horizontal .form-group-lg .control-label {
+ padding-top: 14.3px;
+ }
+}
+@media (min-width: 768px) {
+ .form-horizontal .form-group-sm .control-label {
+ padding-top: 6px;
+ }
+}
+.btn {
+ display: inline-block;
+ padding: 6px 12px;
+ margin-bottom: 0;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ -ms-touch-action: manipulation;
+ touch-action: manipulation;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+.btn:focus,
+.btn:active:focus,
+.btn.active:focus,
+.btn.focus,
+.btn:active.focus,
+.btn.active.focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+.btn:hover,
+.btn:focus,
+.btn.focus {
+ color: #333;
+ text-decoration: none;
+}
+.btn:active,
+.btn.active {
+ background-image: none;
+ outline: 0;
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+ pointer-events: none;
+ cursor: not-allowed;
+ filter: alpha(opacity=65);
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ opacity: .65;
+}
+.btn-default {
+ color: #333;
+ background-color: #fff;
+ border-color: #ccc;
+}
+.btn-default:hover,
+.btn-default:focus,
+.btn-default.focus,
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ background-image: none;
+}
+.btn-default.disabled,
+.btn-default[disabled],
+fieldset[disabled] .btn-default,
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled.focus,
+.btn-default[disabled].focus,
+fieldset[disabled] .btn-default.focus,
+.btn-default.disabled:active,
+.btn-default[disabled]:active,
+fieldset[disabled] .btn-default:active,
+.btn-default.disabled.active,
+.btn-default[disabled].active,
+fieldset[disabled] .btn-default.active {
+ background-color: #fff;
+ border-color: #ccc;
+}
+.btn-default .badge {
+ color: #fff;
+ background-color: #333;
+}
+.btn-primary {
+ color: #fff;
+ background-color: #428bca;
+ border-color: #357ebd;
+}
+.btn-primary:hover,
+.btn-primary:focus,
+.btn-primary.focus,
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ color: #fff;
+ background-color: #3071a9;
+ border-color: #285e8e;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ background-image: none;
+}
+.btn-primary.disabled,
+.btn-primary[disabled],
+fieldset[disabled] .btn-primary,
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled.focus,
+.btn-primary[disabled].focus,
+fieldset[disabled] .btn-primary.focus,
+.btn-primary.disabled:active,
+.btn-primary[disabled]:active,
+fieldset[disabled] .btn-primary:active,
+.btn-primary.disabled.active,
+.btn-primary[disabled].active,
+fieldset[disabled] .btn-primary.active {
+ background-color: #428bca;
+ border-color: #357ebd;
+}
+.btn-primary .badge {
+ color: #428bca;
+ background-color: #fff;
+}
+.btn-success {
+ color: #fff;
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+.btn-success:hover,
+.btn-success:focus,
+.btn-success.focus,
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ background-image: none;
+}
+.btn-success.disabled,
+.btn-success[disabled],
+fieldset[disabled] .btn-success,
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled.focus,
+.btn-success[disabled].focus,
+fieldset[disabled] .btn-success.focus,
+.btn-success.disabled:active,
+.btn-success[disabled]:active,
+fieldset[disabled] .btn-success:active,
+.btn-success.disabled.active,
+.btn-success[disabled].active,
+fieldset[disabled] .btn-success.active {
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+.btn-success .badge {
+ color: #5cb85c;
+ background-color: #fff;
+}
+.btn-info {
+ color: #fff;
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+.btn-info:hover,
+.btn-info:focus,
+.btn-info.focus,
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ background-image: none;
+}
+.btn-info.disabled,
+.btn-info[disabled],
+fieldset[disabled] .btn-info,
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled.focus,
+.btn-info[disabled].focus,
+fieldset[disabled] .btn-info.focus,
+.btn-info.disabled:active,
+.btn-info[disabled]:active,
+fieldset[disabled] .btn-info:active,
+.btn-info.disabled.active,
+.btn-info[disabled].active,
+fieldset[disabled] .btn-info.active {
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+.btn-info .badge {
+ color: #5bc0de;
+ background-color: #fff;
+}
+.btn-warning {
+ color: #fff;
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+.btn-warning:hover,
+.btn-warning:focus,
+.btn-warning.focus,
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ background-image: none;
+}
+.btn-warning.disabled,
+.btn-warning[disabled],
+fieldset[disabled] .btn-warning,
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled.focus,
+.btn-warning[disabled].focus,
+fieldset[disabled] .btn-warning.focus,
+.btn-warning.disabled:active,
+.btn-warning[disabled]:active,
+fieldset[disabled] .btn-warning:active,
+.btn-warning.disabled.active,
+.btn-warning[disabled].active,
+fieldset[disabled] .btn-warning.active {
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+.btn-warning .badge {
+ color: #f0ad4e;
+ background-color: #fff;
+}
+.btn-danger {
+ color: #fff;
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+.btn-danger:hover,
+.btn-danger:focus,
+.btn-danger.focus,
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ background-image: none;
+}
+.btn-danger.disabled,
+.btn-danger[disabled],
+fieldset[disabled] .btn-danger,
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled.focus,
+.btn-danger[disabled].focus,
+fieldset[disabled] .btn-danger.focus,
+.btn-danger.disabled:active,
+.btn-danger[disabled]:active,
+fieldset[disabled] .btn-danger:active,
+.btn-danger.disabled.active,
+.btn-danger[disabled].active,
+fieldset[disabled] .btn-danger.active {
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+.btn-danger .badge {
+ color: #d9534f;
+ background-color: #fff;
+}
+.btn-link {
+ font-weight: normal;
+ color: #428bca;
+ border-radius: 0;
+}
+.btn-link,
+.btn-link:active,
+.btn-link.active,
+.btn-link[disabled],
+fieldset[disabled] .btn-link {
+ background-color: transparent;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.btn-link,
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+ border-color: transparent;
+}
+.btn-link:hover,
+.btn-link:focus {
+ color: #2a6496;
+ text-decoration: underline;
+ background-color: transparent;
+}
+.btn-link[disabled]:hover,
+fieldset[disabled] .btn-link:hover,
+.btn-link[disabled]:focus,
+fieldset[disabled] .btn-link:focus {
+ color: #777;
+ text-decoration: none;
+}
+.btn-lg,
+.btn-group-lg > .btn {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.33;
+ border-radius: 6px;
+}
+.btn-sm,
+.btn-group-sm > .btn {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+.btn-xs,
+.btn-group-xs > .btn {
+ padding: 1px 5px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+.btn-block {
+ display: block;
+ width: 100%;
+}
+.btn-block + .btn-block {
+ margin-top: 5px;
+}
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+ width: 100%;
+}
+.fade {
+ opacity: 0;
+ -webkit-transition: opacity .15s linear;
+ -o-transition: opacity .15s linear;
+ transition: opacity .15s linear;
+}
+.fade.in {
+ opacity: 1;
+}
+.collapse {
+ display: none;
+ visibility: hidden;
+}
+.collapse.in {
+ display: block;
+ visibility: visible;
+}
+tr.collapse.in {
+ display: table-row;
+}
+tbody.collapse.in {
+ display: table-row-group;
+}
+.collapsing {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ -webkit-transition-timing-function: ease;
+ -o-transition-timing-function: ease;
+ transition-timing-function: ease;
+ -webkit-transition-duration: .35s;
+ -o-transition-duration: .35s;
+ transition-duration: .35s;
+ -webkit-transition-property: height, visibility;
+ -o-transition-property: height, visibility;
+ transition-property: height, visibility;
+}
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-left: 2px;
+ vertical-align: middle;
+ border-top: 4px solid;
+ border-right: 4px solid transparent;
+ border-left: 4px solid transparent;
+}
+.dropdown {
+ position: relative;
+}
+.dropdown-toggle:focus {
+ outline: 0;
+}
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 1000;
+ display: none;
+ float: left;
+ min-width: 160px;
+ padding: 5px 0;
+ margin: 2px 0 0;
+ font-size: 14px;
+ text-align: left;
+ list-style: none;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, .15);
+ border-radius: 4px;
+ -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+}
+.dropdown-menu.pull-right {
+ right: 0;
+ left: auto;
+}
+.dropdown-menu .divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+.dropdown-menu > li > a {
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: normal;
+ line-height: 1.42857143;
+ color: #333;
+ white-space: nowrap;
+}
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+ color: #262626;
+ text-decoration: none;
+ background-color: #f5f5f5;
+}
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+ color: #fff;
+ text-decoration: none;
+ background-color: #428bca;
+ outline: 0;
+}
+.dropdown-menu > .disabled > a,
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ color: #777;
+}
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ text-decoration: none;
+ cursor: not-allowed;
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+}
+.open > .dropdown-menu {
+ display: block;
+}
+.open > a {
+ outline: 0;
+}
+.dropdown-menu-right {
+ right: 0;
+ left: auto;
+}
+.dropdown-menu-left {
+ right: auto;
+ left: 0;
+}
+.dropdown-header {
+ display: block;
+ padding: 3px 20px;
+ font-size: 12px;
+ line-height: 1.42857143;
+ color: #777;
+ white-space: nowrap;
+}
+.dropdown-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 990;
+}
+.pull-right > .dropdown-menu {
+ right: 0;
+ left: auto;
+}
+.dropup .caret,
+.navbar-fixed-bottom .dropdown .caret {
+ content: "";
+ border-top: 0;
+ border-bottom: 4px solid;
+}
+.dropup .dropdown-menu,
+.navbar-fixed-bottom .dropdown .dropdown-menu {
+ top: auto;
+ bottom: 100%;
+ margin-bottom: 1px;
+}
+@media (min-width: 768px) {
+ .navbar-right .dropdown-menu {
+ right: 0;
+ left: auto;
+ }
+ .navbar-right .dropdown-menu-left {
+ right: auto;
+ left: 0;
+ }
+}
+.btn-group,
+.btn-group-vertical {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle;
+}
+.btn-group > .btn,
+.btn-group-vertical > .btn {
+ position: relative;
+ float: left;
+}
+.btn-group > .btn:hover,
+.btn-group-vertical > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group-vertical > .btn:focus,
+.btn-group > .btn:active,
+.btn-group-vertical > .btn:active,
+.btn-group > .btn.active,
+.btn-group-vertical > .btn.active {
+ z-index: 2;
+}
+.btn-group > .btn:focus,
+.btn-group-vertical > .btn:focus {
+ outline: 0;
+}
+.btn-group .btn + .btn,
+.btn-group .btn + .btn-group,
+.btn-group .btn-group + .btn,
+.btn-group .btn-group + .btn-group {
+ margin-left: -1px;
+}
+.btn-toolbar {
+ margin-left: -5px;
+}
+.btn-toolbar .btn-group,
+.btn-toolbar .input-group {
+ float: left;
+}
+.btn-toolbar > .btn,
+.btn-toolbar > .btn-group,
+.btn-toolbar > .input-group {
+ margin-left: 5px;
+}
+.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
+ border-radius: 0;
+}
+.btn-group > .btn:first-child {
+ margin-left: 0;
+}
+.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group > .btn-group {
+ float: left;
+}
+.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+.btn-group > .btn-group:first-child > .btn:last-child,
+.btn-group > .btn-group:first-child > .dropdown-toggle {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.btn-group > .btn-group:last-child > .btn:first-child {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+ outline: 0;
+}
+.btn-group > .btn + .dropdown-toggle {
+ padding-right: 8px;
+ padding-left: 8px;
+}
+.btn-group > .btn-lg + .dropdown-toggle {
+ padding-right: 12px;
+ padding-left: 12px;
+}
+.btn-group.open .dropdown-toggle {
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+.btn-group.open .dropdown-toggle.btn-link {
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.btn .caret {
+ margin-left: 0;
+}
+.btn-lg .caret {
+ border-width: 5px 5px 0;
+ border-bottom-width: 0;
+}
+.dropup .btn-lg .caret {
+ border-width: 0 5px 5px;
+}
+.btn-group-vertical > .btn,
+.btn-group-vertical > .btn-group,
+.btn-group-vertical > .btn-group > .btn {
+ display: block;
+ float: none;
+ width: 100%;
+ max-width: 100%;
+}
+.btn-group-vertical > .btn-group > .btn {
+ float: none;
+}
+.btn-group-vertical > .btn + .btn,
+.btn-group-vertical > .btn + .btn-group,
+.btn-group-vertical > .btn-group + .btn,
+.btn-group-vertical > .btn-group + .btn-group {
+ margin-top: -1px;
+ margin-left: 0;
+}
+.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+.btn-group-vertical > .btn:first-child:not(:last-child) {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn:last-child:not(:first-child) {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ border-bottom-left-radius: 4px;
+}
+.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.btn-group-justified {
+ display: table;
+ width: 100%;
+ table-layout: fixed;
+ border-collapse: separate;
+}
+.btn-group-justified > .btn,
+.btn-group-justified > .btn-group {
+ display: table-cell;
+ float: none;
+ width: 1%;
+}
+.btn-group-justified > .btn-group .btn {
+ width: 100%;
+}
+.btn-group-justified > .btn-group .dropdown-menu {
+ left: auto;
+}
+[data-toggle="buttons"] > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn input[type="checkbox"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none;
+}
+.input-group {
+ position: relative;
+ display: table;
+ border-collapse: separate;
+}
+.input-group[class*="col-"] {
+ float: none;
+ padding-right: 0;
+ padding-left: 0;
+}
+.input-group .form-control {
+ position: relative;
+ z-index: 2;
+ float: left;
+ width: 100%;
+ margin-bottom: 0;
+}
+.input-group-lg > .form-control,
+.input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.33;
+ border-radius: 6px;
+}
+select.input-group-lg > .form-control,
+select.input-group-lg > .input-group-addon,
+select.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ line-height: 46px;
+}
+textarea.input-group-lg > .form-control,
+textarea.input-group-lg > .input-group-addon,
+textarea.input-group-lg > .input-group-btn > .btn,
+select[multiple].input-group-lg > .form-control,
+select[multiple].input-group-lg > .input-group-addon,
+select[multiple].input-group-lg > .input-group-btn > .btn {
+ height: auto;
+}
+.input-group-sm > .form-control,
+.input-group-sm > .input-group-addon,
+.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+select.input-group-sm > .form-control,
+select.input-group-sm > .input-group-addon,
+select.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ line-height: 30px;
+}
+textarea.input-group-sm > .form-control,
+textarea.input-group-sm > .input-group-addon,
+textarea.input-group-sm > .input-group-btn > .btn,
+select[multiple].input-group-sm > .form-control,
+select[multiple].input-group-sm > .input-group-addon,
+select[multiple].input-group-sm > .input-group-btn > .btn {
+ height: auto;
+}
+.input-group-addon,
+.input-group-btn,
+.input-group .form-control {
+ display: table-cell;
+}
+.input-group-addon:not(:first-child):not(:last-child),
+.input-group-btn:not(:first-child):not(:last-child),
+.input-group .form-control:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+.input-group-addon,
+.input-group-btn {
+ width: 1%;
+ white-space: nowrap;
+ vertical-align: middle;
+}
+.input-group-addon {
+ padding: 6px 12px;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1;
+ color: #555;
+ text-align: center;
+ background-color: #eee;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+}
+.input-group-addon.input-sm {
+ padding: 5px 10px;
+ font-size: 12px;
+ border-radius: 3px;
+}
+.input-group-addon.input-lg {
+ padding: 10px 16px;
+ font-size: 18px;
+ border-radius: 6px;
+}
+.input-group-addon input[type="radio"],
+.input-group-addon input[type="checkbox"] {
+ margin-top: 0;
+}
+.input-group .form-control:first-child,
+.input-group-addon:first-child,
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group > .btn,
+.input-group-btn:first-child > .dropdown-toggle,
+.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
+.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.input-group-addon:first-child {
+ border-right: 0;
+}
+.input-group .form-control:last-child,
+.input-group-addon:last-child,
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group > .btn,
+.input-group-btn:last-child > .dropdown-toggle,
+.input-group-btn:first-child > .btn:not(:first-child),
+.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.input-group-addon:last-child {
+ border-left: 0;
+}
+.input-group-btn {
+ position: relative;
+ font-size: 0;
+ white-space: nowrap;
+}
+.input-group-btn > .btn {
+ position: relative;
+}
+.input-group-btn > .btn + .btn {
+ margin-left: -1px;
+}
+.input-group-btn > .btn:hover,
+.input-group-btn > .btn:focus,
+.input-group-btn > .btn:active {
+ z-index: 2;
+}
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group {
+ margin-right: -1px;
+}
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group {
+ margin-left: -1px;
+}
+.nav {
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+}
+.nav > li {
+ position: relative;
+ display: block;
+}
+.nav > li > a {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+}
+.nav > li > a:hover,
+.nav > li > a:focus {
+ text-decoration: none;
+ background-color: #eee;
+}
+.nav > li.disabled > a {
+ color: #777;
+}
+.nav > li.disabled > a:hover,
+.nav > li.disabled > a:focus {
+ color: #777;
+ text-decoration: none;
+ cursor: not-allowed;
+ background-color: transparent;
+}
+.nav .open > a,
+.nav .open > a:hover,
+.nav .open > a:focus {
+ background-color: #eee;
+ border-color: #428bca;
+}
+.nav .nav-divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+.nav > li > a > img {
+ max-width: none;
+}
+.nav-tabs {
+ border-bottom: 1px solid #ddd;
+}
+.nav-tabs > li {
+ float: left;
+ margin-bottom: -1px;
+}
+.nav-tabs > li > a {
+ margin-right: 2px;
+ line-height: 1.42857143;
+ border: 1px solid transparent;
+ border-radius: 4px 4px 0 0;
+}
+.nav-tabs > li > a:hover {
+ border-color: #eee #eee #ddd;
+}
+.nav-tabs > li.active > a,
+.nav-tabs > li.active > a:hover,
+.nav-tabs > li.active > a:focus {
+ color: #555;
+ cursor: default;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-bottom-color: transparent;
+}
+.nav-tabs.nav-justified {
+ width: 100%;
+ border-bottom: 0;
+}
+.nav-tabs.nav-justified > li {
+ float: none;
+}
+.nav-tabs.nav-justified > li > a {
+ margin-bottom: 5px;
+ text-align: center;
+}
+.nav-tabs.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+ .nav-tabs.nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+.nav-tabs.nav-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px;
+}
+.nav-tabs.nav-justified > .active > a,
+.nav-tabs.nav-justified > .active > a:hover,
+.nav-tabs.nav-justified > .active > a:focus {
+ border: 1px solid #ddd;
+}
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 4px 4px 0 0;
+ }
+ .nav-tabs.nav-justified > .active > a,
+ .nav-tabs.nav-justified > .active > a:hover,
+ .nav-tabs.nav-justified > .active > a:focus {
+ border-bottom-color: #fff;
+ }
+}
+.nav-pills > li {
+ float: left;
+}
+.nav-pills > li > a {
+ border-radius: 4px;
+}
+.nav-pills > li + li {
+ margin-left: 2px;
+}
+.nav-pills > li.active > a,
+.nav-pills > li.active > a:hover,
+.nav-pills > li.active > a:focus {
+ color: #fff;
+ background-color: #428bca;
+}
+.nav-stacked > li {
+ float: none;
+}
+.nav-stacked > li + li {
+ margin-top: 2px;
+ margin-left: 0;
+}
+.nav-justified {
+ width: 100%;
+}
+.nav-justified > li {
+ float: none;
+}
+.nav-justified > li > a {
+ margin-bottom: 5px;
+ text-align: center;
+}
+.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+@media (min-width: 768px) {
+ .nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+ .nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+.nav-tabs-justified {
+ border-bottom: 0;
+}
+.nav-tabs-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px;
+}
+.nav-tabs-justified > .active > a,
+.nav-tabs-justified > .active > a:hover,
+.nav-tabs-justified > .active > a:focus {
+ border: 1px solid #ddd;
+}
+@media (min-width: 768px) {
+ .nav-tabs-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 4px 4px 0 0;
+ }
+ .nav-tabs-justified > .active > a,
+ .nav-tabs-justified > .active > a:hover,
+ .nav-tabs-justified > .active > a:focus {
+ border-bottom-color: #fff;
+ }
+}
+.tab-content > .tab-pane {
+ display: none;
+ visibility: hidden;
+}
+.tab-content > .active {
+ display: block;
+ visibility: visible;
+}
+.nav-tabs .dropdown-menu {
+ margin-top: -1px;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.navbar {
+ position: relative;
+ min-height: 50px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+}
+@media (min-width: 768px) {
+ .navbar {
+ border-radius: 4px;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-header {
+ float: left;
+ }
+}
+.navbar-collapse {
+ padding-right: 15px;
+ padding-left: 15px;
+ overflow-x: visible;
+ -webkit-overflow-scrolling: touch;
+ border-top: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+}
+.navbar-collapse.in {
+ overflow-y: auto;
+}
+@media (min-width: 768px) {
+ .navbar-collapse {
+ width: auto;
+ border-top: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+ .navbar-collapse.collapse {
+ display: block !important;
+ height: auto !important;
+ padding-bottom: 0;
+ overflow: visible !important;
+ visibility: visible !important;
+ }
+ .navbar-collapse.in {
+ overflow-y: visible;
+ }
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-static-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ padding-right: 0;
+ padding-left: 0;
+ }
+}
+.navbar-fixed-top .navbar-collapse,
+.navbar-fixed-bottom .navbar-collapse {
+ max-height: 340px;
+}
+@media (max-device-width: 480px) and (orientation: landscape) {
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ max-height: 200px;
+ }
+}
+.container > .navbar-header,
+.container-fluid > .navbar-header,
+.container > .navbar-collapse,
+.container-fluid > .navbar-collapse {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+@media (min-width: 768px) {
+ .container > .navbar-header,
+ .container-fluid > .navbar-header,
+ .container > .navbar-collapse,
+ .container-fluid > .navbar-collapse {
+ margin-right: 0;
+ margin-left: 0;
+ }
+}
+.navbar-static-top {
+ z-index: 1000;
+ border-width: 0 0 1px;
+}
+@media (min-width: 768px) {
+ .navbar-static-top {
+ border-radius: 0;
+ }
+}
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+ position: fixed;
+ right: 0;
+ left: 0;
+ z-index: 1030;
+}
+@media (min-width: 768px) {
+ .navbar-fixed-top,
+ .navbar-fixed-bottom {
+ border-radius: 0;
+ }
+}
+.navbar-fixed-top {
+ top: 0;
+ border-width: 0 0 1px;
+}
+.navbar-fixed-bottom {
+ bottom: 0;
+ margin-bottom: 0;
+ border-width: 1px 0 0;
+}
+.navbar-brand {
+ float: left;
+ height: 50px;
+ padding: 15px 15px;
+ font-size: 18px;
+ line-height: 20px;
+}
+.navbar-brand:hover,
+.navbar-brand:focus {
+ text-decoration: none;
+}
+.navbar-brand > img {
+ display: block;
+}
+@media (min-width: 768px) {
+ .navbar > .container .navbar-brand,
+ .navbar > .container-fluid .navbar-brand {
+ margin-left: -15px;
+ }
+}
+.navbar-toggle {
+ position: relative;
+ float: right;
+ padding: 9px 10px;
+ margin-top: 8px;
+ margin-right: 15px;
+ margin-bottom: 8px;
+ background-color: transparent;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+.navbar-toggle:focus {
+ outline: 0;
+}
+.navbar-toggle .icon-bar {
+ display: block;
+ width: 22px;
+ height: 2px;
+ border-radius: 1px;
+}
+.navbar-toggle .icon-bar + .icon-bar {
+ margin-top: 4px;
+}
+@media (min-width: 768px) {
+ .navbar-toggle {
+ display: none;
+ }
+}
+.navbar-nav {
+ margin: 7.5px -15px;
+}
+.navbar-nav > li > a {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ line-height: 20px;
+}
+@media (max-width: 767px) {
+ .navbar-nav .open .dropdown-menu {
+ position: static;
+ float: none;
+ width: auto;
+ margin-top: 0;
+ background-color: transparent;
+ border: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+ .navbar-nav .open .dropdown-menu > li > a,
+ .navbar-nav .open .dropdown-menu .dropdown-header {
+ padding: 5px 15px 5px 25px;
+ }
+ .navbar-nav .open .dropdown-menu > li > a {
+ line-height: 20px;
+ }
+ .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-nav .open .dropdown-menu > li > a:focus {
+ background-image: none;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-nav {
+ float: left;
+ margin: 0;
+ }
+ .navbar-nav > li {
+ float: left;
+ }
+ .navbar-nav > li > a {
+ padding-top: 15px;
+ padding-bottom: 15px;
+ }
+}
+.navbar-form {
+ padding: 10px 15px;
+ margin-top: 8px;
+ margin-right: -15px;
+ margin-bottom: 8px;
+ margin-left: -15px;
+ border-top: 1px solid transparent;
+ border-bottom: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
+}
+@media (min-width: 768px) {
+ .navbar-form .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+ .navbar-form .form-control-static {
+ display: inline-block;
+ }
+ .navbar-form .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+ .navbar-form .input-group .input-group-addon,
+ .navbar-form .input-group .input-group-btn,
+ .navbar-form .input-group .form-control {
+ width: auto;
+ }
+ .navbar-form .input-group > .form-control {
+ width: 100%;
+ }
+ .navbar-form .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .radio,
+ .navbar-form .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .radio label,
+ .navbar-form .checkbox label {
+ padding-left: 0;
+ }
+ .navbar-form .radio input[type="radio"],
+ .navbar-form .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+ .navbar-form .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+@media (max-width: 767px) {
+ .navbar-form .form-group {
+ margin-bottom: 5px;
+ }
+ .navbar-form .form-group:last-child {
+ margin-bottom: 0;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-form {
+ width: auto;
+ padding-top: 0;
+ padding-bottom: 0;
+ margin-right: 0;
+ margin-left: 0;
+ border: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+}
+.navbar-nav > li > .dropdown-menu {
+ margin-top: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.navbar-btn {
+ margin-top: 8px;
+ margin-bottom: 8px;
+}
+.navbar-btn.btn-sm {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+.navbar-btn.btn-xs {
+ margin-top: 14px;
+ margin-bottom: 14px;
+}
+.navbar-text {
+ margin-top: 15px;
+ margin-bottom: 15px;
+}
+@media (min-width: 768px) {
+ .navbar-text {
+ float: left;
+ margin-right: 15px;
+ margin-left: 15px;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-left {
+ float: left !important;
+ }
+ .navbar-right {
+ float: right !important;
+ margin-right: -15px;
+ }
+ .navbar-right ~ .navbar-right {
+ margin-right: 0;
+ }
+}
+.navbar-default {
+ background-color: #f8f8f8;
+ border-color: #e7e7e7;
+}
+.navbar-default .navbar-brand {
+ color: #777;
+}
+.navbar-default .navbar-brand:hover,
+.navbar-default .navbar-brand:focus {
+ color: #5e5e5e;
+ background-color: transparent;
+}
+.navbar-default .navbar-text {
+ color: #777;
+}
+.navbar-default .navbar-nav > li > a {
+ color: #777;
+}
+.navbar-default .navbar-nav > li > a:hover,
+.navbar-default .navbar-nav > li > a:focus {
+ color: #333;
+ background-color: transparent;
+}
+.navbar-default .navbar-nav > .active > a,
+.navbar-default .navbar-nav > .active > a:hover,
+.navbar-default .navbar-nav > .active > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+}
+.navbar-default .navbar-nav > .disabled > a,
+.navbar-default .navbar-nav > .disabled > a:hover,
+.navbar-default .navbar-nav > .disabled > a:focus {
+ color: #ccc;
+ background-color: transparent;
+}
+.navbar-default .navbar-toggle {
+ border-color: #ddd;
+}
+.navbar-default .navbar-toggle:hover,
+.navbar-default .navbar-toggle:focus {
+ background-color: #ddd;
+}
+.navbar-default .navbar-toggle .icon-bar {
+ background-color: #888;
+}
+.navbar-default .navbar-collapse,
+.navbar-default .navbar-form {
+ border-color: #e7e7e7;
+}
+.navbar-default .navbar-nav > .open > a,
+.navbar-default .navbar-nav > .open > a:hover,
+.navbar-default .navbar-nav > .open > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+}
+@media (max-width: 767px) {
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a {
+ color: #777;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #333;
+ background-color: transparent;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #ccc;
+ background-color: transparent;
+ }
+}
+.navbar-default .navbar-link {
+ color: #777;
+}
+.navbar-default .navbar-link:hover {
+ color: #333;
+}
+.navbar-default .btn-link {
+ color: #777;
+}
+.navbar-default .btn-link:hover,
+.navbar-default .btn-link:focus {
+ color: #333;
+}
+.navbar-default .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-default .btn-link:hover,
+.navbar-default .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-default .btn-link:focus {
+ color: #ccc;
+}
+.navbar-inverse {
+ background-color: #222;
+ border-color: #080808;
+}
+.navbar-inverse .navbar-brand {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-brand:hover,
+.navbar-inverse .navbar-brand:focus {
+ color: #fff;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-text {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-nav > li > a {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-nav > li > a:hover,
+.navbar-inverse .navbar-nav > li > a:focus {
+ color: #fff;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-nav > .active > a,
+.navbar-inverse .navbar-nav > .active > a:hover,
+.navbar-inverse .navbar-nav > .active > a:focus {
+ color: #fff;
+ background-color: #080808;
+}
+.navbar-inverse .navbar-nav > .disabled > a,
+.navbar-inverse .navbar-nav > .disabled > a:hover,
+.navbar-inverse .navbar-nav > .disabled > a:focus {
+ color: #444;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-toggle {
+ border-color: #333;
+}
+.navbar-inverse .navbar-toggle:hover,
+.navbar-inverse .navbar-toggle:focus {
+ background-color: #333;
+}
+.navbar-inverse .navbar-toggle .icon-bar {
+ background-color: #fff;
+}
+.navbar-inverse .navbar-collapse,
+.navbar-inverse .navbar-form {
+ border-color: #101010;
+}
+.navbar-inverse .navbar-nav > .open > a,
+.navbar-inverse .navbar-nav > .open > a:hover,
+.navbar-inverse .navbar-nav > .open > a:focus {
+ color: #fff;
+ background-color: #080808;
+}
+@media (max-width: 767px) {
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
+ border-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
+ background-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
+ color: #9d9d9d;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #fff;
+ background-color: transparent;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #fff;
+ background-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #444;
+ background-color: transparent;
+ }
+}
+.navbar-inverse .navbar-link {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-link:hover {
+ color: #fff;
+}
+.navbar-inverse .btn-link {
+ color: #9d9d9d;
+}
+.navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link:focus {
+ color: #fff;
+}
+.navbar-inverse .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-inverse .btn-link:focus {
+ color: #444;
+}
+.breadcrumb {
+ padding: 8px 15px;
+ margin-bottom: 20px;
+ list-style: none;
+ background-color: #f5f5f5;
+ border-radius: 4px;
+}
+.breadcrumb > li {
+ display: inline-block;
+}
+.breadcrumb > li + li:before {
+ padding: 0 5px;
+ color: #ccc;
+ content: "/\00a0";
+}
+.breadcrumb > .active {
+ color: #777;
+}
+.pagination {
+ display: inline-block;
+ padding-left: 0;
+ margin: 20px 0;
+ border-radius: 4px;
+}
+.pagination > li {
+ display: inline;
+}
+.pagination > li > a,
+.pagination > li > span {
+ position: relative;
+ float: left;
+ padding: 6px 12px;
+ margin-left: -1px;
+ line-height: 1.42857143;
+ color: #428bca;
+ text-decoration: none;
+ background-color: #fff;
+ border: 1px solid #ddd;
+}
+.pagination > li:first-child > a,
+.pagination > li:first-child > span {
+ margin-left: 0;
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+.pagination > li:last-child > a,
+.pagination > li:last-child > span {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+}
+.pagination > li > a:hover,
+.pagination > li > span:hover,
+.pagination > li > a:focus,
+.pagination > li > span:focus {
+ color: #2a6496;
+ background-color: #eee;
+ border-color: #ddd;
+}
+.pagination > .active > a,
+.pagination > .active > span,
+.pagination > .active > a:hover,
+.pagination > .active > span:hover,
+.pagination > .active > a:focus,
+.pagination > .active > span:focus {
+ z-index: 2;
+ color: #fff;
+ cursor: default;
+ background-color: #428bca;
+ border-color: #428bca;
+}
+.pagination > .disabled > span,
+.pagination > .disabled > span:hover,
+.pagination > .disabled > span:focus,
+.pagination > .disabled > a,
+.pagination > .disabled > a:hover,
+.pagination > .disabled > a:focus {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #fff;
+ border-color: #ddd;
+}
+.pagination-lg > li > a,
+.pagination-lg > li > span {
+ padding: 10px 16px;
+ font-size: 18px;
+}
+.pagination-lg > li:first-child > a,
+.pagination-lg > li:first-child > span {
+ border-top-left-radius: 6px;
+ border-bottom-left-radius: 6px;
+}
+.pagination-lg > li:last-child > a,
+.pagination-lg > li:last-child > span {
+ border-top-right-radius: 6px;
+ border-bottom-right-radius: 6px;
+}
+.pagination-sm > li > a,
+.pagination-sm > li > span {
+ padding: 5px 10px;
+ font-size: 12px;
+}
+.pagination-sm > li:first-child > a,
+.pagination-sm > li:first-child > span {
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.pagination-sm > li:last-child > a,
+.pagination-sm > li:last-child > span {
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+}
+.pager {
+ padding-left: 0;
+ margin: 20px 0;
+ text-align: center;
+ list-style: none;
+}
+.pager li {
+ display: inline;
+}
+.pager li > a,
+.pager li > span {
+ display: inline-block;
+ padding: 5px 14px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 15px;
+}
+.pager li > a:hover,
+.pager li > a:focus {
+ text-decoration: none;
+ background-color: #eee;
+}
+.pager .next > a,
+.pager .next > span {
+ float: right;
+}
+.pager .previous > a,
+.pager .previous > span {
+ float: left;
+}
+.pager .disabled > a,
+.pager .disabled > a:hover,
+.pager .disabled > a:focus,
+.pager .disabled > span {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #fff;
+}
+.label {
+ display: inline;
+ padding: .2em .6em .3em;
+ font-size: 75%;
+ font-weight: bold;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ border-radius: .25em;
+}
+a.label:hover,
+a.label:focus {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer;
+}
+.label:empty {
+ display: none;
+}
+.btn .label {
+ position: relative;
+ top: -1px;
+}
+.label-default {
+ background-color: #777;
+}
+.label-default[href]:hover,
+.label-default[href]:focus {
+ background-color: #5e5e5e;
+}
+.label-primary {
+ background-color: #428bca;
+}
+.label-primary[href]:hover,
+.label-primary[href]:focus {
+ background-color: #3071a9;
+}
+.label-success {
+ background-color: #5cb85c;
+}
+.label-success[href]:hover,
+.label-success[href]:focus {
+ background-color: #449d44;
+}
+.label-info {
+ background-color: #5bc0de;
+}
+.label-info[href]:hover,
+.label-info[href]:focus {
+ background-color: #31b0d5;
+}
+.label-warning {
+ background-color: #f0ad4e;
+}
+.label-warning[href]:hover,
+.label-warning[href]:focus {
+ background-color: #ec971f;
+}
+.label-danger {
+ background-color: #d9534f;
+}
+.label-danger[href]:hover,
+.label-danger[href]:focus {
+ background-color: #c9302c;
+}
+.badge {
+ display: inline-block;
+ min-width: 10px;
+ padding: 3px 7px;
+ font-size: 12px;
+ font-weight: bold;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ background-color: #777;
+ border-radius: 10px;
+}
+.badge:empty {
+ display: none;
+}
+.btn .badge {
+ position: relative;
+ top: -1px;
+}
+.btn-xs .badge {
+ top: 0;
+ padding: 1px 5px;
+}
+a.badge:hover,
+a.badge:focus {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer;
+}
+a.list-group-item.active > .badge,
+.nav-pills > .active > a > .badge {
+ color: #428bca;
+ background-color: #fff;
+}
+.nav-pills > li > a > .badge {
+ margin-left: 3px;
+}
+.jumbotron {
+ padding: 30px 15px;
+ margin-bottom: 30px;
+ color: inherit;
+ background-color: #eee;
+}
+.jumbotron h1,
+.jumbotron .h1 {
+ color: inherit;
+}
+.jumbotron p {
+ margin-bottom: 15px;
+ font-size: 21px;
+ font-weight: 200;
+}
+.jumbotron > hr {
+ border-top-color: #d5d5d5;
+}
+.container .jumbotron,
+.container-fluid .jumbotron {
+ border-radius: 6px;
+}
+.jumbotron .container {
+ max-width: 100%;
+}
+@media screen and (min-width: 768px) {
+ .jumbotron {
+ padding: 48px 0;
+ }
+ .container .jumbotron {
+ padding-right: 60px;
+ padding-left: 60px;
+ }
+ .jumbotron h1,
+ .jumbotron .h1 {
+ font-size: 63px;
+ }
+}
+.thumbnail {
+ display: block;
+ padding: 4px;
+ margin-bottom: 20px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ -webkit-transition: border .2s ease-in-out;
+ -o-transition: border .2s ease-in-out;
+ transition: border .2s ease-in-out;
+}
+.thumbnail > img,
+.thumbnail a > img {
+ margin-right: auto;
+ margin-left: auto;
+}
+a.thumbnail:hover,
+a.thumbnail:focus,
+a.thumbnail.active {
+ border-color: #428bca;
+}
+.thumbnail .caption {
+ padding: 9px;
+ color: #333;
+}
+.alert {
+ padding: 15px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+.alert h4 {
+ margin-top: 0;
+ color: inherit;
+}
+.alert .alert-link {
+ font-weight: bold;
+}
+.alert > p,
+.alert > ul {
+ margin-bottom: 0;
+}
+.alert > p + p {
+ margin-top: 5px;
+}
+.alert-dismissable,
+.alert-dismissible {
+ padding-right: 35px;
+}
+.alert-dismissable .close,
+.alert-dismissible .close {
+ position: relative;
+ top: -2px;
+ right: -21px;
+ color: inherit;
+}
+.alert-success {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+}
+.alert-success hr {
+ border-top-color: #c9e2b3;
+}
+.alert-success .alert-link {
+ color: #2b542c;
+}
+.alert-info {
+ color: #31708f;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+.alert-info hr {
+ border-top-color: #a6e1ec;
+}
+.alert-info .alert-link {
+ color: #245269;
+}
+.alert-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc;
+}
+.alert-warning hr {
+ border-top-color: #f7e1b5;
+}
+.alert-warning .alert-link {
+ color: #66512c;
+}
+.alert-danger {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #ebccd1;
+}
+.alert-danger hr {
+ border-top-color: #e4b9c0;
+}
+.alert-danger .alert-link {
+ color: #843534;
+}
+@-webkit-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+@-o-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+@keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+.progress {
+ height: 20px;
+ margin-bottom: 20px;
+ overflow: hidden;
+ background-color: #f5f5f5;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+}
+.progress-bar {
+ float: left;
+ width: 0;
+ height: 100%;
+ font-size: 12px;
+ line-height: 20px;
+ color: #fff;
+ text-align: center;
+ background-color: #428bca;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ -webkit-transition: width .6s ease;
+ -o-transition: width .6s ease;
+ transition: width .6s ease;
+}
+.progress-striped .progress-bar,
+.progress-bar-striped {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ -webkit-background-size: 40px 40px;
+ background-size: 40px 40px;
+}
+.progress.active .progress-bar,
+.progress-bar.active {
+ -webkit-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite;
+}
+.progress-bar-success {
+ background-color: #5cb85c;
+}
+.progress-striped .progress-bar-success {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-info {
+ background-color: #5bc0de;
+}
+.progress-striped .progress-bar-info {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-warning {
+ background-color: #f0ad4e;
+}
+.progress-striped .progress-bar-warning {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-danger {
+ background-color: #d9534f;
+}
+.progress-striped .progress-bar-danger {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.media {
+ margin-top: 15px;
+}
+.media:first-child {
+ margin-top: 0;
+}
+.media-right,
+.media > .pull-right {
+ padding-left: 10px;
+}
+.media-left,
+.media > .pull-left {
+ padding-right: 10px;
+}
+.media-left,
+.media-right,
+.media-body {
+ display: table-cell;
+ vertical-align: top;
+}
+.media-middle {
+ vertical-align: middle;
+}
+.media-bottom {
+ vertical-align: bottom;
+}
+.media-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+.media-list {
+ padding-left: 0;
+ list-style: none;
+}
+.list-group {
+ padding-left: 0;
+ margin-bottom: 20px;
+}
+.list-group-item {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+ margin-bottom: -1px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+}
+.list-group-item:first-child {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+.list-group-item:last-child {
+ margin-bottom: 0;
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+.list-group-item > .badge {
+ float: right;
+}
+.list-group-item > .badge + .badge {
+ margin-right: 5px;
+}
+a.list-group-item {
+ color: #555;
+}
+a.list-group-item .list-group-item-heading {
+ color: #333;
+}
+a.list-group-item:hover,
+a.list-group-item:focus {
+ color: #555;
+ text-decoration: none;
+ background-color: #f5f5f5;
+}
+.list-group-item.disabled,
+.list-group-item.disabled:hover,
+.list-group-item.disabled:focus {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #eee;
+}
+.list-group-item.disabled .list-group-item-heading,
+.list-group-item.disabled:hover .list-group-item-heading,
+.list-group-item.disabled:focus .list-group-item-heading {
+ color: inherit;
+}
+.list-group-item.disabled .list-group-item-text,
+.list-group-item.disabled:hover .list-group-item-text,
+.list-group-item.disabled:focus .list-group-item-text {
+ color: #777;
+}
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
+ z-index: 2;
+ color: #fff;
+ background-color: #428bca;
+ border-color: #428bca;
+}
+.list-group-item.active .list-group-item-heading,
+.list-group-item.active:hover .list-group-item-heading,
+.list-group-item.active:focus .list-group-item-heading,
+.list-group-item.active .list-group-item-heading > small,
+.list-group-item.active:hover .list-group-item-heading > small,
+.list-group-item.active:focus .list-group-item-heading > small,
+.list-group-item.active .list-group-item-heading > .small,
+.list-group-item.active:hover .list-group-item-heading > .small,
+.list-group-item.active:focus .list-group-item-heading > .small {
+ color: inherit;
+}
+.list-group-item.active .list-group-item-text,
+.list-group-item.active:hover .list-group-item-text,
+.list-group-item.active:focus .list-group-item-text {
+ color: #e1edf7;
+}
+.list-group-item-success {
+ color: #3c763d;
+ background-color: #dff0d8;
+}
+a.list-group-item-success {
+ color: #3c763d;
+}
+a.list-group-item-success .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-success:hover,
+a.list-group-item-success:focus {
+ color: #3c763d;
+ background-color: #d0e9c6;
+}
+a.list-group-item-success.active,
+a.list-group-item-success.active:hover,
+a.list-group-item-success.active:focus {
+ color: #fff;
+ background-color: #3c763d;
+ border-color: #3c763d;
+}
+.list-group-item-info {
+ color: #31708f;
+ background-color: #d9edf7;
+}
+a.list-group-item-info {
+ color: #31708f;
+}
+a.list-group-item-info .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-info:hover,
+a.list-group-item-info:focus {
+ color: #31708f;
+ background-color: #c4e3f3;
+}
+a.list-group-item-info.active,
+a.list-group-item-info.active:hover,
+a.list-group-item-info.active:focus {
+ color: #fff;
+ background-color: #31708f;
+ border-color: #31708f;
+}
+.list-group-item-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+}
+a.list-group-item-warning {
+ color: #8a6d3b;
+}
+a.list-group-item-warning .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-warning:hover,
+a.list-group-item-warning:focus {
+ color: #8a6d3b;
+ background-color: #faf2cc;
+}
+a.list-group-item-warning.active,
+a.list-group-item-warning.active:hover,
+a.list-group-item-warning.active:focus {
+ color: #fff;
+ background-color: #8a6d3b;
+ border-color: #8a6d3b;
+}
+.list-group-item-danger {
+ color: #a94442;
+ background-color: #f2dede;
+}
+a.list-group-item-danger {
+ color: #a94442;
+}
+a.list-group-item-danger .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-danger:hover,
+a.list-group-item-danger:focus {
+ color: #a94442;
+ background-color: #ebcccc;
+}
+a.list-group-item-danger.active,
+a.list-group-item-danger.active:hover,
+a.list-group-item-danger.active:focus {
+ color: #fff;
+ background-color: #a94442;
+ border-color: #a94442;
+}
+.list-group-item-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+.list-group-item-text {
+ margin-bottom: 0;
+ line-height: 1.3;
+}
+.panel {
+ margin-bottom: 20px;
+ background-color: #fff;
+ border: 1px solid transparent;
+ border-radius: 4px;
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+}
+.panel-body {
+ padding: 15px;
+}
+.panel-heading {
+ padding: 10px 15px;
+ border-bottom: 1px solid transparent;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel-heading > .dropdown .dropdown-toggle {
+ color: inherit;
+}
+.panel-title {
+ margin-top: 0;
+ margin-bottom: 0;
+ font-size: 16px;
+ color: inherit;
+}
+.panel-title > a {
+ color: inherit;
+}
+.panel-footer {
+ padding: 10px 15px;
+ background-color: #f5f5f5;
+ border-top: 1px solid #ddd;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.panel > .list-group,
+.panel > .panel-collapse > .list-group {
+ margin-bottom: 0;
+}
+.panel > .list-group .list-group-item,
+.panel > .panel-collapse > .list-group .list-group-item {
+ border-width: 1px 0;
+ border-radius: 0;
+}
+.panel > .list-group:first-child .list-group-item:first-child,
+.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
+ border-top: 0;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel > .list-group:last-child .list-group-item:last-child,
+.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
+ border-bottom: 0;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.panel-heading + .list-group .list-group-item:first-child {
+ border-top-width: 0;
+}
+.list-group + .panel-footer {
+ border-top-width: 0;
+}
+.panel > .table,
+.panel > .table-responsive > .table,
+.panel > .panel-collapse > .table {
+ margin-bottom: 0;
+}
+.panel > .table caption,
+.panel > .table-responsive > .table caption,
+.panel > .panel-collapse > .table caption {
+ padding-right: 15px;
+ padding-left: 15px;
+}
+.panel > .table:first-child,
+.panel > .table-responsive:first-child > .table:first-child {
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
+ border-top-left-radius: 3px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
+ border-top-right-radius: 3px;
+}
+.panel > .table:last-child,
+.panel > .table-responsive:last-child > .table:last-child {
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
+ border-bottom-left-radius: 3px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
+ border-bottom-right-radius: 3px;
+}
+.panel > .panel-body + .table,
+.panel > .panel-body + .table-responsive,
+.panel > .table + .panel-body,
+.panel > .table-responsive + .panel-body {
+ border-top: 1px solid #ddd;
+}
+.panel > .table > tbody:first-child > tr:first-child th,
+.panel > .table > tbody:first-child > tr:first-child td {
+ border-top: 0;
+}
+.panel > .table-bordered,
+.panel > .table-responsive > .table-bordered {
+ border: 0;
+}
+.panel > .table-bordered > thead > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
+.panel > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-bordered > thead > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
+.panel > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-bordered > tfoot > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+}
+.panel > .table-bordered > thead > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
+.panel > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-bordered > thead > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
+.panel > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-bordered > tfoot > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+}
+.panel > .table-bordered > thead > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
+.panel > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-bordered > thead > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
+.panel > .table-bordered > tbody > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
+ border-bottom: 0;
+}
+.panel > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-bordered > tfoot > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
+ border-bottom: 0;
+}
+.panel > .table-responsive {
+ margin-bottom: 0;
+ border: 0;
+}
+.panel-group {
+ margin-bottom: 20px;
+}
+.panel-group .panel {
+ margin-bottom: 0;
+ border-radius: 4px;
+}
+.panel-group .panel + .panel {
+ margin-top: 5px;
+}
+.panel-group .panel-heading {
+ border-bottom: 0;
+}
+.panel-group .panel-heading + .panel-collapse > .panel-body,
+.panel-group .panel-heading + .panel-collapse > .list-group {
+ border-top: 1px solid #ddd;
+}
+.panel-group .panel-footer {
+ border-top: 0;
+}
+.panel-group .panel-footer + .panel-collapse .panel-body {
+ border-bottom: 1px solid #ddd;
+}
+.panel-default {
+ border-color: #ddd;
+}
+.panel-default > .panel-heading {
+ color: #333;
+ background-color: #f5f5f5;
+ border-color: #ddd;
+}
+.panel-default > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #ddd;
+}
+.panel-default > .panel-heading .badge {
+ color: #f5f5f5;
+ background-color: #333;
+}
+.panel-default > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #ddd;
+}
+.panel-primary {
+ border-color: #428bca;
+}
+.panel-primary > .panel-heading {
+ color: #fff;
+ background-color: #428bca;
+ border-color: #428bca;
+}
+.panel-primary > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #428bca;
+}
+.panel-primary > .panel-heading .badge {
+ color: #428bca;
+ background-color: #fff;
+}
+.panel-primary > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #428bca;
+}
+.panel-success {
+ border-color: #d6e9c6;
+}
+.panel-success > .panel-heading {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+}
+.panel-success > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #d6e9c6;
+}
+.panel-success > .panel-heading .badge {
+ color: #dff0d8;
+ background-color: #3c763d;
+}
+.panel-success > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #d6e9c6;
+}
+.panel-info {
+ border-color: #bce8f1;
+}
+.panel-info > .panel-heading {
+ color: #31708f;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+.panel-info > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #bce8f1;
+}
+.panel-info > .panel-heading .badge {
+ color: #d9edf7;
+ background-color: #31708f;
+}
+.panel-info > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #bce8f1;
+}
+.panel-warning {
+ border-color: #faebcc;
+}
+.panel-warning > .panel-heading {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc;
+}
+.panel-warning > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #faebcc;
+}
+.panel-warning > .panel-heading .badge {
+ color: #fcf8e3;
+ background-color: #8a6d3b;
+}
+.panel-warning > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #faebcc;
+}
+.panel-danger {
+ border-color: #ebccd1;
+}
+.panel-danger > .panel-heading {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #ebccd1;
+}
+.panel-danger > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #ebccd1;
+}
+.panel-danger > .panel-heading .badge {
+ color: #f2dede;
+ background-color: #a94442;
+}
+.panel-danger > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #ebccd1;
+}
+.embed-responsive {
+ position: relative;
+ display: block;
+ height: 0;
+ padding: 0;
+ overflow: hidden;
+}
+.embed-responsive .embed-responsive-item,
+.embed-responsive iframe,
+.embed-responsive embed,
+.embed-responsive object,
+.embed-responsive video {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: 0;
+}
+.embed-responsive.embed-responsive-16by9 {
+ padding-bottom: 56.25%;
+}
+.embed-responsive.embed-responsive-4by3 {
+ padding-bottom: 75%;
+}
+.well {
+ min-height: 20px;
+ padding: 19px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ border: 1px solid #e3e3e3;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
+}
+.well blockquote {
+ border-color: #ddd;
+ border-color: rgba(0, 0, 0, .15);
+}
+.well-lg {
+ padding: 24px;
+ border-radius: 6px;
+}
+.well-sm {
+ padding: 9px;
+ border-radius: 3px;
+}
+.close {
+ float: right;
+ font-size: 21px;
+ font-weight: bold;
+ line-height: 1;
+ color: #000;
+ text-shadow: 0 1px 0 #fff;
+ filter: alpha(opacity=20);
+ opacity: .2;
+}
+.close:hover,
+.close:focus {
+ color: #000;
+ text-decoration: none;
+ cursor: pointer;
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+button.close {
+ -webkit-appearance: none;
+ padding: 0;
+ cursor: pointer;
+ background: transparent;
+ border: 0;
+}
+.modal-open {
+ overflow: hidden;
+}
+.modal {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1040;
+ display: none;
+ overflow: hidden;
+ -webkit-overflow-scrolling: touch;
+ outline: 0;
+}
+.modal.fade .modal-dialog {
+ -webkit-transition: -webkit-transform .3s ease-out;
+ -o-transition: -o-transform .3s ease-out;
+ transition: transform .3s ease-out;
+ -webkit-transform: translate(0, -25%);
+ -ms-transform: translate(0, -25%);
+ -o-transform: translate(0, -25%);
+ transform: translate(0, -25%);
+}
+.modal.in .modal-dialog {
+ -webkit-transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
+ transform: translate(0, 0);
+}
+.modal-open .modal {
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: 10px;
+}
+.modal-content {
+ position: relative;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #999;
+ border: 1px solid rgba(0, 0, 0, .2);
+ border-radius: 6px;
+ outline: 0;
+ -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
+ box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
+}
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background-color: #000;
+}
+.modal-backdrop.fade {
+ filter: alpha(opacity=0);
+ opacity: 0;
+}
+.modal-backdrop.in {
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+.modal-header {
+ min-height: 16.42857143px;
+ padding: 15px;
+ border-bottom: 1px solid #e5e5e5;
+}
+.modal-header .close {
+ margin-top: -2px;
+}
+.modal-title {
+ margin: 0;
+ line-height: 1.42857143;
+}
+.modal-body {
+ position: relative;
+ padding: 15px;
+}
+.modal-footer {
+ padding: 15px;
+ text-align: right;
+ border-top: 1px solid #e5e5e5;
+}
+.modal-footer .btn + .btn {
+ margin-bottom: 0;
+ margin-left: 5px;
+}
+.modal-footer .btn-group .btn + .btn {
+ margin-left: -1px;
+}
+.modal-footer .btn-block + .btn-block {
+ margin-left: 0;
+}
+.modal-scrollbar-measure {
+ position: absolute;
+ top: -9999px;
+ width: 50px;
+ height: 50px;
+ overflow: scroll;
+}
+@media (min-width: 768px) {
+ .modal-dialog {
+ width: 600px;
+ margin: 30px auto;
+ }
+ .modal-content {
+ -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+ box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+ }
+ .modal-sm {
+ width: 300px;
+ }
+}
+@media (min-width: 992px) {
+ .modal-lg {
+ width: 900px;
+ }
+}
+.tooltip {
+ position: absolute;
+ z-index: 1070;
+ display: block;
+ font-size: 12px;
+ line-height: 1.4;
+ visibility: visible;
+ filter: alpha(opacity=0);
+ opacity: 0;
+}
+.tooltip.in {
+ filter: alpha(opacity=90);
+ opacity: .9;
+}
+.tooltip.top {
+ padding: 5px 0;
+ margin-top: -3px;
+}
+.tooltip.right {
+ padding: 0 5px;
+ margin-left: 3px;
+}
+.tooltip.bottom {
+ padding: 5px 0;
+ margin-top: 3px;
+}
+.tooltip.left {
+ padding: 0 5px;
+ margin-left: -3px;
+}
+.tooltip-inner {
+ max-width: 200px;
+ padding: 3px 8px;
+ color: #fff;
+ text-align: center;
+ text-decoration: none;
+ background-color: #000;
+ border-radius: 4px;
+}
+.tooltip-arrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+.tooltip.top .tooltip-arrow {
+ bottom: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.top-left .tooltip-arrow {
+ bottom: 0;
+ left: 5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.top-right .tooltip-arrow {
+ right: 5px;
+ bottom: 0;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.right .tooltip-arrow {
+ top: 50%;
+ left: 0;
+ margin-top: -5px;
+ border-width: 5px 5px 5px 0;
+ border-right-color: #000;
+}
+.tooltip.left .tooltip-arrow {
+ top: 50%;
+ right: 0;
+ margin-top: -5px;
+ border-width: 5px 0 5px 5px;
+ border-left-color: #000;
+}
+.tooltip.bottom .tooltip-arrow {
+ top: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.tooltip.bottom-left .tooltip-arrow {
+ top: 0;
+ left: 5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.tooltip.bottom-right .tooltip-arrow {
+ top: 0;
+ right: 5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 1060;
+ display: none;
+ max-width: 276px;
+ padding: 1px;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: left;
+ white-space: normal;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, .2);
+ border-radius: 6px;
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+}
+.popover.top {
+ margin-top: -10px;
+}
+.popover.right {
+ margin-left: 10px;
+}
+.popover.bottom {
+ margin-top: 10px;
+}
+.popover.left {
+ margin-left: -10px;
+}
+.popover-title {
+ padding: 8px 14px;
+ margin: 0;
+ font-size: 14px;
+ background-color: #f7f7f7;
+ border-bottom: 1px solid #ebebeb;
+ border-radius: 5px 5px 0 0;
+}
+.popover-content {
+ padding: 9px 14px;
+}
+.popover > .arrow,
+.popover > .arrow:after {
+ position: absolute;
+ display: block;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+.popover > .arrow {
+ border-width: 11px;
+}
+.popover > .arrow:after {
+ content: "";
+ border-width: 10px;
+}
+.popover.top > .arrow {
+ bottom: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-top-color: #999;
+ border-top-color: rgba(0, 0, 0, .25);
+ border-bottom-width: 0;
+}
+.popover.top > .arrow:after {
+ bottom: 1px;
+ margin-left: -10px;
+ content: " ";
+ border-top-color: #fff;
+ border-bottom-width: 0;
+}
+.popover.right > .arrow {
+ top: 50%;
+ left: -11px;
+ margin-top: -11px;
+ border-right-color: #999;
+ border-right-color: rgba(0, 0, 0, .25);
+ border-left-width: 0;
+}
+.popover.right > .arrow:after {
+ bottom: -10px;
+ left: 1px;
+ content: " ";
+ border-right-color: #fff;
+ border-left-width: 0;
+}
+.popover.bottom > .arrow {
+ top: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-top-width: 0;
+ border-bottom-color: #999;
+ border-bottom-color: rgba(0, 0, 0, .25);
+}
+.popover.bottom > .arrow:after {
+ top: 1px;
+ margin-left: -10px;
+ content: " ";
+ border-top-width: 0;
+ border-bottom-color: #fff;
+}
+.popover.left > .arrow {
+ top: 50%;
+ right: -11px;
+ margin-top: -11px;
+ border-right-width: 0;
+ border-left-color: #999;
+ border-left-color: rgba(0, 0, 0, .25);
+}
+.popover.left > .arrow:after {
+ right: 1px;
+ bottom: -10px;
+ content: " ";
+ border-right-width: 0;
+ border-left-color: #fff;
+}
+.carousel {
+ position: relative;
+}
+.carousel-inner {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+}
+.carousel-inner > .item {
+ position: relative;
+ display: none;
+ -webkit-transition: .6s ease-in-out left;
+ -o-transition: .6s ease-in-out left;
+ transition: .6s ease-in-out left;
+}
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ line-height: 1;
+}
+@media all and (transform-3d), (-webkit-transform-3d) {
+ .carousel-inner > .item {
+ -webkit-transition: -webkit-transform .6s ease-in-out;
+ -o-transition: -o-transform .6s ease-in-out;
+ transition: transform .6s ease-in-out;
+
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ -webkit-perspective: 1000;
+ perspective: 1000;
+ }
+ .carousel-inner > .item.next,
+ .carousel-inner > .item.active.right {
+ left: 0;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+ .carousel-inner > .item.prev,
+ .carousel-inner > .item.active.left {
+ left: 0;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+ .carousel-inner > .item.next.left,
+ .carousel-inner > .item.prev.right,
+ .carousel-inner > .item.active {
+ left: 0;
+ -webkit-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+}
+.carousel-inner > .active,
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ display: block;
+}
+.carousel-inner > .active {
+ left: 0;
+}
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ position: absolute;
+ top: 0;
+ width: 100%;
+}
+.carousel-inner > .next {
+ left: 100%;
+}
+.carousel-inner > .prev {
+ left: -100%;
+}
+.carousel-inner > .next.left,
+.carousel-inner > .prev.right {
+ left: 0;
+}
+.carousel-inner > .active.left {
+ left: -100%;
+}
+.carousel-inner > .active.right {
+ left: 100%;
+}
+.carousel-control {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 15%;
+ font-size: 20px;
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+.carousel-control.left {
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
+ background-repeat: repeat-x;
+}
+.carousel-control.right {
+ right: 0;
+ left: auto;
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
+ background-repeat: repeat-x;
+}
+.carousel-control:hover,
+.carousel-control:focus {
+ color: #fff;
+ text-decoration: none;
+ filter: alpha(opacity=90);
+ outline: 0;
+ opacity: .9;
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-left,
+.carousel-control .glyphicon-chevron-right {
+ position: absolute;
+ top: 50%;
+ z-index: 5;
+ display: inline-block;
+}
+.carousel-control .icon-prev,
+.carousel-control .glyphicon-chevron-left {
+ left: 50%;
+ margin-left: -10px;
+}
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-right {
+ right: 50%;
+ margin-right: -10px;
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next {
+ width: 20px;
+ height: 20px;
+ margin-top: -10px;
+ font-family: serif;
+}
+.carousel-control .icon-prev:before {
+ content: '\2039';
+}
+.carousel-control .icon-next:before {
+ content: '\203a';
+}
+.carousel-indicators {
+ position: absolute;
+ bottom: 10px;
+ left: 50%;
+ z-index: 15;
+ width: 60%;
+ padding-left: 0;
+ margin-left: -30%;
+ text-align: center;
+ list-style: none;
+}
+.carousel-indicators li {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ margin: 1px;
+ text-indent: -999px;
+ cursor: pointer;
+ background-color: #000 \9;
+ background-color: rgba(0, 0, 0, 0);
+ border: 1px solid #fff;
+ border-radius: 10px;
+}
+.carousel-indicators .active {
+ width: 12px;
+ height: 12px;
+ margin: 0;
+ background-color: #fff;
+}
+.carousel-caption {
+ position: absolute;
+ right: 15%;
+ bottom: 20px;
+ left: 15%;
+ z-index: 10;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
+}
+.carousel-caption .btn {
+ text-shadow: none;
+}
+@media screen and (min-width: 768px) {
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-prev,
+ .carousel-control .icon-next {
+ width: 30px;
+ height: 30px;
+ margin-top: -15px;
+ font-size: 30px;
+ }
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .icon-prev {
+ margin-left: -15px;
+ }
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-next {
+ margin-right: -15px;
+ }
+ .carousel-caption {
+ right: 20%;
+ left: 20%;
+ padding-bottom: 30px;
+ }
+ .carousel-indicators {
+ bottom: 20px;
+ }
+}
+.clearfix:before,
+.clearfix:after,
+.dl-horizontal dd:before,
+.dl-horizontal dd:after,
+.container:before,
+.container:after,
+.container-fluid:before,
+.container-fluid:after,
+.row:before,
+.row:after,
+.form-horizontal .form-group:before,
+.form-horizontal .form-group:after,
+.btn-toolbar:before,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:before,
+.btn-group-vertical > .btn-group:after,
+.nav:before,
+.nav:after,
+.navbar:before,
+.navbar:after,
+.navbar-header:before,
+.navbar-header:after,
+.navbar-collapse:before,
+.navbar-collapse:after,
+.pager:before,
+.pager:after,
+.panel-body:before,
+.panel-body:after,
+.modal-footer:before,
+.modal-footer:after {
+ display: table;
+ content: " ";
+}
+.clearfix:after,
+.dl-horizontal dd:after,
+.container:after,
+.container-fluid:after,
+.row:after,
+.form-horizontal .form-group:after,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:after,
+.nav:after,
+.navbar:after,
+.navbar-header:after,
+.navbar-collapse:after,
+.pager:after,
+.panel-body:after,
+.modal-footer:after {
+ clear: both;
+}
+.center-block {
+ display: block;
+ margin-right: auto;
+ margin-left: auto;
+}
+.pull-right {
+ float: right !important;
+}
+.pull-left {
+ float: left !important;
+}
+.hide {
+ display: none !important;
+}
+.show {
+ display: block !important;
+}
+.invisible {
+ visibility: hidden;
+}
+.text-hide {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+.hidden {
+ display: none !important;
+ visibility: hidden !important;
+}
+.affix {
+ position: fixed;
+}
+@-ms-viewport {
+ width: device-width;
+}
+.visible-xs,
+.visible-sm,
+.visible-md,
+.visible-lg {
+ display: none !important;
+}
+.visible-xs-block,
+.visible-xs-inline,
+.visible-xs-inline-block,
+.visible-sm-block,
+.visible-sm-inline,
+.visible-sm-inline-block,
+.visible-md-block,
+.visible-md-inline,
+.visible-md-inline-block,
+.visible-lg-block,
+.visible-lg-inline,
+.visible-lg-inline-block {
+ display: none !important;
+}
+@media (max-width: 767px) {
+ .visible-xs {
+ display: block !important;
+ }
+ table.visible-xs {
+ display: table;
+ }
+ tr.visible-xs {
+ display: table-row !important;
+ }
+ th.visible-xs,
+ td.visible-xs {
+ display: table-cell !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-block {
+ display: block !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-inline {
+ display: inline !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm {
+ display: block !important;
+ }
+ table.visible-sm {
+ display: table;
+ }
+ tr.visible-sm {
+ display: table-row !important;
+ }
+ th.visible-sm,
+ td.visible-sm {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-block {
+ display: block !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md {
+ display: block !important;
+ }
+ table.visible-md {
+ display: table;
+ }
+ tr.visible-md {
+ display: table-row !important;
+ }
+ th.visible-md,
+ td.visible-md {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-block {
+ display: block !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg {
+ display: block !important;
+ }
+ table.visible-lg {
+ display: table;
+ }
+ tr.visible-lg {
+ display: table-row !important;
+ }
+ th.visible-lg,
+ td.visible-lg {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-block {
+ display: block !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (max-width: 767px) {
+ .hidden-xs {
+ display: none !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .hidden-sm {
+ display: none !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .hidden-md {
+ display: none !important;
+ }
+}
+@media (min-width: 1200px) {
+ .hidden-lg {
+ display: none !important;
+ }
+}
+.visible-print {
+ display: none !important;
+}
+@media print {
+ .visible-print {
+ display: block !important;
+ }
+ table.visible-print {
+ display: table;
+ }
+ tr.visible-print {
+ display: table-row !important;
+ }
+ th.visible-print,
+ td.visible-print {
+ display: table-cell !important;
+ }
+}
+.visible-print-block {
+ display: none !important;
+}
+@media print {
+ .visible-print-block {
+ display: block !important;
+ }
+}
+.visible-print-inline {
+ display: none !important;
+}
+@media print {
+ .visible-print-inline {
+ display: inline !important;
+ }
+}
+.visible-print-inline-block {
+ display: none !important;
+}
+@media print {
+ .visible-print-inline-block {
+ display: inline-block !important;
+ }
+}
+@media print {
+ .hidden-print {
+ display: none !important;
+ }
+}
+/*# sourceMappingURL=bootstrap.css.map */
diff --git a/ungleich_page/static/ungleich_page/css/bootstrap.min.css b/ungleich_page/static/ungleich_page/css/bootstrap.min.css
new file mode 100755
index 0000000..d204542
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/css/bootstrap.min.css
@@ -0,0 +1,5 @@
+/*!
+ * Bootstrap v3.3.0 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:before,:after{color:#000!important;text-shadow:none!important;background:transparent!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px;line-height:1.42857143 \0}input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px;line-height:1.5 \0}input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px;line-height:1.33 \0}_:-ms-fullscreen,:root input[type=date],_:-ms-fullscreen,:root input[type=time],_:-ms-fullscreen,:root input[type=datetime-local],_:-ms-fullscreen,:root input[type=month]{line-height:1.42857143}_:-ms-fullscreen.input-sm,:root input[type=date].input-sm,_:-ms-fullscreen.input-sm,:root input[type=time].input-sm,_:-ms-fullscreen.input-sm,:root input[type=datetime-local].input-sm,_:-ms-fullscreen.input-sm,:root input[type=month].input-sm{line-height:1.5}_:-ms-fullscreen.input-lg,:root input[type=date].input-lg,_:-ms-fullscreen.input-lg,:root input[type=time].input-lg,_:-ms-fullscreen.input-lg,:root input[type=datetime-local].input-lg,_:-ms-fullscreen.input-lg,:root input[type=month].input-lg{line-height:1.33}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{position:absolute;margin-top:4px \9;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],input[type=radio].disabled,input[type=checkbox].disabled,fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm,.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm,select.form-group-sm .form-control{height:30px;line-height:30px}textarea.input-sm,textarea.form-group-sm .form-control,select[multiple].input-sm,select[multiple].form-group-sm .form-control{height:auto}.input-lg,.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg,select.form-group-lg .form-control{height:46px;line-height:46px}textarea.input-lg,textarea.form-group-lg .form-control,select[multiple].input-lg,select[multiple].form-group-lg .form-control{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default.focus,.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary.focus,.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#3071a9;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success.focus,.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info.focus,.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning.focus,.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger.focus,.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#428bca;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#428bca;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=radio],[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important;visibility:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#428bca;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#428bca;border-color:#428bca}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-right:15px;padding-left:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#428bca}.panel-primary>.panel-heading .badge{color:#428bca;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-size:12px;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.next,.carousel-inner>.item.active.right{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{display:table;content:" "}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}
diff --git a/ungleich_page/static/ungleich_page/css/cms.css b/ungleich_page/static/ungleich_page/css/cms.css
new file mode 100755
index 0000000..ac2a752
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/css/cms.css
@@ -0,0 +1,12 @@
+.lead, .split-description.wow.fadeInUp p{
+ font-family: "Raleway" , "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 21px;
+ color: #3a3a3a;
+ font-weight: 300 !important;
+}
+
+@media(min-width: 768px) {
+ .custom-padding-bottom{
+ padding-bottom: 0;
+ }
+}
diff --git a/ungleich_page/static/ungleich_page/css/glasfaser.css b/ungleich_page/static/ungleich_page/css/glasfaser.css
new file mode 100755
index 0000000..fe17bc0
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/css/glasfaser.css
@@ -0,0 +1,269 @@
+#logoWhite,
+.navbar-transparent #logoBlack {
+ display: none;
+}
+
+#logoBlack,
+.navbar-transparent #logoWhite {
+ display: block;
+}
+
+.navbar-default {
+ border-bottom: 1px solid #e7e7e7;
+ background: #fff;
+ padding: 5px;
+}
+
+@media (max-width: 767px) {
+ .navbar-transparent #logoBlack {
+ display: block;
+ }
+ .navbar-transparent #logoWhite {
+ display: none;
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-transparent {
+ padding: 20px;
+ }
+}
+
+.navbar-default .navbar-nav>li>a {
+ text-transform: uppercase;
+ font-weight: 400;
+ letter-spacing: 0.5px;
+ color: #777;
+}
+.navbar-transparent .navbar-nav>li>a {
+ color: #fff;
+}
+
+.navbar-default .navbar-nav>li>a:focus,
+.navbar-default .navbar-nav>li>a:hover,
+.navbar-default .navbar-nav>li>a:active {
+ color: #333;
+}
+
+.navbar-default .navbar-toggle .icon-bar {
+ background-color: #888;
+}
+
+.navbar-default .navbar-toggle:hover,
+.navbar-default .navbar-toggle:focus {
+ background: #ddd;
+}
+
+.navbar-default .navbar-toggle .icon-bar {
+ background-color: #333;
+}
+
+@media (min-width: 768px) {
+ .navbar-transparent .navbar-nav>li>a:focus,
+ .navbar-transparent .navbar-nav>li>a:hover,
+ .navbar-transparent .navbar-nav>li>a:active {
+ color: #e5e6e7;
+ }
+
+ .navbar-transparent {
+ border-color: transparent;
+ }
+
+ .navbar-transparent {
+ background: rgba(0,0,0,0.05);
+ box-shadow: 0 0 55px rgba(0,0,0,0.09);
+ }
+}
+
+.intro-header {
+ background: url(../img/glasfaser/header-nico-sans.jpg) no-repeat center center;
+ background-size: cover;
+ background-position: left;
+ background-color: rgb(118, 140, 163);
+ background-attachment: fixed;
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: space-between;
+ padding-top: 70px;
+}
+
+.intro-header:before {
+ background: transparent;
+ background: rgba(0,0,0,0.2);
+}
+
+.price-tag-container {
+ flex-grow: 1;
+ display: flex;
+ flex-direction: column;
+ margin-right: 8%;
+ margin-left: 10px;
+ margin-bottom: 20px;
+ justify-content: center;
+ position: relative;
+}
+
+.price-tag {
+ background: url(../img/glasfaser/header-pricetag.png) no-repeat center center;
+ height: 225px;
+ width: 225px;
+ background-size: cover;
+}
+
+.high-speed {
+ width: 100%;
+ text-align: right;
+ margin-bottom: 25px;
+ position: relative;
+}
+
+.high-speed h1 {
+ font-size: 32px;
+ font-weight: 700;
+ font-family: 'Open Sans Condensed';
+ padding: 10px 15px 10px 0;
+ text-shadow: 0px 2px 2px rgba(0,0,0,0.52);
+ color: #fff;
+}
+
+.high-speed-border {
+ background: #fff;
+ height: 3px;
+ position: absolute;
+ right: 10px;
+ left: 20px;
+}
+
+.high-speed-border:first-of-type {
+ width: 40%;
+ left: initial;
+}
+
+.high-speed-border:before {
+ content: ' ';
+ display: inline-block;
+ height: 23px;
+ width: 23px;
+ border-radius: 100%;
+ background: #fff;
+ position: absolute;
+ left: -5px;
+ top: -10px;
+}
+
+
+.split-section .container {
+ max-width: 1120px;
+}
+.split-section.right .container {
+ max-width: 840px;
+}
+.split-section {
+ padding: 90px 0;
+ overflow: hidden;
+}
+.split-section.right {
+ /* padding: 100px 0; */
+ background: rgba(0,0,0,0.03);
+}
+.split-section.right .split-description {
+ width: 100%;
+}
+.split-section .split-text .split-title h2,
+.split-section.left .split-text .split-title h2 {
+ font-size: 40px;
+ letter-spacing: 0.5px;
+}
+.split-section.left .split-text .split-title::before,
+.split-section.right .split-text .split-title::before {
+ width: 90%;
+ max-width: 420px;
+}
+
+.team-member h4 {
+ font-family: 'Raleway', Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
+ font-weight: 700;
+ margin-bottom: 20px;
+}
+
+.timeline>li .timeline-panel {
+ display: flex;
+ min-height: 80px;
+ padding-bottom: 15px;
+}
+
+@media(min-width: 768px) {
+ .timeline>li .timeline-panel {
+ align-items: center;
+ }
+}
+
+.timeline>li.timeline-inverted>.timeline-panel {
+ padding-bottom: 0;
+}
+
+
+.contact-section h2,
+.contact-section h3,
+.contact-section p {
+ color: rgba(255,255,255,0.9);
+ text-transform: initial;
+ font-weight: 300;
+ font-family: 'Lato';
+}
+
+.contact-section p {
+ font-size: 20px;
+ line-height: 1.4;
+}
+
+footer {
+ padding: 20px;
+}
+
+@media(max-width: 767px) {
+ .split-section .split-text .split-title h2,
+ .split-section.left .split-text .split-title h2 {
+ font-size: 32px;
+ line-height: 40px;
+ }
+}
+
+@media(min-width: 768px) {
+ section {
+ padding: 90px 0;
+ }
+}
+
+@media (min-width: 768px) {
+ .intro-header {
+ align-items: flex-end;
+ }
+ .high-speed h1 {
+ font-size: 88px;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .intro-header {
+ background-position: -100px;
+ background-size: auto 110%;
+ }
+ .price-tag {
+ height: 240px;
+ width: 240px;
+ }
+ .timeline>li .timeline-panel {
+ min-height: 100px;
+ }
+}
+
+@media (min-width: 992px) {
+ .price-tag {
+ min-height: 320px;
+ width: 320px;
+ }
+ .timeline>li .timeline-panel {
+ min-height: 170px;
+ }
+}
diff --git a/ungleich_page/static/ungleich_page/css/lib/animate.min.css b/ungleich_page/static/ungleich_page/css/lib/animate.min.css
new file mode 100755
index 0000000..14cfe52
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/css/lib/animate.min.css
@@ -0,0 +1,6 @@
+@charset "UTF-8";/*!
+Animate.css - http://daneden.me/animate
+Licensed under the MIT license - http://opensource.org/licenses/MIT
+
+Copyright (c) 2015 Daniel Eden
+*/.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}.animated.bounceIn,.animated.bounceOut,.animated.flipOutX,.animated.flipOutY{-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes bounce{20%,53%,80%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{20%,53%,80%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{50%,from,to{opacity:1}25%,75%{opacity:0}}@keyframes flash{50%,from,to{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes pulse{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes rubberBand{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{from,to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{from,to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}to{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}@keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}to{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}.swing{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes tada{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{from{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}to{-webkit-transform:none;transform:none}}@keyframes wobble{from{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}to{-webkit-transform:none;transform:none}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes jello{11.1%,from,to{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(0.390625deg) skewY(0.390625deg);transform:skewX(0.390625deg) skewY(0.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}@keyframes jello{11.1%,from,to{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(0.390625deg) skewY(0.390625deg);transform:skewX(0.390625deg) skewY(0.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}.jello{-webkit-animation-name:jello;animation-name:jello;-webkit-transform-origin:center;transform-origin:center}@-webkit-keyframes bounceIn{20%,40%,60%,80%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes bounceIn{20%,40%,60%,80%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:none;transform:none}}@keyframes bounceInDown{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:none;transform:none}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:none;transform:none}}@keyframes bounceInLeft{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:none;transform:none}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:none;transform:none}}@keyframes bounceInRight{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:none;transform:none}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes bounceInUp{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}to{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}to{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{from{opacity:0}to{opacity:1}}@keyframes fadeIn{from{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{from{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDownBig{from{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{from{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeft{from{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{from{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeftBig{from{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{from{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRight{from{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{from{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRightBig{from{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{from{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUp{from{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{from{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUpBig{from{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{from{opacity:1}to{opacity:0}}@keyframes fadeOut{from{opacity:1}to{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}to{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}to{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{from{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{from{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@keyframes flipOutX{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}@keyframes flipOutY{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}.flipOutY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedIn{from{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}to{-webkit-transform:none;transform:none;opacity:1}}@keyframes lightSpeedIn{from{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}to{-webkit-transform:none;transform:none;opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{from{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOut{from{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{from{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}to{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateIn{from{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}to{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{from{-webkit-transform-origin:center;transform-origin:center;opacity:1}to{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}@keyframes rotateOut{from{-webkit-transform-origin:center;transform-origin:center;opacity:1}to{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}@keyframes rotateOutDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}@keyframes rotateOutUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}to{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}to{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{from{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes rollIn{from{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}to{opacity:1;-webkit-transform:none;transform:none}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}@keyframes rollOut{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{from{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{from{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInDown{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInLeft{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInRight{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInUp{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{from{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}@keyframes zoomOut{from{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{from{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInDown{from{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{from{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInLeft{from{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{from{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInRight{from{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{from{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInUp{from{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideOutLeft{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideOutRight{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideOutUp{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp}
\ No newline at end of file
diff --git a/ungleich_page/static/ungleich_page/css/ungleich.css b/ungleich_page/static/ungleich_page/css/ungleich.css
new file mode 100755
index 0000000..af71e69
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/css/ungleich.css
@@ -0,0 +1,406 @@
+@media (min-width: 768px) and (max-width: 991px) {
+ .navbar > .container {
+ width: 100%;
+ }
+}
+
+.btn-trans {
+ color: #fff;
+ border: 2px solid #fff;
+ padding: 4px 18px;
+ letter-spacing: 0.6px;
+ background: rgba(0,0,0,0.35);
+}
+
+.btn-trans:focus,
+.btn-trans:active,
+.btn-trans:hover {
+ background: #fff;
+ color: #333;
+}
+
+#page-top #services .container .row .col-lg-12.text-center .section-heading {
+ font-style: normal;
+ color: #494949;
+}
+
+#page-top #portfolio .container .row .col-lg-12.text-center .section-heading {
+ color: #494949;
+}
+
+.header-vh {
+ height: 30px;
+}
+.intro-cap-sans-transform p {
+ font-family: 'Raleway', 'Helvetica Neue', 'Open Sans Bold', Helvetica, Arial, 'Arial Bold', sans-serif;
+ font-size: 26px;
+ font-style: normal;
+ font-weight: 200;
+ color: #FFF;
+}
+
+.intro-cap {
+ margin-top: 25px;
+ margin-bottom: 15px;
+ font-family: 'Raleway', 'Helvetica Neue', 'Open Sans Bold', Helvetica, Arial, 'Arial Bold', sans-serif;
+ font-size: 24px;
+ font-style: normal;
+ font-weight: 200;
+ text-transform: uppercase;
+ color: #FFF;
+}
+
+.intro-smallcap {
+ font-family: 'Raleway' , "Open Sans Bold", Helvetica, Arial, "Arial Bold", sans-serif;
+ font-size: 22px;
+ font-style: normal;
+ font-weight: 200;
+ text-transform: none;
+ color: #FFF;
+}
+
+.ungleich-gallery-text-carousel {
+ min-height: 220px;
+ margin-bottom: 30px;
+ padding-bottom: 20px;
+}
+
+.ungleich-gallery-text-carousel .carousel-indicators, .text-carousel .carousel-indicators {
+ display: block;
+ height: 15px;
+ position: absolute;
+ bottom: 0px;
+ font-size: 0px;
+}
+
+.ungleich-gallery-text-carousel .carousel-indicators li, .text-carousel .carousel-indicators li {
+ width: 15px;
+ height: 15px;
+ margin: 0px 7px;
+ border: 2px solid #CACACA;
+ border-radius: 50%;
+}
+
+.ungleich-gallery-text-carousel .carousel-indicators li.active, .text-carousel .carousel-indicators li.active {
+ background: #FED136;
+}
+
+.ungleich-gallery-text-carousel .carousel-inner, .text-carousel .carousel-inner {
+ min-height: 220px;
+}
+
+.ungleich-gallery-text-carousel .carousel-inner, .text-carousel .carousel-inner {
+ padding: 0px 0px 15px;
+ position: relative;
+}
+
+.ungleich-gallery-text-carousel .carousel-inner .item, .text-carousel .carousel-inner .item {
+ padding: 0px 30px;
+}
+
+.center-block {
+ float: none !important;
+}
+
+#portfolio .portfolio-item {
+ overflow: hidden;
+}
+
+#portfolio .portfolio-item .portfolio-caption {
+ height: 250px;
+ overflow: hidden;
+}
+
+.img-client {
+ margin: 30px auto 30px auto;
+ max-height: 64px !important;
+}
+
+.team-member .team-member-caption {
+ padding: 0px 25px;
+ max-width: 400px;
+ text-align: center;
+ width: 100%;
+}
+
+.cursor-pointer {
+ cursor: pointer;
+}
+
+.img-toggle {
+ cursor: pointer;
+}
+
+@media only screen and (max-device-width: 480px) {
+ .carousel-text {
+ font-size: 14px;
+ }
+ #portfolio .portfolio-item .portfolio-caption {
+ height: auto;
+ overflow: hidden;
+ }
+}
+
+@media (max-width: 767px) {
+ .intro-smallcap.sm_left,
+ .section-heading.sm_left,
+ .section-subheading.sm_left {
+ padding-left: 15px;
+ padding-right: 15px;
+ max-width: 600px;
+ margin-left: auto;
+ margin-right: auto;
+ }
+}
+
+.header_slider > .carousel .carousel-inner {
+ min-height: 95vh;
+ display: flex;
+}
+
+.header_slider > .carousel .carousel-inner > .next,
+.header_slider > .carousel .carousel-inner > .prev {
+ bottom: 0;
+}
+
+.header_slider .carousel-indicators {
+ width: 100%;
+ left: 0;
+ margin-left: 0;
+}
+
+.header_slider .carousel-indicators li {
+ margin-right: 25px;
+ width: 16px;
+ height: 16px;
+}
+
+.header_slider .carousel-indicators li.active {
+ background-color: #ffffff;
+}
+
+.header_slider .carousel-control {
+ display: none;
+}
+
+.header_slider .carousel-control .fa {
+ font-size: 2em;
+ position: absolute;
+ top: 50%;
+ margin-top: -50px;
+}
+
+.header_slider > .carousel .item {
+ background: rgba(0,0,0,0.5);
+ flex: 1;
+}
+
+.header_slider > .carousel .item .container-fluid {
+ overflow: auto;
+ padding: 50px 20px 60px;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
+ /* background: rgba(0,0,0,0.5); */
+}
+
+.header_slider .intro-cap {
+ margin: 0;
+ text-align: right;
+ line-height: 1.1;
+ font-size: 23px;
+ padding-bottom: 10px;
+}
+
+.header_slider .btn-trans {
+ align-self: flex-end;
+ z-index: 2;
+ position: relative;
+}
+
+@media (min-width: 768px) {
+ .header_slider .intro-cap {
+ font-size: 2.5em;
+ }
+ .header_slider .carousel-control {
+ width: 50px;
+ display: block;
+ }
+ .header_slider .carousel-control .fa-angle-left {
+ left: 25px;
+ }
+ .header_slider .carousel-control .fa-angle-right {
+ right: 25px;
+ }
+ .header_slider .carousel-control .fa {
+ font-size: 4em;
+ }
+ .header_slider > .carousel .item .container-fluid {
+ overflow: auto;
+ padding: 75px 50px;
+ }
+ .header_slider .btn-trans {
+ padding: 8px 15px;
+ min-width: 175px;
+ letter-spacing: 1px;
+ font-size: 1.25em;
+ }
+}
+
+@media (min-width: 992px) {
+ .header_slider .intro-cap {
+ font-size: 3.25em;
+ }
+}
+
+.header_slider .intro_lead {
+ color: #fff;
+ font-size: 1.55em;
+ text-align: right;
+ line-height: 1.4;
+ margin-bottom: 0;
+ padding-bottom: 10px;
+}
+
+@media (max-width: 768px) {
+ .header_slider .intro_lead {
+ font-size: 1.1em;
+ margin-bottom: 15px;
+ }
+
+ .header_slider .carousel-indicators li {
+ margin: 1px 25px;
+ width: 16px;
+ height: 16px;
+ }
+ .header_slider .carousel-indicators li.active {
+ margin: 0 25px;
+ width: 18px;
+ height: 18px;
+ }
+}
+
+.bg_img {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: -1;
+ width: 100%;
+ height: 100%;
+ background-size: cover;
+ background-position: center;
+}
+
+.bg_vid {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: -1;
+ width: 100%;
+ height: 100%;
+ background-size: cover;
+ background-position: center;
+}
+
+@media (min-aspect-ratio: 16/9) {
+ .bg_vid > video {
+ width: 100%;
+ height: auto;
+ }
+}
+
+@media (max-aspect-ratio: 16/9) {
+ .bg_vid > video {
+ /* width: auto; */
+ height: 100%;
+ }
+}
+
+.timeline>li .timeline-panel {
+ display: flex;
+ flex-direction: column;
+ min-height: 80px;
+ align-items: stretch;
+ justify-content: center;
+ padding-bottom: 15px;
+}
+
+.flex-justify-content-end{
+ justify-content: flex-end;
+}
+
+.flex-justify-content-start{
+ justify-content: flex-start;
+}
+
+.timeline>li.timeline-inverted>.timeline-panel {
+ padding-bottom: 0;
+}
+
+@media (max-width: 767px) {
+ .sm_left {
+ text-align: left !important;
+ }
+}
+
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .timeline>li .timeline-panel {
+ min-height: 100px;
+ }
+}
+
+@media (min-width: 992px) {
+ .timeline>li .timeline-panel {
+ min-height: 150px;
+ }
+}
+
+@media (min-width: 1200px) {
+ .timeline>li .timeline-panel {
+ min-height: 170px;
+ }
+}
+
+.header_slider_box {
+ position: relative;
+ text-shadow: 0px 3px 5px rgba(0,0,0,0.5);
+ background: rgba(0,0,0,0.35);
+ box-shadow: 0 0 5px rgba(0,0,0,0.7);
+}
+
+.cam_corner:after,
+.cam_corner:before{
+ position: absolute;
+ content: ' ';
+ z-index: 5;
+ width: 50px;
+ height: 50px;
+ background: transparent;
+ display: block;
+}
+
+.cam_corner:after {
+ top: -2px;
+ right: -2px;
+ border-top: 2px solid rgba(255,255,255,0.5);
+ border-right: 2px solid rgba(255,255,255,0.5);
+}
+
+.cam_corner:before {
+ bottom: -2px;
+ left: -2px;
+ border-bottom: 2px solid rgba(255,255,255,0.5);
+ border-left: 2px solid rgba(255,255,255,0.5);
+}
+
+.bg_vid_back:after {
+ content: ' ';
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ bottom: 0;
+ background: rgba(0,0,0,0.35);
+}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/css/font-awesome.css b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/css/font-awesome.css
new file mode 100755
index 0000000..eb4127b
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/css/font-awesome.css
@@ -0,0 +1,1566 @@
+/*!
+ * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
+ * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+/* FONT PATH
+ * -------------------------- */
+@font-face {
+ font-family: 'FontAwesome';
+ src: url('../fonts/fontawesome-webfont.eot?v=4.1.0');
+ src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+.fa {
+ display: inline-block;
+ font-family: FontAwesome;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+/* makes the font 33% larger relative to the icon container */
+.fa-lg {
+ font-size: 1.33333333em;
+ line-height: 0.75em;
+ vertical-align: -15%;
+}
+.fa-2x {
+ font-size: 2em;
+}
+.fa-3x {
+ font-size: 3em;
+}
+.fa-4x {
+ font-size: 4em;
+}
+.fa-5x {
+ font-size: 5em;
+}
+.fa-fw {
+ width: 1.28571429em;
+ text-align: center;
+}
+.fa-ul {
+ padding-left: 0;
+ margin-left: 2.14285714em;
+ list-style-type: none;
+}
+.fa-ul > li {
+ position: relative;
+}
+.fa-li {
+ position: absolute;
+ left: -2.14285714em;
+ width: 2.14285714em;
+ top: 0.14285714em;
+ text-align: center;
+}
+.fa-li.fa-lg {
+ left: -1.85714286em;
+}
+.fa-border {
+ padding: .2em .25em .15em;
+ border: solid 0.08em #eeeeee;
+ border-radius: .1em;
+}
+.pull-right {
+ float: right;
+}
+.pull-left {
+ float: left;
+}
+.fa.pull-left {
+ margin-right: .3em;
+}
+.fa.pull-right {
+ margin-left: .3em;
+}
+.fa-spin {
+ -webkit-animation: spin 2s infinite linear;
+ -moz-animation: spin 2s infinite linear;
+ -o-animation: spin 2s infinite linear;
+ animation: spin 2s infinite linear;
+}
+@-moz-keyframes spin {
+ 0% {
+ -moz-transform: rotate(0deg);
+ }
+ 100% {
+ -moz-transform: rotate(359deg);
+ }
+}
+@-webkit-keyframes spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(359deg);
+ }
+}
+@-o-keyframes spin {
+ 0% {
+ -o-transform: rotate(0deg);
+ }
+ 100% {
+ -o-transform: rotate(359deg);
+ }
+}
+@keyframes spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+}
+.fa-rotate-90 {
+ filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
+ -webkit-transform: rotate(90deg);
+ -moz-transform: rotate(90deg);
+ -ms-transform: rotate(90deg);
+ -o-transform: rotate(90deg);
+ transform: rotate(90deg);
+}
+.fa-rotate-180 {
+ filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
+ -webkit-transform: rotate(180deg);
+ -moz-transform: rotate(180deg);
+ -ms-transform: rotate(180deg);
+ -o-transform: rotate(180deg);
+ transform: rotate(180deg);
+}
+.fa-rotate-270 {
+ filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
+ -webkit-transform: rotate(270deg);
+ -moz-transform: rotate(270deg);
+ -ms-transform: rotate(270deg);
+ -o-transform: rotate(270deg);
+ transform: rotate(270deg);
+}
+.fa-flip-horizontal {
+ filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);
+ -webkit-transform: scale(-1, 1);
+ -moz-transform: scale(-1, 1);
+ -ms-transform: scale(-1, 1);
+ -o-transform: scale(-1, 1);
+ transform: scale(-1, 1);
+}
+.fa-flip-vertical {
+ filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);
+ -webkit-transform: scale(1, -1);
+ -moz-transform: scale(1, -1);
+ -ms-transform: scale(1, -1);
+ -o-transform: scale(1, -1);
+ transform: scale(1, -1);
+}
+.fa-stack {
+ position: relative;
+ display: inline-block;
+ width: 2em;
+ height: 2em;
+ line-height: 2em;
+ vertical-align: middle;
+}
+.fa-stack-1x,
+.fa-stack-2x {
+ position: absolute;
+ left: 0;
+ width: 100%;
+ text-align: center;
+}
+.fa-stack-1x {
+ line-height: inherit;
+}
+.fa-stack-2x {
+ font-size: 2em;
+}
+.fa-inverse {
+ color: #ffffff;
+}
+/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+ readers do not read off random characters that represent icons */
+.fa-glass:before {
+ content: "\f000";
+}
+.fa-music:before {
+ content: "\f001";
+}
+.fa-search:before {
+ content: "\f002";
+}
+.fa-envelope-o:before {
+ content: "\f003";
+}
+.fa-heart:before {
+ content: "\f004";
+}
+.fa-star:before {
+ content: "\f005";
+}
+.fa-star-o:before {
+ content: "\f006";
+}
+.fa-user:before {
+ content: "\f007";
+}
+.fa-film:before {
+ content: "\f008";
+}
+.fa-th-large:before {
+ content: "\f009";
+}
+.fa-th:before {
+ content: "\f00a";
+}
+.fa-th-list:before {
+ content: "\f00b";
+}
+.fa-check:before {
+ content: "\f00c";
+}
+.fa-times:before {
+ content: "\f00d";
+}
+.fa-search-plus:before {
+ content: "\f00e";
+}
+.fa-search-minus:before {
+ content: "\f010";
+}
+.fa-power-off:before {
+ content: "\f011";
+}
+.fa-signal:before {
+ content: "\f012";
+}
+.fa-gear:before,
+.fa-cog:before {
+ content: "\f013";
+}
+.fa-trash-o:before {
+ content: "\f014";
+}
+.fa-home:before {
+ content: "\f015";
+}
+.fa-file-o:before {
+ content: "\f016";
+}
+.fa-clock-o:before {
+ content: "\f017";
+}
+.fa-road:before {
+ content: "\f018";
+}
+.fa-download:before {
+ content: "\f019";
+}
+.fa-arrow-circle-o-down:before {
+ content: "\f01a";
+}
+.fa-arrow-circle-o-up:before {
+ content: "\f01b";
+}
+.fa-inbox:before {
+ content: "\f01c";
+}
+.fa-play-circle-o:before {
+ content: "\f01d";
+}
+.fa-rotate-right:before,
+.fa-repeat:before {
+ content: "\f01e";
+}
+.fa-refresh:before {
+ content: "\f021";
+}
+.fa-list-alt:before {
+ content: "\f022";
+}
+.fa-lock:before {
+ content: "\f023";
+}
+.fa-flag:before {
+ content: "\f024";
+}
+.fa-headphones:before {
+ content: "\f025";
+}
+.fa-volume-off:before {
+ content: "\f026";
+}
+.fa-volume-down:before {
+ content: "\f027";
+}
+.fa-volume-up:before {
+ content: "\f028";
+}
+.fa-qrcode:before {
+ content: "\f029";
+}
+.fa-barcode:before {
+ content: "\f02a";
+}
+.fa-tag:before {
+ content: "\f02b";
+}
+.fa-tags:before {
+ content: "\f02c";
+}
+.fa-book:before {
+ content: "\f02d";
+}
+.fa-bookmark:before {
+ content: "\f02e";
+}
+.fa-print:before {
+ content: "\f02f";
+}
+.fa-camera:before {
+ content: "\f030";
+}
+.fa-font:before {
+ content: "\f031";
+}
+.fa-bold:before {
+ content: "\f032";
+}
+.fa-italic:before {
+ content: "\f033";
+}
+.fa-text-height:before {
+ content: "\f034";
+}
+.fa-text-width:before {
+ content: "\f035";
+}
+.fa-align-left:before {
+ content: "\f036";
+}
+.fa-align-center:before {
+ content: "\f037";
+}
+.fa-align-right:before {
+ content: "\f038";
+}
+.fa-align-justify:before {
+ content: "\f039";
+}
+.fa-list:before {
+ content: "\f03a";
+}
+.fa-dedent:before,
+.fa-outdent:before {
+ content: "\f03b";
+}
+.fa-indent:before {
+ content: "\f03c";
+}
+.fa-video-camera:before {
+ content: "\f03d";
+}
+.fa-photo:before,
+.fa-image:before,
+.fa-picture-o:before {
+ content: "\f03e";
+}
+.fa-pencil:before {
+ content: "\f040";
+}
+.fa-map-marker:before {
+ content: "\f041";
+}
+.fa-adjust:before {
+ content: "\f042";
+}
+.fa-tint:before {
+ content: "\f043";
+}
+.fa-edit:before,
+.fa-pencil-square-o:before {
+ content: "\f044";
+}
+.fa-share-square-o:before {
+ content: "\f045";
+}
+.fa-check-square-o:before {
+ content: "\f046";
+}
+.fa-arrows:before {
+ content: "\f047";
+}
+.fa-step-backward:before {
+ content: "\f048";
+}
+.fa-fast-backward:before {
+ content: "\f049";
+}
+.fa-backward:before {
+ content: "\f04a";
+}
+.fa-play:before {
+ content: "\f04b";
+}
+.fa-pause:before {
+ content: "\f04c";
+}
+.fa-stop:before {
+ content: "\f04d";
+}
+.fa-forward:before {
+ content: "\f04e";
+}
+.fa-fast-forward:before {
+ content: "\f050";
+}
+.fa-step-forward:before {
+ content: "\f051";
+}
+.fa-eject:before {
+ content: "\f052";
+}
+.fa-chevron-left:before {
+ content: "\f053";
+}
+.fa-chevron-right:before {
+ content: "\f054";
+}
+.fa-plus-circle:before {
+ content: "\f055";
+}
+.fa-minus-circle:before {
+ content: "\f056";
+}
+.fa-times-circle:before {
+ content: "\f057";
+}
+.fa-check-circle:before {
+ content: "\f058";
+}
+.fa-question-circle:before {
+ content: "\f059";
+}
+.fa-info-circle:before {
+ content: "\f05a";
+}
+.fa-crosshairs:before {
+ content: "\f05b";
+}
+.fa-times-circle-o:before {
+ content: "\f05c";
+}
+.fa-check-circle-o:before {
+ content: "\f05d";
+}
+.fa-ban:before {
+ content: "\f05e";
+}
+.fa-arrow-left:before {
+ content: "\f060";
+}
+.fa-arrow-right:before {
+ content: "\f061";
+}
+.fa-arrow-up:before {
+ content: "\f062";
+}
+.fa-arrow-down:before {
+ content: "\f063";
+}
+.fa-mail-forward:before,
+.fa-share:before {
+ content: "\f064";
+}
+.fa-expand:before {
+ content: "\f065";
+}
+.fa-compress:before {
+ content: "\f066";
+}
+.fa-plus:before {
+ content: "\f067";
+}
+.fa-minus:before {
+ content: "\f068";
+}
+.fa-asterisk:before {
+ content: "\f069";
+}
+.fa-exclamation-circle:before {
+ content: "\f06a";
+}
+.fa-gift:before {
+ content: "\f06b";
+}
+.fa-leaf:before {
+ content: "\f06c";
+}
+.fa-fire:before {
+ content: "\f06d";
+}
+.fa-eye:before {
+ content: "\f06e";
+}
+.fa-eye-slash:before {
+ content: "\f070";
+}
+.fa-warning:before,
+.fa-exclamation-triangle:before {
+ content: "\f071";
+}
+.fa-plane:before {
+ content: "\f072";
+}
+.fa-calendar:before {
+ content: "\f073";
+}
+.fa-random:before {
+ content: "\f074";
+}
+.fa-comment:before {
+ content: "\f075";
+}
+.fa-magnet:before {
+ content: "\f076";
+}
+.fa-chevron-up:before {
+ content: "\f077";
+}
+.fa-chevron-down:before {
+ content: "\f078";
+}
+.fa-retweet:before {
+ content: "\f079";
+}
+.fa-shopping-cart:before {
+ content: "\f07a";
+}
+.fa-folder:before {
+ content: "\f07b";
+}
+.fa-folder-open:before {
+ content: "\f07c";
+}
+.fa-arrows-v:before {
+ content: "\f07d";
+}
+.fa-arrows-h:before {
+ content: "\f07e";
+}
+.fa-bar-chart-o:before {
+ content: "\f080";
+}
+.fa-twitter-square:before {
+ content: "\f081";
+}
+.fa-facebook-square:before {
+ content: "\f082";
+}
+.fa-camera-retro:before {
+ content: "\f083";
+}
+.fa-key:before {
+ content: "\f084";
+}
+.fa-gears:before,
+.fa-cogs:before {
+ content: "\f085";
+}
+.fa-comments:before {
+ content: "\f086";
+}
+.fa-thumbs-o-up:before {
+ content: "\f087";
+}
+.fa-thumbs-o-down:before {
+ content: "\f088";
+}
+.fa-star-half:before {
+ content: "\f089";
+}
+.fa-heart-o:before {
+ content: "\f08a";
+}
+.fa-sign-out:before {
+ content: "\f08b";
+}
+.fa-linkedin-square:before {
+ content: "\f08c";
+}
+.fa-thumb-tack:before {
+ content: "\f08d";
+}
+.fa-external-link:before {
+ content: "\f08e";
+}
+.fa-sign-in:before {
+ content: "\f090";
+}
+.fa-trophy:before {
+ content: "\f091";
+}
+.fa-github-square:before {
+ content: "\f092";
+}
+.fa-upload:before {
+ content: "\f093";
+}
+.fa-lemon-o:before {
+ content: "\f094";
+}
+.fa-phone:before {
+ content: "\f095";
+}
+.fa-square-o:before {
+ content: "\f096";
+}
+.fa-bookmark-o:before {
+ content: "\f097";
+}
+.fa-phone-square:before {
+ content: "\f098";
+}
+.fa-twitter:before {
+ content: "\f099";
+}
+.fa-facebook:before {
+ content: "\f09a";
+}
+.fa-github:before {
+ content: "\f09b";
+}
+.fa-unlock:before {
+ content: "\f09c";
+}
+.fa-credit-card:before {
+ content: "\f09d";
+}
+.fa-rss:before {
+ content: "\f09e";
+}
+.fa-hdd-o:before {
+ content: "\f0a0";
+}
+.fa-bullhorn:before {
+ content: "\f0a1";
+}
+.fa-bell:before {
+ content: "\f0f3";
+}
+.fa-certificate:before {
+ content: "\f0a3";
+}
+.fa-hand-o-right:before {
+ content: "\f0a4";
+}
+.fa-hand-o-left:before {
+ content: "\f0a5";
+}
+.fa-hand-o-up:before {
+ content: "\f0a6";
+}
+.fa-hand-o-down:before {
+ content: "\f0a7";
+}
+.fa-arrow-circle-left:before {
+ content: "\f0a8";
+}
+.fa-arrow-circle-right:before {
+ content: "\f0a9";
+}
+.fa-arrow-circle-up:before {
+ content: "\f0aa";
+}
+.fa-arrow-circle-down:before {
+ content: "\f0ab";
+}
+.fa-globe:before {
+ content: "\f0ac";
+}
+.fa-wrench:before {
+ content: "\f0ad";
+}
+.fa-tasks:before {
+ content: "\f0ae";
+}
+.fa-filter:before {
+ content: "\f0b0";
+}
+.fa-briefcase:before {
+ content: "\f0b1";
+}
+.fa-arrows-alt:before {
+ content: "\f0b2";
+}
+.fa-group:before,
+.fa-users:before {
+ content: "\f0c0";
+}
+.fa-chain:before,
+.fa-link:before {
+ content: "\f0c1";
+}
+.fa-cloud:before {
+ content: "\f0c2";
+}
+.fa-flask:before {
+ content: "\f0c3";
+}
+.fa-cut:before,
+.fa-scissors:before {
+ content: "\f0c4";
+}
+.fa-copy:before,
+.fa-files-o:before {
+ content: "\f0c5";
+}
+.fa-paperclip:before {
+ content: "\f0c6";
+}
+.fa-save:before,
+.fa-floppy-o:before {
+ content: "\f0c7";
+}
+.fa-square:before {
+ content: "\f0c8";
+}
+.fa-navicon:before,
+.fa-reorder:before,
+.fa-bars:before {
+ content: "\f0c9";
+}
+.fa-list-ul:before {
+ content: "\f0ca";
+}
+.fa-list-ol:before {
+ content: "\f0cb";
+}
+.fa-strikethrough:before {
+ content: "\f0cc";
+}
+.fa-underline:before {
+ content: "\f0cd";
+}
+.fa-table:before {
+ content: "\f0ce";
+}
+.fa-magic:before {
+ content: "\f0d0";
+}
+.fa-truck:before {
+ content: "\f0d1";
+}
+.fa-pinterest:before {
+ content: "\f0d2";
+}
+.fa-pinterest-square:before {
+ content: "\f0d3";
+}
+.fa-google-plus-square:before {
+ content: "\f0d4";
+}
+.fa-google-plus:before {
+ content: "\f0d5";
+}
+.fa-money:before {
+ content: "\f0d6";
+}
+.fa-caret-down:before {
+ content: "\f0d7";
+}
+.fa-caret-up:before {
+ content: "\f0d8";
+}
+.fa-caret-left:before {
+ content: "\f0d9";
+}
+.fa-caret-right:before {
+ content: "\f0da";
+}
+.fa-columns:before {
+ content: "\f0db";
+}
+.fa-unsorted:before,
+.fa-sort:before {
+ content: "\f0dc";
+}
+.fa-sort-down:before,
+.fa-sort-desc:before {
+ content: "\f0dd";
+}
+.fa-sort-up:before,
+.fa-sort-asc:before {
+ content: "\f0de";
+}
+.fa-envelope:before {
+ content: "\f0e0";
+}
+.fa-linkedin:before {
+ content: "\f0e1";
+}
+.fa-rotate-left:before,
+.fa-undo:before {
+ content: "\f0e2";
+}
+.fa-legal:before,
+.fa-gavel:before {
+ content: "\f0e3";
+}
+.fa-dashboard:before,
+.fa-tachometer:before {
+ content: "\f0e4";
+}
+.fa-comment-o:before {
+ content: "\f0e5";
+}
+.fa-comments-o:before {
+ content: "\f0e6";
+}
+.fa-flash:before,
+.fa-bolt:before {
+ content: "\f0e7";
+}
+.fa-sitemap:before {
+ content: "\f0e8";
+}
+.fa-umbrella:before {
+ content: "\f0e9";
+}
+.fa-paste:before,
+.fa-clipboard:before {
+ content: "\f0ea";
+}
+.fa-lightbulb-o:before {
+ content: "\f0eb";
+}
+.fa-exchange:before {
+ content: "\f0ec";
+}
+.fa-cloud-download:before {
+ content: "\f0ed";
+}
+.fa-cloud-upload:before {
+ content: "\f0ee";
+}
+.fa-user-md:before {
+ content: "\f0f0";
+}
+.fa-stethoscope:before {
+ content: "\f0f1";
+}
+.fa-suitcase:before {
+ content: "\f0f2";
+}
+.fa-bell-o:before {
+ content: "\f0a2";
+}
+.fa-coffee:before {
+ content: "\f0f4";
+}
+.fa-cutlery:before {
+ content: "\f0f5";
+}
+.fa-file-text-o:before {
+ content: "\f0f6";
+}
+.fa-building-o:before {
+ content: "\f0f7";
+}
+.fa-hospital-o:before {
+ content: "\f0f8";
+}
+.fa-ambulance:before {
+ content: "\f0f9";
+}
+.fa-medkit:before {
+ content: "\f0fa";
+}
+.fa-fighter-jet:before {
+ content: "\f0fb";
+}
+.fa-beer:before {
+ content: "\f0fc";
+}
+.fa-h-square:before {
+ content: "\f0fd";
+}
+.fa-plus-square:before {
+ content: "\f0fe";
+}
+.fa-angle-double-left:before {
+ content: "\f100";
+}
+.fa-angle-double-right:before {
+ content: "\f101";
+}
+.fa-angle-double-up:before {
+ content: "\f102";
+}
+.fa-angle-double-down:before {
+ content: "\f103";
+}
+.fa-angle-left:before {
+ content: "\f104";
+}
+.fa-angle-right:before {
+ content: "\f105";
+}
+.fa-angle-up:before {
+ content: "\f106";
+}
+.fa-angle-down:before {
+ content: "\f107";
+}
+.fa-desktop:before {
+ content: "\f108";
+}
+.fa-laptop:before {
+ content: "\f109";
+}
+.fa-tablet:before {
+ content: "\f10a";
+}
+.fa-mobile-phone:before,
+.fa-mobile:before {
+ content: "\f10b";
+}
+.fa-circle-o:before {
+ content: "\f10c";
+}
+.fa-quote-left:before {
+ content: "\f10d";
+}
+.fa-quote-right:before {
+ content: "\f10e";
+}
+.fa-spinner:before {
+ content: "\f110";
+}
+.fa-circle:before {
+ content: "\f111";
+}
+.fa-mail-reply:before,
+.fa-reply:before {
+ content: "\f112";
+}
+.fa-github-alt:before {
+ content: "\f113";
+}
+.fa-folder-o:before {
+ content: "\f114";
+}
+.fa-folder-open-o:before {
+ content: "\f115";
+}
+.fa-smile-o:before {
+ content: "\f118";
+}
+.fa-frown-o:before {
+ content: "\f119";
+}
+.fa-meh-o:before {
+ content: "\f11a";
+}
+.fa-gamepad:before {
+ content: "\f11b";
+}
+.fa-keyboard-o:before {
+ content: "\f11c";
+}
+.fa-flag-o:before {
+ content: "\f11d";
+}
+.fa-flag-checkered:before {
+ content: "\f11e";
+}
+.fa-terminal:before {
+ content: "\f120";
+}
+.fa-code:before {
+ content: "\f121";
+}
+.fa-mail-reply-all:before,
+.fa-reply-all:before {
+ content: "\f122";
+}
+.fa-star-half-empty:before,
+.fa-star-half-full:before,
+.fa-star-half-o:before {
+ content: "\f123";
+}
+.fa-location-arrow:before {
+ content: "\f124";
+}
+.fa-crop:before {
+ content: "\f125";
+}
+.fa-code-fork:before {
+ content: "\f126";
+}
+.fa-unlink:before,
+.fa-chain-broken:before {
+ content: "\f127";
+}
+.fa-question:before {
+ content: "\f128";
+}
+.fa-info:before {
+ content: "\f129";
+}
+.fa-exclamation:before {
+ content: "\f12a";
+}
+.fa-superscript:before {
+ content: "\f12b";
+}
+.fa-subscript:before {
+ content: "\f12c";
+}
+.fa-eraser:before {
+ content: "\f12d";
+}
+.fa-puzzle-piece:before {
+ content: "\f12e";
+}
+.fa-microphone:before {
+ content: "\f130";
+}
+.fa-microphone-slash:before {
+ content: "\f131";
+}
+.fa-shield:before {
+ content: "\f132";
+}
+.fa-calendar-o:before {
+ content: "\f133";
+}
+.fa-fire-extinguisher:before {
+ content: "\f134";
+}
+.fa-rocket:before {
+ content: "\f135";
+}
+.fa-maxcdn:before {
+ content: "\f136";
+}
+.fa-chevron-circle-left:before {
+ content: "\f137";
+}
+.fa-chevron-circle-right:before {
+ content: "\f138";
+}
+.fa-chevron-circle-up:before {
+ content: "\f139";
+}
+.fa-chevron-circle-down:before {
+ content: "\f13a";
+}
+.fa-html5:before {
+ content: "\f13b";
+}
+.fa-css3:before {
+ content: "\f13c";
+}
+.fa-anchor:before {
+ content: "\f13d";
+}
+.fa-unlock-alt:before {
+ content: "\f13e";
+}
+.fa-bullseye:before {
+ content: "\f140";
+}
+.fa-ellipsis-h:before {
+ content: "\f141";
+}
+.fa-ellipsis-v:before {
+ content: "\f142";
+}
+.fa-rss-square:before {
+ content: "\f143";
+}
+.fa-play-circle:before {
+ content: "\f144";
+}
+.fa-ticket:before {
+ content: "\f145";
+}
+.fa-minus-square:before {
+ content: "\f146";
+}
+.fa-minus-square-o:before {
+ content: "\f147";
+}
+.fa-level-up:before {
+ content: "\f148";
+}
+.fa-level-down:before {
+ content: "\f149";
+}
+.fa-check-square:before {
+ content: "\f14a";
+}
+.fa-pencil-square:before {
+ content: "\f14b";
+}
+.fa-external-link-square:before {
+ content: "\f14c";
+}
+.fa-share-square:before {
+ content: "\f14d";
+}
+.fa-compass:before {
+ content: "\f14e";
+}
+.fa-toggle-down:before,
+.fa-caret-square-o-down:before {
+ content: "\f150";
+}
+.fa-toggle-up:before,
+.fa-caret-square-o-up:before {
+ content: "\f151";
+}
+.fa-toggle-right:before,
+.fa-caret-square-o-right:before {
+ content: "\f152";
+}
+.fa-euro:before,
+.fa-eur:before {
+ content: "\f153";
+}
+.fa-gbp:before {
+ content: "\f154";
+}
+.fa-dollar:before,
+.fa-usd:before {
+ content: "\f155";
+}
+.fa-rupee:before,
+.fa-inr:before {
+ content: "\f156";
+}
+.fa-cny:before,
+.fa-rmb:before,
+.fa-yen:before,
+.fa-jpy:before {
+ content: "\f157";
+}
+.fa-ruble:before,
+.fa-rouble:before,
+.fa-rub:before {
+ content: "\f158";
+}
+.fa-won:before,
+.fa-krw:before {
+ content: "\f159";
+}
+.fa-bitcoin:before,
+.fa-btc:before {
+ content: "\f15a";
+}
+.fa-file:before {
+ content: "\f15b";
+}
+.fa-file-text:before {
+ content: "\f15c";
+}
+.fa-sort-alpha-asc:before {
+ content: "\f15d";
+}
+.fa-sort-alpha-desc:before {
+ content: "\f15e";
+}
+.fa-sort-amount-asc:before {
+ content: "\f160";
+}
+.fa-sort-amount-desc:before {
+ content: "\f161";
+}
+.fa-sort-numeric-asc:before {
+ content: "\f162";
+}
+.fa-sort-numeric-desc:before {
+ content: "\f163";
+}
+.fa-thumbs-up:before {
+ content: "\f164";
+}
+.fa-thumbs-down:before {
+ content: "\f165";
+}
+.fa-youtube-square:before {
+ content: "\f166";
+}
+.fa-youtube:before {
+ content: "\f167";
+}
+.fa-xing:before {
+ content: "\f168";
+}
+.fa-xing-square:before {
+ content: "\f169";
+}
+.fa-youtube-play:before {
+ content: "\f16a";
+}
+.fa-dropbox:before {
+ content: "\f16b";
+}
+.fa-stack-overflow:before {
+ content: "\f16c";
+}
+.fa-instagram:before {
+ content: "\f16d";
+}
+.fa-flickr:before {
+ content: "\f16e";
+}
+.fa-adn:before {
+ content: "\f170";
+}
+.fa-bitbucket:before {
+ content: "\f171";
+}
+.fa-bitbucket-square:before {
+ content: "\f172";
+}
+.fa-tumblr:before {
+ content: "\f173";
+}
+.fa-tumblr-square:before {
+ content: "\f174";
+}
+.fa-long-arrow-down:before {
+ content: "\f175";
+}
+.fa-long-arrow-up:before {
+ content: "\f176";
+}
+.fa-long-arrow-left:before {
+ content: "\f177";
+}
+.fa-long-arrow-right:before {
+ content: "\f178";
+}
+.fa-apple:before {
+ content: "\f179";
+}
+.fa-windows:before {
+ content: "\f17a";
+}
+.fa-android:before {
+ content: "\f17b";
+}
+.fa-linux:before {
+ content: "\f17c";
+}
+.fa-dribbble:before {
+ content: "\f17d";
+}
+.fa-skype:before {
+ content: "\f17e";
+}
+.fa-foursquare:before {
+ content: "\f180";
+}
+.fa-trello:before {
+ content: "\f181";
+}
+.fa-female:before {
+ content: "\f182";
+}
+.fa-male:before {
+ content: "\f183";
+}
+.fa-gittip:before {
+ content: "\f184";
+}
+.fa-sun-o:before {
+ content: "\f185";
+}
+.fa-moon-o:before {
+ content: "\f186";
+}
+.fa-archive:before {
+ content: "\f187";
+}
+.fa-bug:before {
+ content: "\f188";
+}
+.fa-vk:before {
+ content: "\f189";
+}
+.fa-weibo:before {
+ content: "\f18a";
+}
+.fa-renren:before {
+ content: "\f18b";
+}
+.fa-pagelines:before {
+ content: "\f18c";
+}
+.fa-stack-exchange:before {
+ content: "\f18d";
+}
+.fa-arrow-circle-o-right:before {
+ content: "\f18e";
+}
+.fa-arrow-circle-o-left:before {
+ content: "\f190";
+}
+.fa-toggle-left:before,
+.fa-caret-square-o-left:before {
+ content: "\f191";
+}
+.fa-dot-circle-o:before {
+ content: "\f192";
+}
+.fa-wheelchair:before {
+ content: "\f193";
+}
+.fa-vimeo-square:before {
+ content: "\f194";
+}
+.fa-turkish-lira:before,
+.fa-try:before {
+ content: "\f195";
+}
+.fa-plus-square-o:before {
+ content: "\f196";
+}
+.fa-space-shuttle:before {
+ content: "\f197";
+}
+.fa-slack:before {
+ content: "\f198";
+}
+.fa-envelope-square:before {
+ content: "\f199";
+}
+.fa-wordpress:before {
+ content: "\f19a";
+}
+.fa-openid:before {
+ content: "\f19b";
+}
+.fa-institution:before,
+.fa-bank:before,
+.fa-university:before {
+ content: "\f19c";
+}
+.fa-mortar-board:before,
+.fa-graduation-cap:before {
+ content: "\f19d";
+}
+.fa-yahoo:before {
+ content: "\f19e";
+}
+.fa-google:before {
+ content: "\f1a0";
+}
+.fa-reddit:before {
+ content: "\f1a1";
+}
+.fa-reddit-square:before {
+ content: "\f1a2";
+}
+.fa-stumbleupon-circle:before {
+ content: "\f1a3";
+}
+.fa-stumbleupon:before {
+ content: "\f1a4";
+}
+.fa-delicious:before {
+ content: "\f1a5";
+}
+.fa-digg:before {
+ content: "\f1a6";
+}
+.fa-pied-piper-square:before,
+.fa-pied-piper:before {
+ content: "\f1a7";
+}
+.fa-pied-piper-alt:before {
+ content: "\f1a8";
+}
+.fa-drupal:before {
+ content: "\f1a9";
+}
+.fa-joomla:before {
+ content: "\f1aa";
+}
+.fa-language:before {
+ content: "\f1ab";
+}
+.fa-fax:before {
+ content: "\f1ac";
+}
+.fa-building:before {
+ content: "\f1ad";
+}
+.fa-child:before {
+ content: "\f1ae";
+}
+.fa-paw:before {
+ content: "\f1b0";
+}
+.fa-spoon:before {
+ content: "\f1b1";
+}
+.fa-cube:before {
+ content: "\f1b2";
+}
+.fa-cubes:before {
+ content: "\f1b3";
+}
+.fa-behance:before {
+ content: "\f1b4";
+}
+.fa-behance-square:before {
+ content: "\f1b5";
+}
+.fa-steam:before {
+ content: "\f1b6";
+}
+.fa-steam-square:before {
+ content: "\f1b7";
+}
+.fa-recycle:before {
+ content: "\f1b8";
+}
+.fa-automobile:before,
+.fa-car:before {
+ content: "\f1b9";
+}
+.fa-cab:before,
+.fa-taxi:before {
+ content: "\f1ba";
+}
+.fa-tree:before {
+ content: "\f1bb";
+}
+.fa-spotify:before {
+ content: "\f1bc";
+}
+.fa-deviantart:before {
+ content: "\f1bd";
+}
+.fa-soundcloud:before {
+ content: "\f1be";
+}
+.fa-database:before {
+ content: "\f1c0";
+}
+.fa-file-pdf-o:before {
+ content: "\f1c1";
+}
+.fa-file-word-o:before {
+ content: "\f1c2";
+}
+.fa-file-excel-o:before {
+ content: "\f1c3";
+}
+.fa-file-powerpoint-o:before {
+ content: "\f1c4";
+}
+.fa-file-photo-o:before,
+.fa-file-picture-o:before,
+.fa-file-image-o:before {
+ content: "\f1c5";
+}
+.fa-file-zip-o:before,
+.fa-file-archive-o:before {
+ content: "\f1c6";
+}
+.fa-file-sound-o:before,
+.fa-file-audio-o:before {
+ content: "\f1c7";
+}
+.fa-file-movie-o:before,
+.fa-file-video-o:before {
+ content: "\f1c8";
+}
+.fa-file-code-o:before {
+ content: "\f1c9";
+}
+.fa-vine:before {
+ content: "\f1ca";
+}
+.fa-codepen:before {
+ content: "\f1cb";
+}
+.fa-jsfiddle:before {
+ content: "\f1cc";
+}
+.fa-life-bouy:before,
+.fa-life-saver:before,
+.fa-support:before,
+.fa-life-ring:before {
+ content: "\f1cd";
+}
+.fa-circle-o-notch:before {
+ content: "\f1ce";
+}
+.fa-ra:before,
+.fa-rebel:before {
+ content: "\f1d0";
+}
+.fa-ge:before,
+.fa-empire:before {
+ content: "\f1d1";
+}
+.fa-git-square:before {
+ content: "\f1d2";
+}
+.fa-git:before {
+ content: "\f1d3";
+}
+.fa-hacker-news:before {
+ content: "\f1d4";
+}
+.fa-tencent-weibo:before {
+ content: "\f1d5";
+}
+.fa-qq:before {
+ content: "\f1d6";
+}
+.fa-wechat:before,
+.fa-weixin:before {
+ content: "\f1d7";
+}
+.fa-send:before,
+.fa-paper-plane:before {
+ content: "\f1d8";
+}
+.fa-send-o:before,
+.fa-paper-plane-o:before {
+ content: "\f1d9";
+}
+.fa-history:before {
+ content: "\f1da";
+}
+.fa-circle-thin:before {
+ content: "\f1db";
+}
+.fa-header:before {
+ content: "\f1dc";
+}
+.fa-paragraph:before {
+ content: "\f1dd";
+}
+.fa-sliders:before {
+ content: "\f1de";
+}
+.fa-share-alt:before {
+ content: "\f1e0";
+}
+.fa-share-alt-square:before {
+ content: "\f1e1";
+}
+.fa-bomb:before {
+ content: "\f1e2";
+}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/css/font-awesome.min.css b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/css/font-awesome.min.css
new file mode 100755
index 0000000..a7024f8
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/css/font-awesome.min.css
@@ -0,0 +1,15 @@
+/*!
+ * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
+ * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.1.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{
+ position: absolute;
+ left: 0;
+ width: 100%;
+ text-align: center;
+ color: #FED136
+ background-color: #FFFFFF;
+ visibility: inherit;
+}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{
+ color: #fff;
+ background-color: #FED136;
+}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-square:before,.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/fonts/FontAwesome.otf b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/fonts/FontAwesome.otf
new file mode 100755
index 0000000..3461e3f
Binary files /dev/null and b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/fonts/FontAwesome.otf differ
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/fonts/fontawesome-webfont.eot b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/fonts/fontawesome-webfont.eot
new file mode 100755
index 0000000..6cfd566
Binary files /dev/null and b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/fonts/fontawesome-webfont.eot differ
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/fonts/fontawesome-webfont.svg b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/fonts/fontawesome-webfont.svg
new file mode 100755
index 0000000..a9f8469
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/fonts/fontawesome-webfont.svg
@@ -0,0 +1,504 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/fonts/fontawesome-webfont.ttf b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/fonts/fontawesome-webfont.ttf
new file mode 100755
index 0000000..5cd6cff
Binary files /dev/null and b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/fonts/fontawesome-webfont.ttf differ
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/fonts/fontawesome-webfont.woff b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/fonts/fontawesome-webfont.woff
new file mode 100755
index 0000000..9eaecb3
Binary files /dev/null and b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/fonts/fontawesome-webfont.woff differ
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/bordered-pulled.less b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/bordered-pulled.less
new file mode 100755
index 0000000..0c90eb5
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/bordered-pulled.less
@@ -0,0 +1,16 @@
+// Bordered & Pulled
+// -------------------------
+
+.@{fa-css-prefix}-border {
+ padding: .2em .25em .15em;
+ border: solid .08em @fa-border-color;
+ border-radius: .1em;
+}
+
+.pull-right { float: right; }
+.pull-left { float: left; }
+
+.@{fa-css-prefix} {
+ &.pull-left { margin-right: .3em; }
+ &.pull-right { margin-left: .3em; }
+}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/core.less b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/core.less
new file mode 100755
index 0000000..6d223bc
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/core.less
@@ -0,0 +1,12 @@
+// Base Class Definition
+// -------------------------
+
+.@{fa-css-prefix} {
+ display: inline-block;
+ font-family: FontAwesome;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/fixed-width.less b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/fixed-width.less
new file mode 100755
index 0000000..110289f
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/fixed-width.less
@@ -0,0 +1,6 @@
+// Fixed Width Icons
+// -------------------------
+.@{fa-css-prefix}-fw {
+ width: (18em / 14);
+ text-align: center;
+}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/font-awesome.less b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/font-awesome.less
new file mode 100755
index 0000000..50cbcac
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/font-awesome.less
@@ -0,0 +1,17 @@
+/*!
+ * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
+ * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+
+@import "variables.less";
+@import "mixins.less";
+@import "path.less";
+@import "core.less";
+@import "larger.less";
+@import "fixed-width.less";
+@import "list.less";
+@import "bordered-pulled.less";
+@import "spinning.less";
+@import "rotated-flipped.less";
+@import "stacked.less";
+@import "icons.less";
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/icons.less b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/icons.less
new file mode 100755
index 0000000..13d8c68
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/icons.less
@@ -0,0 +1,506 @@
+/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+ readers do not read off random characters that represent icons */
+
+.@{fa-css-prefix}-glass:before { content: @fa-var-glass; }
+.@{fa-css-prefix}-music:before { content: @fa-var-music; }
+.@{fa-css-prefix}-search:before { content: @fa-var-search; }
+.@{fa-css-prefix}-envelope-o:before { content: @fa-var-envelope-o; }
+.@{fa-css-prefix}-heart:before { content: @fa-var-heart; }
+.@{fa-css-prefix}-star:before { content: @fa-var-star; }
+.@{fa-css-prefix}-star-o:before { content: @fa-var-star-o; }
+.@{fa-css-prefix}-user:before { content: @fa-var-user; }
+.@{fa-css-prefix}-film:before { content: @fa-var-film; }
+.@{fa-css-prefix}-th-large:before { content: @fa-var-th-large; }
+.@{fa-css-prefix}-th:before { content: @fa-var-th; }
+.@{fa-css-prefix}-th-list:before { content: @fa-var-th-list; }
+.@{fa-css-prefix}-check:before { content: @fa-var-check; }
+.@{fa-css-prefix}-times:before { content: @fa-var-times; }
+.@{fa-css-prefix}-search-plus:before { content: @fa-var-search-plus; }
+.@{fa-css-prefix}-search-minus:before { content: @fa-var-search-minus; }
+.@{fa-css-prefix}-power-off:before { content: @fa-var-power-off; }
+.@{fa-css-prefix}-signal:before { content: @fa-var-signal; }
+.@{fa-css-prefix}-gear:before,
+.@{fa-css-prefix}-cog:before { content: @fa-var-cog; }
+.@{fa-css-prefix}-trash-o:before { content: @fa-var-trash-o; }
+.@{fa-css-prefix}-home:before { content: @fa-var-home; }
+.@{fa-css-prefix}-file-o:before { content: @fa-var-file-o; }
+.@{fa-css-prefix}-clock-o:before { content: @fa-var-clock-o; }
+.@{fa-css-prefix}-road:before { content: @fa-var-road; }
+.@{fa-css-prefix}-download:before { content: @fa-var-download; }
+.@{fa-css-prefix}-arrow-circle-o-down:before { content: @fa-var-arrow-circle-o-down; }
+.@{fa-css-prefix}-arrow-circle-o-up:before { content: @fa-var-arrow-circle-o-up; }
+.@{fa-css-prefix}-inbox:before { content: @fa-var-inbox; }
+.@{fa-css-prefix}-play-circle-o:before { content: @fa-var-play-circle-o; }
+.@{fa-css-prefix}-rotate-right:before,
+.@{fa-css-prefix}-repeat:before { content: @fa-var-repeat; }
+.@{fa-css-prefix}-refresh:before { content: @fa-var-refresh; }
+.@{fa-css-prefix}-list-alt:before { content: @fa-var-list-alt; }
+.@{fa-css-prefix}-lock:before { content: @fa-var-lock; }
+.@{fa-css-prefix}-flag:before { content: @fa-var-flag; }
+.@{fa-css-prefix}-headphones:before { content: @fa-var-headphones; }
+.@{fa-css-prefix}-volume-off:before { content: @fa-var-volume-off; }
+.@{fa-css-prefix}-volume-down:before { content: @fa-var-volume-down; }
+.@{fa-css-prefix}-volume-up:before { content: @fa-var-volume-up; }
+.@{fa-css-prefix}-qrcode:before { content: @fa-var-qrcode; }
+.@{fa-css-prefix}-barcode:before { content: @fa-var-barcode; }
+.@{fa-css-prefix}-tag:before { content: @fa-var-tag; }
+.@{fa-css-prefix}-tags:before { content: @fa-var-tags; }
+.@{fa-css-prefix}-book:before { content: @fa-var-book; }
+.@{fa-css-prefix}-bookmark:before { content: @fa-var-bookmark; }
+.@{fa-css-prefix}-print:before { content: @fa-var-print; }
+.@{fa-css-prefix}-camera:before { content: @fa-var-camera; }
+.@{fa-css-prefix}-font:before { content: @fa-var-font; }
+.@{fa-css-prefix}-bold:before { content: @fa-var-bold; }
+.@{fa-css-prefix}-italic:before { content: @fa-var-italic; }
+.@{fa-css-prefix}-text-height:before { content: @fa-var-text-height; }
+.@{fa-css-prefix}-text-width:before { content: @fa-var-text-width; }
+.@{fa-css-prefix}-align-left:before { content: @fa-var-align-left; }
+.@{fa-css-prefix}-align-center:before { content: @fa-var-align-center; }
+.@{fa-css-prefix}-align-right:before { content: @fa-var-align-right; }
+.@{fa-css-prefix}-align-justify:before { content: @fa-var-align-justify; }
+.@{fa-css-prefix}-list:before { content: @fa-var-list; }
+.@{fa-css-prefix}-dedent:before,
+.@{fa-css-prefix}-outdent:before { content: @fa-var-outdent; }
+.@{fa-css-prefix}-indent:before { content: @fa-var-indent; }
+.@{fa-css-prefix}-video-camera:before { content: @fa-var-video-camera; }
+.@{fa-css-prefix}-photo:before,
+.@{fa-css-prefix}-image:before,
+.@{fa-css-prefix}-picture-o:before { content: @fa-var-picture-o; }
+.@{fa-css-prefix}-pencil:before { content: @fa-var-pencil; }
+.@{fa-css-prefix}-map-marker:before { content: @fa-var-map-marker; }
+.@{fa-css-prefix}-adjust:before { content: @fa-var-adjust; }
+.@{fa-css-prefix}-tint:before { content: @fa-var-tint; }
+.@{fa-css-prefix}-edit:before,
+.@{fa-css-prefix}-pencil-square-o:before { content: @fa-var-pencil-square-o; }
+.@{fa-css-prefix}-share-square-o:before { content: @fa-var-share-square-o; }
+.@{fa-css-prefix}-check-square-o:before { content: @fa-var-check-square-o; }
+.@{fa-css-prefix}-arrows:before { content: @fa-var-arrows; }
+.@{fa-css-prefix}-step-backward:before { content: @fa-var-step-backward; }
+.@{fa-css-prefix}-fast-backward:before { content: @fa-var-fast-backward; }
+.@{fa-css-prefix}-backward:before { content: @fa-var-backward; }
+.@{fa-css-prefix}-play:before { content: @fa-var-play; }
+.@{fa-css-prefix}-pause:before { content: @fa-var-pause; }
+.@{fa-css-prefix}-stop:before { content: @fa-var-stop; }
+.@{fa-css-prefix}-forward:before { content: @fa-var-forward; }
+.@{fa-css-prefix}-fast-forward:before { content: @fa-var-fast-forward; }
+.@{fa-css-prefix}-step-forward:before { content: @fa-var-step-forward; }
+.@{fa-css-prefix}-eject:before { content: @fa-var-eject; }
+.@{fa-css-prefix}-chevron-left:before { content: @fa-var-chevron-left; }
+.@{fa-css-prefix}-chevron-right:before { content: @fa-var-chevron-right; }
+.@{fa-css-prefix}-plus-circle:before { content: @fa-var-plus-circle; }
+.@{fa-css-prefix}-minus-circle:before { content: @fa-var-minus-circle; }
+.@{fa-css-prefix}-times-circle:before { content: @fa-var-times-circle; }
+.@{fa-css-prefix}-check-circle:before { content: @fa-var-check-circle; }
+.@{fa-css-prefix}-question-circle:before { content: @fa-var-question-circle; }
+.@{fa-css-prefix}-info-circle:before { content: @fa-var-info-circle; }
+.@{fa-css-prefix}-crosshairs:before { content: @fa-var-crosshairs; }
+.@{fa-css-prefix}-times-circle-o:before { content: @fa-var-times-circle-o; }
+.@{fa-css-prefix}-check-circle-o:before { content: @fa-var-check-circle-o; }
+.@{fa-css-prefix}-ban:before { content: @fa-var-ban; }
+.@{fa-css-prefix}-arrow-left:before { content: @fa-var-arrow-left; }
+.@{fa-css-prefix}-arrow-right:before { content: @fa-var-arrow-right; }
+.@{fa-css-prefix}-arrow-up:before { content: @fa-var-arrow-up; }
+.@{fa-css-prefix}-arrow-down:before { content: @fa-var-arrow-down; }
+.@{fa-css-prefix}-mail-forward:before,
+.@{fa-css-prefix}-share:before { content: @fa-var-share; }
+.@{fa-css-prefix}-expand:before { content: @fa-var-expand; }
+.@{fa-css-prefix}-compress:before { content: @fa-var-compress; }
+.@{fa-css-prefix}-plus:before { content: @fa-var-plus; }
+.@{fa-css-prefix}-minus:before { content: @fa-var-minus; }
+.@{fa-css-prefix}-asterisk:before { content: @fa-var-asterisk; }
+.@{fa-css-prefix}-exclamation-circle:before { content: @fa-var-exclamation-circle; }
+.@{fa-css-prefix}-gift:before { content: @fa-var-gift; }
+.@{fa-css-prefix}-leaf:before { content: @fa-var-leaf; }
+.@{fa-css-prefix}-fire:before { content: @fa-var-fire; }
+.@{fa-css-prefix}-eye:before { content: @fa-var-eye; }
+.@{fa-css-prefix}-eye-slash:before { content: @fa-var-eye-slash; }
+.@{fa-css-prefix}-warning:before,
+.@{fa-css-prefix}-exclamation-triangle:before { content: @fa-var-exclamation-triangle; }
+.@{fa-css-prefix}-plane:before { content: @fa-var-plane; }
+.@{fa-css-prefix}-calendar:before { content: @fa-var-calendar; }
+.@{fa-css-prefix}-random:before { content: @fa-var-random; }
+.@{fa-css-prefix}-comment:before { content: @fa-var-comment; }
+.@{fa-css-prefix}-magnet:before { content: @fa-var-magnet; }
+.@{fa-css-prefix}-chevron-up:before { content: @fa-var-chevron-up; }
+.@{fa-css-prefix}-chevron-down:before { content: @fa-var-chevron-down; }
+.@{fa-css-prefix}-retweet:before { content: @fa-var-retweet; }
+.@{fa-css-prefix}-shopping-cart:before { content: @fa-var-shopping-cart; }
+.@{fa-css-prefix}-folder:before { content: @fa-var-folder; }
+.@{fa-css-prefix}-folder-open:before { content: @fa-var-folder-open; }
+.@{fa-css-prefix}-arrows-v:before { content: @fa-var-arrows-v; }
+.@{fa-css-prefix}-arrows-h:before { content: @fa-var-arrows-h; }
+.@{fa-css-prefix}-bar-chart-o:before { content: @fa-var-bar-chart-o; }
+.@{fa-css-prefix}-twitter-square:before { content: @fa-var-twitter-square; }
+.@{fa-css-prefix}-facebook-square:before { content: @fa-var-facebook-square; }
+.@{fa-css-prefix}-camera-retro:before { content: @fa-var-camera-retro; }
+.@{fa-css-prefix}-key:before { content: @fa-var-key; }
+.@{fa-css-prefix}-gears:before,
+.@{fa-css-prefix}-cogs:before { content: @fa-var-cogs; }
+.@{fa-css-prefix}-comments:before { content: @fa-var-comments; }
+.@{fa-css-prefix}-thumbs-o-up:before { content: @fa-var-thumbs-o-up; }
+.@{fa-css-prefix}-thumbs-o-down:before { content: @fa-var-thumbs-o-down; }
+.@{fa-css-prefix}-star-half:before { content: @fa-var-star-half; }
+.@{fa-css-prefix}-heart-o:before { content: @fa-var-heart-o; }
+.@{fa-css-prefix}-sign-out:before { content: @fa-var-sign-out; }
+.@{fa-css-prefix}-linkedin-square:before { content: @fa-var-linkedin-square; }
+.@{fa-css-prefix}-thumb-tack:before { content: @fa-var-thumb-tack; }
+.@{fa-css-prefix}-external-link:before { content: @fa-var-external-link; }
+.@{fa-css-prefix}-sign-in:before { content: @fa-var-sign-in; }
+.@{fa-css-prefix}-trophy:before { content: @fa-var-trophy; }
+.@{fa-css-prefix}-github-square:before { content: @fa-var-github-square; }
+.@{fa-css-prefix}-upload:before { content: @fa-var-upload; }
+.@{fa-css-prefix}-lemon-o:before { content: @fa-var-lemon-o; }
+.@{fa-css-prefix}-phone:before { content: @fa-var-phone; }
+.@{fa-css-prefix}-square-o:before { content: @fa-var-square-o; }
+.@{fa-css-prefix}-bookmark-o:before { content: @fa-var-bookmark-o; }
+.@{fa-css-prefix}-phone-square:before { content: @fa-var-phone-square; }
+.@{fa-css-prefix}-twitter:before { content: @fa-var-twitter; }
+.@{fa-css-prefix}-facebook:before { content: @fa-var-facebook; }
+.@{fa-css-prefix}-github:before { content: @fa-var-github; }
+.@{fa-css-prefix}-unlock:before { content: @fa-var-unlock; }
+.@{fa-css-prefix}-credit-card:before { content: @fa-var-credit-card; }
+.@{fa-css-prefix}-rss:before { content: @fa-var-rss; }
+.@{fa-css-prefix}-hdd-o:before { content: @fa-var-hdd-o; }
+.@{fa-css-prefix}-bullhorn:before { content: @fa-var-bullhorn; }
+.@{fa-css-prefix}-bell:before { content: @fa-var-bell; }
+.@{fa-css-prefix}-certificate:before { content: @fa-var-certificate; }
+.@{fa-css-prefix}-hand-o-right:before { content: @fa-var-hand-o-right; }
+.@{fa-css-prefix}-hand-o-left:before { content: @fa-var-hand-o-left; }
+.@{fa-css-prefix}-hand-o-up:before { content: @fa-var-hand-o-up; }
+.@{fa-css-prefix}-hand-o-down:before { content: @fa-var-hand-o-down; }
+.@{fa-css-prefix}-arrow-circle-left:before { content: @fa-var-arrow-circle-left; }
+.@{fa-css-prefix}-arrow-circle-right:before { content: @fa-var-arrow-circle-right; }
+.@{fa-css-prefix}-arrow-circle-up:before { content: @fa-var-arrow-circle-up; }
+.@{fa-css-prefix}-arrow-circle-down:before { content: @fa-var-arrow-circle-down; }
+.@{fa-css-prefix}-globe:before { content: @fa-var-globe; }
+.@{fa-css-prefix}-wrench:before { content: @fa-var-wrench; }
+.@{fa-css-prefix}-tasks:before { content: @fa-var-tasks; }
+.@{fa-css-prefix}-filter:before { content: @fa-var-filter; }
+.@{fa-css-prefix}-briefcase:before { content: @fa-var-briefcase; }
+.@{fa-css-prefix}-arrows-alt:before { content: @fa-var-arrows-alt; }
+.@{fa-css-prefix}-group:before,
+.@{fa-css-prefix}-users:before { content: @fa-var-users; }
+.@{fa-css-prefix}-chain:before,
+.@{fa-css-prefix}-link:before { content: @fa-var-link; }
+.@{fa-css-prefix}-cloud:before { content: @fa-var-cloud; }
+.@{fa-css-prefix}-flask:before { content: @fa-var-flask; }
+.@{fa-css-prefix}-cut:before,
+.@{fa-css-prefix}-scissors:before { content: @fa-var-scissors; }
+.@{fa-css-prefix}-copy:before,
+.@{fa-css-prefix}-files-o:before { content: @fa-var-files-o; }
+.@{fa-css-prefix}-paperclip:before { content: @fa-var-paperclip; }
+.@{fa-css-prefix}-save:before,
+.@{fa-css-prefix}-floppy-o:before { content: @fa-var-floppy-o; }
+.@{fa-css-prefix}-square:before { content: @fa-var-square; }
+.@{fa-css-prefix}-navicon:before,
+.@{fa-css-prefix}-reorder:before,
+.@{fa-css-prefix}-bars:before { content: @fa-var-bars; }
+.@{fa-css-prefix}-list-ul:before { content: @fa-var-list-ul; }
+.@{fa-css-prefix}-list-ol:before { content: @fa-var-list-ol; }
+.@{fa-css-prefix}-strikethrough:before { content: @fa-var-strikethrough; }
+.@{fa-css-prefix}-underline:before { content: @fa-var-underline; }
+.@{fa-css-prefix}-table:before { content: @fa-var-table; }
+.@{fa-css-prefix}-magic:before { content: @fa-var-magic; }
+.@{fa-css-prefix}-truck:before { content: @fa-var-truck; }
+.@{fa-css-prefix}-pinterest:before { content: @fa-var-pinterest; }
+.@{fa-css-prefix}-pinterest-square:before { content: @fa-var-pinterest-square; }
+.@{fa-css-prefix}-google-plus-square:before { content: @fa-var-google-plus-square; }
+.@{fa-css-prefix}-google-plus:before { content: @fa-var-google-plus; }
+.@{fa-css-prefix}-money:before { content: @fa-var-money; }
+.@{fa-css-prefix}-caret-down:before { content: @fa-var-caret-down; }
+.@{fa-css-prefix}-caret-up:before { content: @fa-var-caret-up; }
+.@{fa-css-prefix}-caret-left:before { content: @fa-var-caret-left; }
+.@{fa-css-prefix}-caret-right:before { content: @fa-var-caret-right; }
+.@{fa-css-prefix}-columns:before { content: @fa-var-columns; }
+.@{fa-css-prefix}-unsorted:before,
+.@{fa-css-prefix}-sort:before { content: @fa-var-sort; }
+.@{fa-css-prefix}-sort-down:before,
+.@{fa-css-prefix}-sort-desc:before { content: @fa-var-sort-desc; }
+.@{fa-css-prefix}-sort-up:before,
+.@{fa-css-prefix}-sort-asc:before { content: @fa-var-sort-asc; }
+.@{fa-css-prefix}-envelope:before { content: @fa-var-envelope; }
+.@{fa-css-prefix}-linkedin:before { content: @fa-var-linkedin; }
+.@{fa-css-prefix}-rotate-left:before,
+.@{fa-css-prefix}-undo:before { content: @fa-var-undo; }
+.@{fa-css-prefix}-legal:before,
+.@{fa-css-prefix}-gavel:before { content: @fa-var-gavel; }
+.@{fa-css-prefix}-dashboard:before,
+.@{fa-css-prefix}-tachometer:before { content: @fa-var-tachometer; }
+.@{fa-css-prefix}-comment-o:before { content: @fa-var-comment-o; }
+.@{fa-css-prefix}-comments-o:before { content: @fa-var-comments-o; }
+.@{fa-css-prefix}-flash:before,
+.@{fa-css-prefix}-bolt:before { content: @fa-var-bolt; }
+.@{fa-css-prefix}-sitemap:before { content: @fa-var-sitemap; }
+.@{fa-css-prefix}-umbrella:before { content: @fa-var-umbrella; }
+.@{fa-css-prefix}-paste:before,
+.@{fa-css-prefix}-clipboard:before { content: @fa-var-clipboard; }
+.@{fa-css-prefix}-lightbulb-o:before { content: @fa-var-lightbulb-o; }
+.@{fa-css-prefix}-exchange:before { content: @fa-var-exchange; }
+.@{fa-css-prefix}-cloud-download:before { content: @fa-var-cloud-download; }
+.@{fa-css-prefix}-cloud-upload:before { content: @fa-var-cloud-upload; }
+.@{fa-css-prefix}-user-md:before { content: @fa-var-user-md; }
+.@{fa-css-prefix}-stethoscope:before { content: @fa-var-stethoscope; }
+.@{fa-css-prefix}-suitcase:before { content: @fa-var-suitcase; }
+.@{fa-css-prefix}-bell-o:before { content: @fa-var-bell-o; }
+.@{fa-css-prefix}-coffee:before { content: @fa-var-coffee; }
+.@{fa-css-prefix}-cutlery:before { content: @fa-var-cutlery; }
+.@{fa-css-prefix}-file-text-o:before { content: @fa-var-file-text-o; }
+.@{fa-css-prefix}-building-o:before { content: @fa-var-building-o; }
+.@{fa-css-prefix}-hospital-o:before { content: @fa-var-hospital-o; }
+.@{fa-css-prefix}-ambulance:before { content: @fa-var-ambulance; }
+.@{fa-css-prefix}-medkit:before { content: @fa-var-medkit; }
+.@{fa-css-prefix}-fighter-jet:before { content: @fa-var-fighter-jet; }
+.@{fa-css-prefix}-beer:before { content: @fa-var-beer; }
+.@{fa-css-prefix}-h-square:before { content: @fa-var-h-square; }
+.@{fa-css-prefix}-plus-square:before { content: @fa-var-plus-square; }
+.@{fa-css-prefix}-angle-double-left:before { content: @fa-var-angle-double-left; }
+.@{fa-css-prefix}-angle-double-right:before { content: @fa-var-angle-double-right; }
+.@{fa-css-prefix}-angle-double-up:before { content: @fa-var-angle-double-up; }
+.@{fa-css-prefix}-angle-double-down:before { content: @fa-var-angle-double-down; }
+.@{fa-css-prefix}-angle-left:before { content: @fa-var-angle-left; }
+.@{fa-css-prefix}-angle-right:before { content: @fa-var-angle-right; }
+.@{fa-css-prefix}-angle-up:before { content: @fa-var-angle-up; }
+.@{fa-css-prefix}-angle-down:before { content: @fa-var-angle-down; }
+.@{fa-css-prefix}-desktop:before { content: @fa-var-desktop; }
+.@{fa-css-prefix}-laptop:before { content: @fa-var-laptop; }
+.@{fa-css-prefix}-tablet:before { content: @fa-var-tablet; }
+.@{fa-css-prefix}-mobile-phone:before,
+.@{fa-css-prefix}-mobile:before { content: @fa-var-mobile; }
+.@{fa-css-prefix}-circle-o:before { content: @fa-var-circle-o; }
+.@{fa-css-prefix}-quote-left:before { content: @fa-var-quote-left; }
+.@{fa-css-prefix}-quote-right:before { content: @fa-var-quote-right; }
+.@{fa-css-prefix}-spinner:before { content: @fa-var-spinner; }
+.@{fa-css-prefix}-circle:before { content: @fa-var-circle; }
+.@{fa-css-prefix}-mail-reply:before,
+.@{fa-css-prefix}-reply:before { content: @fa-var-reply; }
+.@{fa-css-prefix}-github-alt:before { content: @fa-var-github-alt; }
+.@{fa-css-prefix}-folder-o:before { content: @fa-var-folder-o; }
+.@{fa-css-prefix}-folder-open-o:before { content: @fa-var-folder-open-o; }
+.@{fa-css-prefix}-smile-o:before { content: @fa-var-smile-o; }
+.@{fa-css-prefix}-frown-o:before { content: @fa-var-frown-o; }
+.@{fa-css-prefix}-meh-o:before { content: @fa-var-meh-o; }
+.@{fa-css-prefix}-gamepad:before { content: @fa-var-gamepad; }
+.@{fa-css-prefix}-keyboard-o:before { content: @fa-var-keyboard-o; }
+.@{fa-css-prefix}-flag-o:before { content: @fa-var-flag-o; }
+.@{fa-css-prefix}-flag-checkered:before { content: @fa-var-flag-checkered; }
+.@{fa-css-prefix}-terminal:before { content: @fa-var-terminal; }
+.@{fa-css-prefix}-code:before { content: @fa-var-code; }
+.@{fa-css-prefix}-mail-reply-all:before,
+.@{fa-css-prefix}-reply-all:before { content: @fa-var-reply-all; }
+.@{fa-css-prefix}-star-half-empty:before,
+.@{fa-css-prefix}-star-half-full:before,
+.@{fa-css-prefix}-star-half-o:before { content: @fa-var-star-half-o; }
+.@{fa-css-prefix}-location-arrow:before { content: @fa-var-location-arrow; }
+.@{fa-css-prefix}-crop:before { content: @fa-var-crop; }
+.@{fa-css-prefix}-code-fork:before { content: @fa-var-code-fork; }
+.@{fa-css-prefix}-unlink:before,
+.@{fa-css-prefix}-chain-broken:before { content: @fa-var-chain-broken; }
+.@{fa-css-prefix}-question:before { content: @fa-var-question; }
+.@{fa-css-prefix}-info:before { content: @fa-var-info; }
+.@{fa-css-prefix}-exclamation:before { content: @fa-var-exclamation; }
+.@{fa-css-prefix}-superscript:before { content: @fa-var-superscript; }
+.@{fa-css-prefix}-subscript:before { content: @fa-var-subscript; }
+.@{fa-css-prefix}-eraser:before { content: @fa-var-eraser; }
+.@{fa-css-prefix}-puzzle-piece:before { content: @fa-var-puzzle-piece; }
+.@{fa-css-prefix}-microphone:before { content: @fa-var-microphone; }
+.@{fa-css-prefix}-microphone-slash:before { content: @fa-var-microphone-slash; }
+.@{fa-css-prefix}-shield:before { content: @fa-var-shield; }
+.@{fa-css-prefix}-calendar-o:before { content: @fa-var-calendar-o; }
+.@{fa-css-prefix}-fire-extinguisher:before { content: @fa-var-fire-extinguisher; }
+.@{fa-css-prefix}-rocket:before { content: @fa-var-rocket; }
+.@{fa-css-prefix}-maxcdn:before { content: @fa-var-maxcdn; }
+.@{fa-css-prefix}-chevron-circle-left:before { content: @fa-var-chevron-circle-left; }
+.@{fa-css-prefix}-chevron-circle-right:before { content: @fa-var-chevron-circle-right; }
+.@{fa-css-prefix}-chevron-circle-up:before { content: @fa-var-chevron-circle-up; }
+.@{fa-css-prefix}-chevron-circle-down:before { content: @fa-var-chevron-circle-down; }
+.@{fa-css-prefix}-html5:before { content: @fa-var-html5; }
+.@{fa-css-prefix}-css3:before { content: @fa-var-css3; }
+.@{fa-css-prefix}-anchor:before { content: @fa-var-anchor; }
+.@{fa-css-prefix}-unlock-alt:before { content: @fa-var-unlock-alt; }
+.@{fa-css-prefix}-bullseye:before { content: @fa-var-bullseye; }
+.@{fa-css-prefix}-ellipsis-h:before { content: @fa-var-ellipsis-h; }
+.@{fa-css-prefix}-ellipsis-v:before { content: @fa-var-ellipsis-v; }
+.@{fa-css-prefix}-rss-square:before { content: @fa-var-rss-square; }
+.@{fa-css-prefix}-play-circle:before { content: @fa-var-play-circle; }
+.@{fa-css-prefix}-ticket:before { content: @fa-var-ticket; }
+.@{fa-css-prefix}-minus-square:before { content: @fa-var-minus-square; }
+.@{fa-css-prefix}-minus-square-o:before { content: @fa-var-minus-square-o; }
+.@{fa-css-prefix}-level-up:before { content: @fa-var-level-up; }
+.@{fa-css-prefix}-level-down:before { content: @fa-var-level-down; }
+.@{fa-css-prefix}-check-square:before { content: @fa-var-check-square; }
+.@{fa-css-prefix}-pencil-square:before { content: @fa-var-pencil-square; }
+.@{fa-css-prefix}-external-link-square:before { content: @fa-var-external-link-square; }
+.@{fa-css-prefix}-share-square:before { content: @fa-var-share-square; }
+.@{fa-css-prefix}-compass:before { content: @fa-var-compass; }
+.@{fa-css-prefix}-toggle-down:before,
+.@{fa-css-prefix}-caret-square-o-down:before { content: @fa-var-caret-square-o-down; }
+.@{fa-css-prefix}-toggle-up:before,
+.@{fa-css-prefix}-caret-square-o-up:before { content: @fa-var-caret-square-o-up; }
+.@{fa-css-prefix}-toggle-right:before,
+.@{fa-css-prefix}-caret-square-o-right:before { content: @fa-var-caret-square-o-right; }
+.@{fa-css-prefix}-euro:before,
+.@{fa-css-prefix}-eur:before { content: @fa-var-eur; }
+.@{fa-css-prefix}-gbp:before { content: @fa-var-gbp; }
+.@{fa-css-prefix}-dollar:before,
+.@{fa-css-prefix}-usd:before { content: @fa-var-usd; }
+.@{fa-css-prefix}-rupee:before,
+.@{fa-css-prefix}-inr:before { content: @fa-var-inr; }
+.@{fa-css-prefix}-cny:before,
+.@{fa-css-prefix}-rmb:before,
+.@{fa-css-prefix}-yen:before,
+.@{fa-css-prefix}-jpy:before { content: @fa-var-jpy; }
+.@{fa-css-prefix}-ruble:before,
+.@{fa-css-prefix}-rouble:before,
+.@{fa-css-prefix}-rub:before { content: @fa-var-rub; }
+.@{fa-css-prefix}-won:before,
+.@{fa-css-prefix}-krw:before { content: @fa-var-krw; }
+.@{fa-css-prefix}-bitcoin:before,
+.@{fa-css-prefix}-btc:before { content: @fa-var-btc; }
+.@{fa-css-prefix}-file:before { content: @fa-var-file; }
+.@{fa-css-prefix}-file-text:before { content: @fa-var-file-text; }
+.@{fa-css-prefix}-sort-alpha-asc:before { content: @fa-var-sort-alpha-asc; }
+.@{fa-css-prefix}-sort-alpha-desc:before { content: @fa-var-sort-alpha-desc; }
+.@{fa-css-prefix}-sort-amount-asc:before { content: @fa-var-sort-amount-asc; }
+.@{fa-css-prefix}-sort-amount-desc:before { content: @fa-var-sort-amount-desc; }
+.@{fa-css-prefix}-sort-numeric-asc:before { content: @fa-var-sort-numeric-asc; }
+.@{fa-css-prefix}-sort-numeric-desc:before { content: @fa-var-sort-numeric-desc; }
+.@{fa-css-prefix}-thumbs-up:before { content: @fa-var-thumbs-up; }
+.@{fa-css-prefix}-thumbs-down:before { content: @fa-var-thumbs-down; }
+.@{fa-css-prefix}-youtube-square:before { content: @fa-var-youtube-square; }
+.@{fa-css-prefix}-youtube:before { content: @fa-var-youtube; }
+.@{fa-css-prefix}-xing:before { content: @fa-var-xing; }
+.@{fa-css-prefix}-xing-square:before { content: @fa-var-xing-square; }
+.@{fa-css-prefix}-youtube-play:before { content: @fa-var-youtube-play; }
+.@{fa-css-prefix}-dropbox:before { content: @fa-var-dropbox; }
+.@{fa-css-prefix}-stack-overflow:before { content: @fa-var-stack-overflow; }
+.@{fa-css-prefix}-instagram:before { content: @fa-var-instagram; }
+.@{fa-css-prefix}-flickr:before { content: @fa-var-flickr; }
+.@{fa-css-prefix}-adn:before { content: @fa-var-adn; }
+.@{fa-css-prefix}-bitbucket:before { content: @fa-var-bitbucket; }
+.@{fa-css-prefix}-bitbucket-square:before { content: @fa-var-bitbucket-square; }
+.@{fa-css-prefix}-tumblr:before { content: @fa-var-tumblr; }
+.@{fa-css-prefix}-tumblr-square:before { content: @fa-var-tumblr-square; }
+.@{fa-css-prefix}-long-arrow-down:before { content: @fa-var-long-arrow-down; }
+.@{fa-css-prefix}-long-arrow-up:before { content: @fa-var-long-arrow-up; }
+.@{fa-css-prefix}-long-arrow-left:before { content: @fa-var-long-arrow-left; }
+.@{fa-css-prefix}-long-arrow-right:before { content: @fa-var-long-arrow-right; }
+.@{fa-css-prefix}-apple:before { content: @fa-var-apple; }
+.@{fa-css-prefix}-windows:before { content: @fa-var-windows; }
+.@{fa-css-prefix}-android:before { content: @fa-var-android; }
+.@{fa-css-prefix}-linux:before { content: @fa-var-linux; }
+.@{fa-css-prefix}-dribbble:before { content: @fa-var-dribbble; }
+.@{fa-css-prefix}-skype:before { content: @fa-var-skype; }
+.@{fa-css-prefix}-foursquare:before { content: @fa-var-foursquare; }
+.@{fa-css-prefix}-trello:before { content: @fa-var-trello; }
+.@{fa-css-prefix}-female:before { content: @fa-var-female; }
+.@{fa-css-prefix}-male:before { content: @fa-var-male; }
+.@{fa-css-prefix}-gittip:before { content: @fa-var-gittip; }
+.@{fa-css-prefix}-sun-o:before { content: @fa-var-sun-o; }
+.@{fa-css-prefix}-moon-o:before { content: @fa-var-moon-o; }
+.@{fa-css-prefix}-archive:before { content: @fa-var-archive; }
+.@{fa-css-prefix}-bug:before { content: @fa-var-bug; }
+.@{fa-css-prefix}-vk:before { content: @fa-var-vk; }
+.@{fa-css-prefix}-weibo:before { content: @fa-var-weibo; }
+.@{fa-css-prefix}-renren:before { content: @fa-var-renren; }
+.@{fa-css-prefix}-pagelines:before { content: @fa-var-pagelines; }
+.@{fa-css-prefix}-stack-exchange:before { content: @fa-var-stack-exchange; }
+.@{fa-css-prefix}-arrow-circle-o-right:before { content: @fa-var-arrow-circle-o-right; }
+.@{fa-css-prefix}-arrow-circle-o-left:before { content: @fa-var-arrow-circle-o-left; }
+.@{fa-css-prefix}-toggle-left:before,
+.@{fa-css-prefix}-caret-square-o-left:before { content: @fa-var-caret-square-o-left; }
+.@{fa-css-prefix}-dot-circle-o:before { content: @fa-var-dot-circle-o; }
+.@{fa-css-prefix}-wheelchair:before { content: @fa-var-wheelchair; }
+.@{fa-css-prefix}-vimeo-square:before { content: @fa-var-vimeo-square; }
+.@{fa-css-prefix}-turkish-lira:before,
+.@{fa-css-prefix}-try:before { content: @fa-var-try; }
+.@{fa-css-prefix}-plus-square-o:before { content: @fa-var-plus-square-o; }
+.@{fa-css-prefix}-space-shuttle:before { content: @fa-var-space-shuttle; }
+.@{fa-css-prefix}-slack:before { content: @fa-var-slack; }
+.@{fa-css-prefix}-envelope-square:before { content: @fa-var-envelope-square; }
+.@{fa-css-prefix}-wordpress:before { content: @fa-var-wordpress; }
+.@{fa-css-prefix}-openid:before { content: @fa-var-openid; }
+.@{fa-css-prefix}-institution:before,
+.@{fa-css-prefix}-bank:before,
+.@{fa-css-prefix}-university:before { content: @fa-var-university; }
+.@{fa-css-prefix}-mortar-board:before,
+.@{fa-css-prefix}-graduation-cap:before { content: @fa-var-graduation-cap; }
+.@{fa-css-prefix}-yahoo:before { content: @fa-var-yahoo; }
+.@{fa-css-prefix}-google:before { content: @fa-var-google; }
+.@{fa-css-prefix}-reddit:before { content: @fa-var-reddit; }
+.@{fa-css-prefix}-reddit-square:before { content: @fa-var-reddit-square; }
+.@{fa-css-prefix}-stumbleupon-circle:before { content: @fa-var-stumbleupon-circle; }
+.@{fa-css-prefix}-stumbleupon:before { content: @fa-var-stumbleupon; }
+.@{fa-css-prefix}-delicious:before { content: @fa-var-delicious; }
+.@{fa-css-prefix}-digg:before { content: @fa-var-digg; }
+.@{fa-css-prefix}-pied-piper-square:before,
+.@{fa-css-prefix}-pied-piper:before { content: @fa-var-pied-piper; }
+.@{fa-css-prefix}-pied-piper-alt:before { content: @fa-var-pied-piper-alt; }
+.@{fa-css-prefix}-drupal:before { content: @fa-var-drupal; }
+.@{fa-css-prefix}-joomla:before { content: @fa-var-joomla; }
+.@{fa-css-prefix}-language:before { content: @fa-var-language; }
+.@{fa-css-prefix}-fax:before { content: @fa-var-fax; }
+.@{fa-css-prefix}-building:before { content: @fa-var-building; }
+.@{fa-css-prefix}-child:before { content: @fa-var-child; }
+.@{fa-css-prefix}-paw:before { content: @fa-var-paw; }
+.@{fa-css-prefix}-spoon:before { content: @fa-var-spoon; }
+.@{fa-css-prefix}-cube:before { content: @fa-var-cube; }
+.@{fa-css-prefix}-cubes:before { content: @fa-var-cubes; }
+.@{fa-css-prefix}-behance:before { content: @fa-var-behance; }
+.@{fa-css-prefix}-behance-square:before { content: @fa-var-behance-square; }
+.@{fa-css-prefix}-steam:before { content: @fa-var-steam; }
+.@{fa-css-prefix}-steam-square:before { content: @fa-var-steam-square; }
+.@{fa-css-prefix}-recycle:before { content: @fa-var-recycle; }
+.@{fa-css-prefix}-automobile:before,
+.@{fa-css-prefix}-car:before { content: @fa-var-car; }
+.@{fa-css-prefix}-cab:before,
+.@{fa-css-prefix}-taxi:before { content: @fa-var-taxi; }
+.@{fa-css-prefix}-tree:before { content: @fa-var-tree; }
+.@{fa-css-prefix}-spotify:before { content: @fa-var-spotify; }
+.@{fa-css-prefix}-deviantart:before { content: @fa-var-deviantart; }
+.@{fa-css-prefix}-soundcloud:before { content: @fa-var-soundcloud; }
+.@{fa-css-prefix}-database:before { content: @fa-var-database; }
+.@{fa-css-prefix}-file-pdf-o:before { content: @fa-var-file-pdf-o; }
+.@{fa-css-prefix}-file-word-o:before { content: @fa-var-file-word-o; }
+.@{fa-css-prefix}-file-excel-o:before { content: @fa-var-file-excel-o; }
+.@{fa-css-prefix}-file-powerpoint-o:before { content: @fa-var-file-powerpoint-o; }
+.@{fa-css-prefix}-file-photo-o:before,
+.@{fa-css-prefix}-file-picture-o:before,
+.@{fa-css-prefix}-file-image-o:before { content: @fa-var-file-image-o; }
+.@{fa-css-prefix}-file-zip-o:before,
+.@{fa-css-prefix}-file-archive-o:before { content: @fa-var-file-archive-o; }
+.@{fa-css-prefix}-file-sound-o:before,
+.@{fa-css-prefix}-file-audio-o:before { content: @fa-var-file-audio-o; }
+.@{fa-css-prefix}-file-movie-o:before,
+.@{fa-css-prefix}-file-video-o:before { content: @fa-var-file-video-o; }
+.@{fa-css-prefix}-file-code-o:before { content: @fa-var-file-code-o; }
+.@{fa-css-prefix}-vine:before { content: @fa-var-vine; }
+.@{fa-css-prefix}-codepen:before { content: @fa-var-codepen; }
+.@{fa-css-prefix}-jsfiddle:before { content: @fa-var-jsfiddle; }
+.@{fa-css-prefix}-life-bouy:before,
+.@{fa-css-prefix}-life-saver:before,
+.@{fa-css-prefix}-support:before,
+.@{fa-css-prefix}-life-ring:before { content: @fa-var-life-ring; }
+.@{fa-css-prefix}-circle-o-notch:before { content: @fa-var-circle-o-notch; }
+.@{fa-css-prefix}-ra:before,
+.@{fa-css-prefix}-rebel:before { content: @fa-var-rebel; }
+.@{fa-css-prefix}-ge:before,
+.@{fa-css-prefix}-empire:before { content: @fa-var-empire; }
+.@{fa-css-prefix}-git-square:before { content: @fa-var-git-square; }
+.@{fa-css-prefix}-git:before { content: @fa-var-git; }
+.@{fa-css-prefix}-hacker-news:before { content: @fa-var-hacker-news; }
+.@{fa-css-prefix}-tencent-weibo:before { content: @fa-var-tencent-weibo; }
+.@{fa-css-prefix}-qq:before { content: @fa-var-qq; }
+.@{fa-css-prefix}-wechat:before,
+.@{fa-css-prefix}-weixin:before { content: @fa-var-weixin; }
+.@{fa-css-prefix}-send:before,
+.@{fa-css-prefix}-paper-plane:before { content: @fa-var-paper-plane; }
+.@{fa-css-prefix}-send-o:before,
+.@{fa-css-prefix}-paper-plane-o:before { content: @fa-var-paper-plane-o; }
+.@{fa-css-prefix}-history:before { content: @fa-var-history; }
+.@{fa-css-prefix}-circle-thin:before { content: @fa-var-circle-thin; }
+.@{fa-css-prefix}-header:before { content: @fa-var-header; }
+.@{fa-css-prefix}-paragraph:before { content: @fa-var-paragraph; }
+.@{fa-css-prefix}-sliders:before { content: @fa-var-sliders; }
+.@{fa-css-prefix}-share-alt:before { content: @fa-var-share-alt; }
+.@{fa-css-prefix}-share-alt-square:before { content: @fa-var-share-alt-square; }
+.@{fa-css-prefix}-bomb:before { content: @fa-var-bomb; }
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/larger.less b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/larger.less
new file mode 100755
index 0000000..c9d6467
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/larger.less
@@ -0,0 +1,13 @@
+// Icon Sizes
+// -------------------------
+
+/* makes the font 33% larger relative to the icon container */
+.@{fa-css-prefix}-lg {
+ font-size: (4em / 3);
+ line-height: (3em / 4);
+ vertical-align: -15%;
+}
+.@{fa-css-prefix}-2x { font-size: 2em; }
+.@{fa-css-prefix}-3x { font-size: 3em; }
+.@{fa-css-prefix}-4x { font-size: 4em; }
+.@{fa-css-prefix}-5x { font-size: 5em; }
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/list.less b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/list.less
new file mode 100755
index 0000000..eed9340
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/list.less
@@ -0,0 +1,19 @@
+// List Icons
+// -------------------------
+
+.@{fa-css-prefix}-ul {
+ padding-left: 0;
+ margin-left: @fa-li-width;
+ list-style-type: none;
+ > li { position: relative; }
+}
+.@{fa-css-prefix}-li {
+ position: absolute;
+ left: -@fa-li-width;
+ width: @fa-li-width;
+ top: (2em / 14);
+ text-align: center;
+ &.@{fa-css-prefix}-lg {
+ left: -@fa-li-width + (4em / 14);
+ }
+}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/mixins.less b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/mixins.less
new file mode 100755
index 0000000..19e5a64
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/mixins.less
@@ -0,0 +1,20 @@
+// Mixins
+// --------------------------
+
+.fa-icon-rotate(@degrees, @rotation) {
+ filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation);
+ -webkit-transform: rotate(@degrees);
+ -moz-transform: rotate(@degrees);
+ -ms-transform: rotate(@degrees);
+ -o-transform: rotate(@degrees);
+ transform: rotate(@degrees);
+}
+
+.fa-icon-flip(@horiz, @vert, @rotation) {
+ filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation, mirror=1);
+ -webkit-transform: scale(@horiz, @vert);
+ -moz-transform: scale(@horiz, @vert);
+ -ms-transform: scale(@horiz, @vert);
+ -o-transform: scale(@horiz, @vert);
+ transform: scale(@horiz, @vert);
+}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/path.less b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/path.less
new file mode 100755
index 0000000..d73bff8
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/path.less
@@ -0,0 +1,14 @@
+/* FONT PATH
+ * -------------------------- */
+
+@font-face {
+ font-family: 'FontAwesome';
+ src: ~"url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}')";
+ src: ~"url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype')",
+ ~"url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff')",
+ ~"url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype')",
+ ~"url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg')";
+// src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
+ font-weight: normal;
+ font-style: normal;
+}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/rotated-flipped.less b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/rotated-flipped.less
new file mode 100755
index 0000000..8fff3a6
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/rotated-flipped.less
@@ -0,0 +1,9 @@
+// Rotated & Flipped Icons
+// -------------------------
+
+.@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); }
+.@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
+.@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
+
+.@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
+.@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); }
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/spinning.less b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/spinning.less
new file mode 100755
index 0000000..06b71ec
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/spinning.less
@@ -0,0 +1,32 @@
+// Spinning Icons
+// --------------------------
+
+.@{fa-css-prefix}-spin {
+ -webkit-animation: spin 2s infinite linear;
+ -moz-animation: spin 2s infinite linear;
+ -o-animation: spin 2s infinite linear;
+ animation: spin 2s infinite linear;
+}
+
+@-moz-keyframes spin {
+ 0% { -moz-transform: rotate(0deg); }
+ 100% { -moz-transform: rotate(359deg); }
+}
+@-webkit-keyframes spin {
+ 0% { -webkit-transform: rotate(0deg); }
+ 100% { -webkit-transform: rotate(359deg); }
+}
+@-o-keyframes spin {
+ 0% { -o-transform: rotate(0deg); }
+ 100% { -o-transform: rotate(359deg); }
+}
+@keyframes spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/stacked.less b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/stacked.less
new file mode 100755
index 0000000..fc53fb0
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/stacked.less
@@ -0,0 +1,20 @@
+// Stacked Icons
+// -------------------------
+
+.@{fa-css-prefix}-stack {
+ position: relative;
+ display: inline-block;
+ width: 2em;
+ height: 2em;
+ line-height: 2em;
+ vertical-align: middle;
+}
+.@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
+ position: absolute;
+ left: 0;
+ width: 100%;
+ text-align: center;
+}
+.@{fa-css-prefix}-stack-1x { line-height: inherit; }
+.@{fa-css-prefix}-stack-2x { font-size: 2em; }
+.@{fa-css-prefix}-inverse { color: @fa-inverse; }
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/variables.less b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/variables.less
new file mode 100755
index 0000000..d7e8bd7
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/less/variables.less
@@ -0,0 +1,515 @@
+// Variables
+// --------------------------
+
+@fa-font-path: "../fonts";
+//@fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.1.0/fonts"; // for referencing Bootstrap CDN font files directly
+@fa-css-prefix: fa;
+@fa-version: "4.1.0";
+@fa-border-color: #eee;
+@fa-inverse: #fff;
+@fa-li-width: (30em / 14);
+
+@fa-var-adjust: "\f042";
+@fa-var-adn: "\f170";
+@fa-var-align-center: "\f037";
+@fa-var-align-justify: "\f039";
+@fa-var-align-left: "\f036";
+@fa-var-align-right: "\f038";
+@fa-var-ambulance: "\f0f9";
+@fa-var-anchor: "\f13d";
+@fa-var-android: "\f17b";
+@fa-var-angle-double-down: "\f103";
+@fa-var-angle-double-left: "\f100";
+@fa-var-angle-double-right: "\f101";
+@fa-var-angle-double-up: "\f102";
+@fa-var-angle-down: "\f107";
+@fa-var-angle-left: "\f104";
+@fa-var-angle-right: "\f105";
+@fa-var-angle-up: "\f106";
+@fa-var-apple: "\f179";
+@fa-var-archive: "\f187";
+@fa-var-arrow-circle-down: "\f0ab";
+@fa-var-arrow-circle-left: "\f0a8";
+@fa-var-arrow-circle-o-down: "\f01a";
+@fa-var-arrow-circle-o-left: "\f190";
+@fa-var-arrow-circle-o-right: "\f18e";
+@fa-var-arrow-circle-o-up: "\f01b";
+@fa-var-arrow-circle-right: "\f0a9";
+@fa-var-arrow-circle-up: "\f0aa";
+@fa-var-arrow-down: "\f063";
+@fa-var-arrow-left: "\f060";
+@fa-var-arrow-right: "\f061";
+@fa-var-arrow-up: "\f062";
+@fa-var-arrows: "\f047";
+@fa-var-arrows-alt: "\f0b2";
+@fa-var-arrows-h: "\f07e";
+@fa-var-arrows-v: "\f07d";
+@fa-var-asterisk: "\f069";
+@fa-var-automobile: "\f1b9";
+@fa-var-backward: "\f04a";
+@fa-var-ban: "\f05e";
+@fa-var-bank: "\f19c";
+@fa-var-bar-chart-o: "\f080";
+@fa-var-barcode: "\f02a";
+@fa-var-bars: "\f0c9";
+@fa-var-beer: "\f0fc";
+@fa-var-behance: "\f1b4";
+@fa-var-behance-square: "\f1b5";
+@fa-var-bell: "\f0f3";
+@fa-var-bell-o: "\f0a2";
+@fa-var-bitbucket: "\f171";
+@fa-var-bitbucket-square: "\f172";
+@fa-var-bitcoin: "\f15a";
+@fa-var-bold: "\f032";
+@fa-var-bolt: "\f0e7";
+@fa-var-bomb: "\f1e2";
+@fa-var-book: "\f02d";
+@fa-var-bookmark: "\f02e";
+@fa-var-bookmark-o: "\f097";
+@fa-var-briefcase: "\f0b1";
+@fa-var-btc: "\f15a";
+@fa-var-bug: "\f188";
+@fa-var-building: "\f1ad";
+@fa-var-building-o: "\f0f7";
+@fa-var-bullhorn: "\f0a1";
+@fa-var-bullseye: "\f140";
+@fa-var-cab: "\f1ba";
+@fa-var-calendar: "\f073";
+@fa-var-calendar-o: "\f133";
+@fa-var-camera: "\f030";
+@fa-var-camera-retro: "\f083";
+@fa-var-car: "\f1b9";
+@fa-var-caret-down: "\f0d7";
+@fa-var-caret-left: "\f0d9";
+@fa-var-caret-right: "\f0da";
+@fa-var-caret-square-o-down: "\f150";
+@fa-var-caret-square-o-left: "\f191";
+@fa-var-caret-square-o-right: "\f152";
+@fa-var-caret-square-o-up: "\f151";
+@fa-var-caret-up: "\f0d8";
+@fa-var-certificate: "\f0a3";
+@fa-var-chain: "\f0c1";
+@fa-var-chain-broken: "\f127";
+@fa-var-check: "\f00c";
+@fa-var-check-circle: "\f058";
+@fa-var-check-circle-o: "\f05d";
+@fa-var-check-square: "\f14a";
+@fa-var-check-square-o: "\f046";
+@fa-var-chevron-circle-down: "\f13a";
+@fa-var-chevron-circle-left: "\f137";
+@fa-var-chevron-circle-right: "\f138";
+@fa-var-chevron-circle-up: "\f139";
+@fa-var-chevron-down: "\f078";
+@fa-var-chevron-left: "\f053";
+@fa-var-chevron-right: "\f054";
+@fa-var-chevron-up: "\f077";
+@fa-var-child: "\f1ae";
+@fa-var-circle: "\f111";
+@fa-var-circle-o: "\f10c";
+@fa-var-circle-o-notch: "\f1ce";
+@fa-var-circle-thin: "\f1db";
+@fa-var-clipboard: "\f0ea";
+@fa-var-clock-o: "\f017";
+@fa-var-cloud: "\f0c2";
+@fa-var-cloud-download: "\f0ed";
+@fa-var-cloud-upload: "\f0ee";
+@fa-var-cny: "\f157";
+@fa-var-code: "\f121";
+@fa-var-code-fork: "\f126";
+@fa-var-codepen: "\f1cb";
+@fa-var-coffee: "\f0f4";
+@fa-var-cog: "\f013";
+@fa-var-cogs: "\f085";
+@fa-var-columns: "\f0db";
+@fa-var-comment: "\f075";
+@fa-var-comment-o: "\f0e5";
+@fa-var-comments: "\f086";
+@fa-var-comments-o: "\f0e6";
+@fa-var-compass: "\f14e";
+@fa-var-compress: "\f066";
+@fa-var-copy: "\f0c5";
+@fa-var-credit-card: "\f09d";
+@fa-var-crop: "\f125";
+@fa-var-crosshairs: "\f05b";
+@fa-var-css3: "\f13c";
+@fa-var-cube: "\f1b2";
+@fa-var-cubes: "\f1b3";
+@fa-var-cut: "\f0c4";
+@fa-var-cutlery: "\f0f5";
+@fa-var-dashboard: "\f0e4";
+@fa-var-database: "\f1c0";
+@fa-var-dedent: "\f03b";
+@fa-var-delicious: "\f1a5";
+@fa-var-desktop: "\f108";
+@fa-var-deviantart: "\f1bd";
+@fa-var-digg: "\f1a6";
+@fa-var-dollar: "\f155";
+@fa-var-dot-circle-o: "\f192";
+@fa-var-download: "\f019";
+@fa-var-dribbble: "\f17d";
+@fa-var-dropbox: "\f16b";
+@fa-var-drupal: "\f1a9";
+@fa-var-edit: "\f044";
+@fa-var-eject: "\f052";
+@fa-var-ellipsis-h: "\f141";
+@fa-var-ellipsis-v: "\f142";
+@fa-var-empire: "\f1d1";
+@fa-var-envelope: "\f0e0";
+@fa-var-envelope-o: "\f003";
+@fa-var-envelope-square: "\f199";
+@fa-var-eraser: "\f12d";
+@fa-var-eur: "\f153";
+@fa-var-euro: "\f153";
+@fa-var-exchange: "\f0ec";
+@fa-var-exclamation: "\f12a";
+@fa-var-exclamation-circle: "\f06a";
+@fa-var-exclamation-triangle: "\f071";
+@fa-var-expand: "\f065";
+@fa-var-external-link: "\f08e";
+@fa-var-external-link-square: "\f14c";
+@fa-var-eye: "\f06e";
+@fa-var-eye-slash: "\f070";
+@fa-var-facebook: "\f09a";
+@fa-var-facebook-square: "\f082";
+@fa-var-fast-backward: "\f049";
+@fa-var-fast-forward: "\f050";
+@fa-var-fax: "\f1ac";
+@fa-var-female: "\f182";
+@fa-var-fighter-jet: "\f0fb";
+@fa-var-file: "\f15b";
+@fa-var-file-archive-o: "\f1c6";
+@fa-var-file-audio-o: "\f1c7";
+@fa-var-file-code-o: "\f1c9";
+@fa-var-file-excel-o: "\f1c3";
+@fa-var-file-image-o: "\f1c5";
+@fa-var-file-movie-o: "\f1c8";
+@fa-var-file-o: "\f016";
+@fa-var-file-pdf-o: "\f1c1";
+@fa-var-file-photo-o: "\f1c5";
+@fa-var-file-picture-o: "\f1c5";
+@fa-var-file-powerpoint-o: "\f1c4";
+@fa-var-file-sound-o: "\f1c7";
+@fa-var-file-text: "\f15c";
+@fa-var-file-text-o: "\f0f6";
+@fa-var-file-video-o: "\f1c8";
+@fa-var-file-word-o: "\f1c2";
+@fa-var-file-zip-o: "\f1c6";
+@fa-var-files-o: "\f0c5";
+@fa-var-film: "\f008";
+@fa-var-filter: "\f0b0";
+@fa-var-fire: "\f06d";
+@fa-var-fire-extinguisher: "\f134";
+@fa-var-flag: "\f024";
+@fa-var-flag-checkered: "\f11e";
+@fa-var-flag-o: "\f11d";
+@fa-var-flash: "\f0e7";
+@fa-var-flask: "\f0c3";
+@fa-var-flickr: "\f16e";
+@fa-var-floppy-o: "\f0c7";
+@fa-var-folder: "\f07b";
+@fa-var-folder-o: "\f114";
+@fa-var-folder-open: "\f07c";
+@fa-var-folder-open-o: "\f115";
+@fa-var-font: "\f031";
+@fa-var-forward: "\f04e";
+@fa-var-foursquare: "\f180";
+@fa-var-frown-o: "\f119";
+@fa-var-gamepad: "\f11b";
+@fa-var-gavel: "\f0e3";
+@fa-var-gbp: "\f154";
+@fa-var-ge: "\f1d1";
+@fa-var-gear: "\f013";
+@fa-var-gears: "\f085";
+@fa-var-gift: "\f06b";
+@fa-var-git: "\f1d3";
+@fa-var-git-square: "\f1d2";
+@fa-var-github: "\f09b";
+@fa-var-github-alt: "\f113";
+@fa-var-github-square: "\f092";
+@fa-var-gittip: "\f184";
+@fa-var-glass: "\f000";
+@fa-var-globe: "\f0ac";
+@fa-var-google: "\f1a0";
+@fa-var-google-plus: "\f0d5";
+@fa-var-google-plus-square: "\f0d4";
+@fa-var-graduation-cap: "\f19d";
+@fa-var-group: "\f0c0";
+@fa-var-h-square: "\f0fd";
+@fa-var-hacker-news: "\f1d4";
+@fa-var-hand-o-down: "\f0a7";
+@fa-var-hand-o-left: "\f0a5";
+@fa-var-hand-o-right: "\f0a4";
+@fa-var-hand-o-up: "\f0a6";
+@fa-var-hdd-o: "\f0a0";
+@fa-var-header: "\f1dc";
+@fa-var-headphones: "\f025";
+@fa-var-heart: "\f004";
+@fa-var-heart-o: "\f08a";
+@fa-var-history: "\f1da";
+@fa-var-home: "\f015";
+@fa-var-hospital-o: "\f0f8";
+@fa-var-html5: "\f13b";
+@fa-var-image: "\f03e";
+@fa-var-inbox: "\f01c";
+@fa-var-indent: "\f03c";
+@fa-var-info: "\f129";
+@fa-var-info-circle: "\f05a";
+@fa-var-inr: "\f156";
+@fa-var-instagram: "\f16d";
+@fa-var-institution: "\f19c";
+@fa-var-italic: "\f033";
+@fa-var-joomla: "\f1aa";
+@fa-var-jpy: "\f157";
+@fa-var-jsfiddle: "\f1cc";
+@fa-var-key: "\f084";
+@fa-var-keyboard-o: "\f11c";
+@fa-var-krw: "\f159";
+@fa-var-language: "\f1ab";
+@fa-var-laptop: "\f109";
+@fa-var-leaf: "\f06c";
+@fa-var-legal: "\f0e3";
+@fa-var-lemon-o: "\f094";
+@fa-var-level-down: "\f149";
+@fa-var-level-up: "\f148";
+@fa-var-life-bouy: "\f1cd";
+@fa-var-life-ring: "\f1cd";
+@fa-var-life-saver: "\f1cd";
+@fa-var-lightbulb-o: "\f0eb";
+@fa-var-link: "\f0c1";
+@fa-var-linkedin: "\f0e1";
+@fa-var-linkedin-square: "\f08c";
+@fa-var-linux: "\f17c";
+@fa-var-list: "\f03a";
+@fa-var-list-alt: "\f022";
+@fa-var-list-ol: "\f0cb";
+@fa-var-list-ul: "\f0ca";
+@fa-var-location-arrow: "\f124";
+@fa-var-lock: "\f023";
+@fa-var-long-arrow-down: "\f175";
+@fa-var-long-arrow-left: "\f177";
+@fa-var-long-arrow-right: "\f178";
+@fa-var-long-arrow-up: "\f176";
+@fa-var-magic: "\f0d0";
+@fa-var-magnet: "\f076";
+@fa-var-mail-forward: "\f064";
+@fa-var-mail-reply: "\f112";
+@fa-var-mail-reply-all: "\f122";
+@fa-var-male: "\f183";
+@fa-var-map-marker: "\f041";
+@fa-var-maxcdn: "\f136";
+@fa-var-medkit: "\f0fa";
+@fa-var-meh-o: "\f11a";
+@fa-var-microphone: "\f130";
+@fa-var-microphone-slash: "\f131";
+@fa-var-minus: "\f068";
+@fa-var-minus-circle: "\f056";
+@fa-var-minus-square: "\f146";
+@fa-var-minus-square-o: "\f147";
+@fa-var-mobile: "\f10b";
+@fa-var-mobile-phone: "\f10b";
+@fa-var-money: "\f0d6";
+@fa-var-moon-o: "\f186";
+@fa-var-mortar-board: "\f19d";
+@fa-var-music: "\f001";
+@fa-var-navicon: "\f0c9";
+@fa-var-openid: "\f19b";
+@fa-var-outdent: "\f03b";
+@fa-var-pagelines: "\f18c";
+@fa-var-paper-plane: "\f1d8";
+@fa-var-paper-plane-o: "\f1d9";
+@fa-var-paperclip: "\f0c6";
+@fa-var-paragraph: "\f1dd";
+@fa-var-paste: "\f0ea";
+@fa-var-pause: "\f04c";
+@fa-var-paw: "\f1b0";
+@fa-var-pencil: "\f040";
+@fa-var-pencil-square: "\f14b";
+@fa-var-pencil-square-o: "\f044";
+@fa-var-phone: "\f095";
+@fa-var-phone-square: "\f098";
+@fa-var-photo: "\f03e";
+@fa-var-picture-o: "\f03e";
+@fa-var-pied-piper: "\f1a7";
+@fa-var-pied-piper-alt: "\f1a8";
+@fa-var-pied-piper-square: "\f1a7";
+@fa-var-pinterest: "\f0d2";
+@fa-var-pinterest-square: "\f0d3";
+@fa-var-plane: "\f072";
+@fa-var-play: "\f04b";
+@fa-var-play-circle: "\f144";
+@fa-var-play-circle-o: "\f01d";
+@fa-var-plus: "\f067";
+@fa-var-plus-circle: "\f055";
+@fa-var-plus-square: "\f0fe";
+@fa-var-plus-square-o: "\f196";
+@fa-var-power-off: "\f011";
+@fa-var-print: "\f02f";
+@fa-var-puzzle-piece: "\f12e";
+@fa-var-qq: "\f1d6";
+@fa-var-qrcode: "\f029";
+@fa-var-question: "\f128";
+@fa-var-question-circle: "\f059";
+@fa-var-quote-left: "\f10d";
+@fa-var-quote-right: "\f10e";
+@fa-var-ra: "\f1d0";
+@fa-var-random: "\f074";
+@fa-var-rebel: "\f1d0";
+@fa-var-recycle: "\f1b8";
+@fa-var-reddit: "\f1a1";
+@fa-var-reddit-square: "\f1a2";
+@fa-var-refresh: "\f021";
+@fa-var-renren: "\f18b";
+@fa-var-reorder: "\f0c9";
+@fa-var-repeat: "\f01e";
+@fa-var-reply: "\f112";
+@fa-var-reply-all: "\f122";
+@fa-var-retweet: "\f079";
+@fa-var-rmb: "\f157";
+@fa-var-road: "\f018";
+@fa-var-rocket: "\f135";
+@fa-var-rotate-left: "\f0e2";
+@fa-var-rotate-right: "\f01e";
+@fa-var-rouble: "\f158";
+@fa-var-rss: "\f09e";
+@fa-var-rss-square: "\f143";
+@fa-var-rub: "\f158";
+@fa-var-ruble: "\f158";
+@fa-var-rupee: "\f156";
+@fa-var-save: "\f0c7";
+@fa-var-scissors: "\f0c4";
+@fa-var-search: "\f002";
+@fa-var-search-minus: "\f010";
+@fa-var-search-plus: "\f00e";
+@fa-var-send: "\f1d8";
+@fa-var-send-o: "\f1d9";
+@fa-var-share: "\f064";
+@fa-var-share-alt: "\f1e0";
+@fa-var-share-alt-square: "\f1e1";
+@fa-var-share-square: "\f14d";
+@fa-var-share-square-o: "\f045";
+@fa-var-shield: "\f132";
+@fa-var-shopping-cart: "\f07a";
+@fa-var-sign-in: "\f090";
+@fa-var-sign-out: "\f08b";
+@fa-var-signal: "\f012";
+@fa-var-sitemap: "\f0e8";
+@fa-var-skype: "\f17e";
+@fa-var-slack: "\f198";
+@fa-var-sliders: "\f1de";
+@fa-var-smile-o: "\f118";
+@fa-var-sort: "\f0dc";
+@fa-var-sort-alpha-asc: "\f15d";
+@fa-var-sort-alpha-desc: "\f15e";
+@fa-var-sort-amount-asc: "\f160";
+@fa-var-sort-amount-desc: "\f161";
+@fa-var-sort-asc: "\f0de";
+@fa-var-sort-desc: "\f0dd";
+@fa-var-sort-down: "\f0dd";
+@fa-var-sort-numeric-asc: "\f162";
+@fa-var-sort-numeric-desc: "\f163";
+@fa-var-sort-up: "\f0de";
+@fa-var-soundcloud: "\f1be";
+@fa-var-space-shuttle: "\f197";
+@fa-var-spinner: "\f110";
+@fa-var-spoon: "\f1b1";
+@fa-var-spotify: "\f1bc";
+@fa-var-square: "\f0c8";
+@fa-var-square-o: "\f096";
+@fa-var-stack-exchange: "\f18d";
+@fa-var-stack-overflow: "\f16c";
+@fa-var-star: "\f005";
+@fa-var-star-half: "\f089";
+@fa-var-star-half-empty: "\f123";
+@fa-var-star-half-full: "\f123";
+@fa-var-star-half-o: "\f123";
+@fa-var-star-o: "\f006";
+@fa-var-steam: "\f1b6";
+@fa-var-steam-square: "\f1b7";
+@fa-var-step-backward: "\f048";
+@fa-var-step-forward: "\f051";
+@fa-var-stethoscope: "\f0f1";
+@fa-var-stop: "\f04d";
+@fa-var-strikethrough: "\f0cc";
+@fa-var-stumbleupon: "\f1a4";
+@fa-var-stumbleupon-circle: "\f1a3";
+@fa-var-subscript: "\f12c";
+@fa-var-suitcase: "\f0f2";
+@fa-var-sun-o: "\f185";
+@fa-var-superscript: "\f12b";
+@fa-var-support: "\f1cd";
+@fa-var-table: "\f0ce";
+@fa-var-tablet: "\f10a";
+@fa-var-tachometer: "\f0e4";
+@fa-var-tag: "\f02b";
+@fa-var-tags: "\f02c";
+@fa-var-tasks: "\f0ae";
+@fa-var-taxi: "\f1ba";
+@fa-var-tencent-weibo: "\f1d5";
+@fa-var-terminal: "\f120";
+@fa-var-text-height: "\f034";
+@fa-var-text-width: "\f035";
+@fa-var-th: "\f00a";
+@fa-var-th-large: "\f009";
+@fa-var-th-list: "\f00b";
+@fa-var-thumb-tack: "\f08d";
+@fa-var-thumbs-down: "\f165";
+@fa-var-thumbs-o-down: "\f088";
+@fa-var-thumbs-o-up: "\f087";
+@fa-var-thumbs-up: "\f164";
+@fa-var-ticket: "\f145";
+@fa-var-times: "\f00d";
+@fa-var-times-circle: "\f057";
+@fa-var-times-circle-o: "\f05c";
+@fa-var-tint: "\f043";
+@fa-var-toggle-down: "\f150";
+@fa-var-toggle-left: "\f191";
+@fa-var-toggle-right: "\f152";
+@fa-var-toggle-up: "\f151";
+@fa-var-trash-o: "\f014";
+@fa-var-tree: "\f1bb";
+@fa-var-trello: "\f181";
+@fa-var-trophy: "\f091";
+@fa-var-truck: "\f0d1";
+@fa-var-try: "\f195";
+@fa-var-tumblr: "\f173";
+@fa-var-tumblr-square: "\f174";
+@fa-var-turkish-lira: "\f195";
+@fa-var-twitter: "\f099";
+@fa-var-twitter-square: "\f081";
+@fa-var-umbrella: "\f0e9";
+@fa-var-underline: "\f0cd";
+@fa-var-undo: "\f0e2";
+@fa-var-university: "\f19c";
+@fa-var-unlink: "\f127";
+@fa-var-unlock: "\f09c";
+@fa-var-unlock-alt: "\f13e";
+@fa-var-unsorted: "\f0dc";
+@fa-var-upload: "\f093";
+@fa-var-usd: "\f155";
+@fa-var-user: "\f007";
+@fa-var-user-md: "\f0f0";
+@fa-var-users: "\f0c0";
+@fa-var-video-camera: "\f03d";
+@fa-var-vimeo-square: "\f194";
+@fa-var-vine: "\f1ca";
+@fa-var-vk: "\f189";
+@fa-var-volume-down: "\f027";
+@fa-var-volume-off: "\f026";
+@fa-var-volume-up: "\f028";
+@fa-var-warning: "\f071";
+@fa-var-wechat: "\f1d7";
+@fa-var-weibo: "\f18a";
+@fa-var-weixin: "\f1d7";
+@fa-var-wheelchair: "\f193";
+@fa-var-windows: "\f17a";
+@fa-var-won: "\f159";
+@fa-var-wordpress: "\f19a";
+@fa-var-wrench: "\f0ad";
+@fa-var-xing: "\f168";
+@fa-var-xing-square: "\f169";
+@fa-var-yahoo: "\f19e";
+@fa-var-yen: "\f157";
+@fa-var-youtube: "\f167";
+@fa-var-youtube-play: "\f16a";
+@fa-var-youtube-square: "\f166";
+
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_bordered-pulled.scss b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_bordered-pulled.scss
new file mode 100755
index 0000000..9d3fdf3
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_bordered-pulled.scss
@@ -0,0 +1,16 @@
+// Bordered & Pulled
+// -------------------------
+
+.#{$fa-css-prefix}-border {
+ padding: .2em .25em .15em;
+ border: solid .08em $fa-border-color;
+ border-radius: .1em;
+}
+
+.pull-right { float: right; }
+.pull-left { float: left; }
+
+.#{$fa-css-prefix} {
+ &.pull-left { margin-right: .3em; }
+ &.pull-right { margin-left: .3em; }
+}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_core.scss b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_core.scss
new file mode 100755
index 0000000..861ccd9
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_core.scss
@@ -0,0 +1,12 @@
+// Base Class Definition
+// -------------------------
+
+.#{$fa-css-prefix} {
+ display: inline-block;
+ font-family: FontAwesome;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_fixed-width.scss b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_fixed-width.scss
new file mode 100755
index 0000000..b221c98
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_fixed-width.scss
@@ -0,0 +1,6 @@
+// Fixed Width Icons
+// -------------------------
+.#{$fa-css-prefix}-fw {
+ width: (18em / 14);
+ text-align: center;
+}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_icons.scss b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_icons.scss
new file mode 100755
index 0000000..efb4435
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_icons.scss
@@ -0,0 +1,506 @@
+/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+ readers do not read off random characters that represent icons */
+
+.#{$fa-css-prefix}-glass:before { content: $fa-var-glass; }
+.#{$fa-css-prefix}-music:before { content: $fa-var-music; }
+.#{$fa-css-prefix}-search:before { content: $fa-var-search; }
+.#{$fa-css-prefix}-envelope-o:before { content: $fa-var-envelope-o; }
+.#{$fa-css-prefix}-heart:before { content: $fa-var-heart; }
+.#{$fa-css-prefix}-star:before { content: $fa-var-star; }
+.#{$fa-css-prefix}-star-o:before { content: $fa-var-star-o; }
+.#{$fa-css-prefix}-user:before { content: $fa-var-user; }
+.#{$fa-css-prefix}-film:before { content: $fa-var-film; }
+.#{$fa-css-prefix}-th-large:before { content: $fa-var-th-large; }
+.#{$fa-css-prefix}-th:before { content: $fa-var-th; }
+.#{$fa-css-prefix}-th-list:before { content: $fa-var-th-list; }
+.#{$fa-css-prefix}-check:before { content: $fa-var-check; }
+.#{$fa-css-prefix}-times:before { content: $fa-var-times; }
+.#{$fa-css-prefix}-search-plus:before { content: $fa-var-search-plus; }
+.#{$fa-css-prefix}-search-minus:before { content: $fa-var-search-minus; }
+.#{$fa-css-prefix}-power-off:before { content: $fa-var-power-off; }
+.#{$fa-css-prefix}-signal:before { content: $fa-var-signal; }
+.#{$fa-css-prefix}-gear:before,
+.#{$fa-css-prefix}-cog:before { content: $fa-var-cog; }
+.#{$fa-css-prefix}-trash-o:before { content: $fa-var-trash-o; }
+.#{$fa-css-prefix}-home:before { content: $fa-var-home; }
+.#{$fa-css-prefix}-file-o:before { content: $fa-var-file-o; }
+.#{$fa-css-prefix}-clock-o:before { content: $fa-var-clock-o; }
+.#{$fa-css-prefix}-road:before { content: $fa-var-road; }
+.#{$fa-css-prefix}-download:before { content: $fa-var-download; }
+.#{$fa-css-prefix}-arrow-circle-o-down:before { content: $fa-var-arrow-circle-o-down; }
+.#{$fa-css-prefix}-arrow-circle-o-up:before { content: $fa-var-arrow-circle-o-up; }
+.#{$fa-css-prefix}-inbox:before { content: $fa-var-inbox; }
+.#{$fa-css-prefix}-play-circle-o:before { content: $fa-var-play-circle-o; }
+.#{$fa-css-prefix}-rotate-right:before,
+.#{$fa-css-prefix}-repeat:before { content: $fa-var-repeat; }
+.#{$fa-css-prefix}-refresh:before { content: $fa-var-refresh; }
+.#{$fa-css-prefix}-list-alt:before { content: $fa-var-list-alt; }
+.#{$fa-css-prefix}-lock:before { content: $fa-var-lock; }
+.#{$fa-css-prefix}-flag:before { content: $fa-var-flag; }
+.#{$fa-css-prefix}-headphones:before { content: $fa-var-headphones; }
+.#{$fa-css-prefix}-volume-off:before { content: $fa-var-volume-off; }
+.#{$fa-css-prefix}-volume-down:before { content: $fa-var-volume-down; }
+.#{$fa-css-prefix}-volume-up:before { content: $fa-var-volume-up; }
+.#{$fa-css-prefix}-qrcode:before { content: $fa-var-qrcode; }
+.#{$fa-css-prefix}-barcode:before { content: $fa-var-barcode; }
+.#{$fa-css-prefix}-tag:before { content: $fa-var-tag; }
+.#{$fa-css-prefix}-tags:before { content: $fa-var-tags; }
+.#{$fa-css-prefix}-book:before { content: $fa-var-book; }
+.#{$fa-css-prefix}-bookmark:before { content: $fa-var-bookmark; }
+.#{$fa-css-prefix}-print:before { content: $fa-var-print; }
+.#{$fa-css-prefix}-camera:before { content: $fa-var-camera; }
+.#{$fa-css-prefix}-font:before { content: $fa-var-font; }
+.#{$fa-css-prefix}-bold:before { content: $fa-var-bold; }
+.#{$fa-css-prefix}-italic:before { content: $fa-var-italic; }
+.#{$fa-css-prefix}-text-height:before { content: $fa-var-text-height; }
+.#{$fa-css-prefix}-text-width:before { content: $fa-var-text-width; }
+.#{$fa-css-prefix}-align-left:before { content: $fa-var-align-left; }
+.#{$fa-css-prefix}-align-center:before { content: $fa-var-align-center; }
+.#{$fa-css-prefix}-align-right:before { content: $fa-var-align-right; }
+.#{$fa-css-prefix}-align-justify:before { content: $fa-var-align-justify; }
+.#{$fa-css-prefix}-list:before { content: $fa-var-list; }
+.#{$fa-css-prefix}-dedent:before,
+.#{$fa-css-prefix}-outdent:before { content: $fa-var-outdent; }
+.#{$fa-css-prefix}-indent:before { content: $fa-var-indent; }
+.#{$fa-css-prefix}-video-camera:before { content: $fa-var-video-camera; }
+.#{$fa-css-prefix}-photo:before,
+.#{$fa-css-prefix}-image:before,
+.#{$fa-css-prefix}-picture-o:before { content: $fa-var-picture-o; }
+.#{$fa-css-prefix}-pencil:before { content: $fa-var-pencil; }
+.#{$fa-css-prefix}-map-marker:before { content: $fa-var-map-marker; }
+.#{$fa-css-prefix}-adjust:before { content: $fa-var-adjust; }
+.#{$fa-css-prefix}-tint:before { content: $fa-var-tint; }
+.#{$fa-css-prefix}-edit:before,
+.#{$fa-css-prefix}-pencil-square-o:before { content: $fa-var-pencil-square-o; }
+.#{$fa-css-prefix}-share-square-o:before { content: $fa-var-share-square-o; }
+.#{$fa-css-prefix}-check-square-o:before { content: $fa-var-check-square-o; }
+.#{$fa-css-prefix}-arrows:before { content: $fa-var-arrows; }
+.#{$fa-css-prefix}-step-backward:before { content: $fa-var-step-backward; }
+.#{$fa-css-prefix}-fast-backward:before { content: $fa-var-fast-backward; }
+.#{$fa-css-prefix}-backward:before { content: $fa-var-backward; }
+.#{$fa-css-prefix}-play:before { content: $fa-var-play; }
+.#{$fa-css-prefix}-pause:before { content: $fa-var-pause; }
+.#{$fa-css-prefix}-stop:before { content: $fa-var-stop; }
+.#{$fa-css-prefix}-forward:before { content: $fa-var-forward; }
+.#{$fa-css-prefix}-fast-forward:before { content: $fa-var-fast-forward; }
+.#{$fa-css-prefix}-step-forward:before { content: $fa-var-step-forward; }
+.#{$fa-css-prefix}-eject:before { content: $fa-var-eject; }
+.#{$fa-css-prefix}-chevron-left:before { content: $fa-var-chevron-left; }
+.#{$fa-css-prefix}-chevron-right:before { content: $fa-var-chevron-right; }
+.#{$fa-css-prefix}-plus-circle:before { content: $fa-var-plus-circle; }
+.#{$fa-css-prefix}-minus-circle:before { content: $fa-var-minus-circle; }
+.#{$fa-css-prefix}-times-circle:before { content: $fa-var-times-circle; }
+.#{$fa-css-prefix}-check-circle:before { content: $fa-var-check-circle; }
+.#{$fa-css-prefix}-question-circle:before { content: $fa-var-question-circle; }
+.#{$fa-css-prefix}-info-circle:before { content: $fa-var-info-circle; }
+.#{$fa-css-prefix}-crosshairs:before { content: $fa-var-crosshairs; }
+.#{$fa-css-prefix}-times-circle-o:before { content: $fa-var-times-circle-o; }
+.#{$fa-css-prefix}-check-circle-o:before { content: $fa-var-check-circle-o; }
+.#{$fa-css-prefix}-ban:before { content: $fa-var-ban; }
+.#{$fa-css-prefix}-arrow-left:before { content: $fa-var-arrow-left; }
+.#{$fa-css-prefix}-arrow-right:before { content: $fa-var-arrow-right; }
+.#{$fa-css-prefix}-arrow-up:before { content: $fa-var-arrow-up; }
+.#{$fa-css-prefix}-arrow-down:before { content: $fa-var-arrow-down; }
+.#{$fa-css-prefix}-mail-forward:before,
+.#{$fa-css-prefix}-share:before { content: $fa-var-share; }
+.#{$fa-css-prefix}-expand:before { content: $fa-var-expand; }
+.#{$fa-css-prefix}-compress:before { content: $fa-var-compress; }
+.#{$fa-css-prefix}-plus:before { content: $fa-var-plus; }
+.#{$fa-css-prefix}-minus:before { content: $fa-var-minus; }
+.#{$fa-css-prefix}-asterisk:before { content: $fa-var-asterisk; }
+.#{$fa-css-prefix}-exclamation-circle:before { content: $fa-var-exclamation-circle; }
+.#{$fa-css-prefix}-gift:before { content: $fa-var-gift; }
+.#{$fa-css-prefix}-leaf:before { content: $fa-var-leaf; }
+.#{$fa-css-prefix}-fire:before { content: $fa-var-fire; }
+.#{$fa-css-prefix}-eye:before { content: $fa-var-eye; }
+.#{$fa-css-prefix}-eye-slash:before { content: $fa-var-eye-slash; }
+.#{$fa-css-prefix}-warning:before,
+.#{$fa-css-prefix}-exclamation-triangle:before { content: $fa-var-exclamation-triangle; }
+.#{$fa-css-prefix}-plane:before { content: $fa-var-plane; }
+.#{$fa-css-prefix}-calendar:before { content: $fa-var-calendar; }
+.#{$fa-css-prefix}-random:before { content: $fa-var-random; }
+.#{$fa-css-prefix}-comment:before { content: $fa-var-comment; }
+.#{$fa-css-prefix}-magnet:before { content: $fa-var-magnet; }
+.#{$fa-css-prefix}-chevron-up:before { content: $fa-var-chevron-up; }
+.#{$fa-css-prefix}-chevron-down:before { content: $fa-var-chevron-down; }
+.#{$fa-css-prefix}-retweet:before { content: $fa-var-retweet; }
+.#{$fa-css-prefix}-shopping-cart:before { content: $fa-var-shopping-cart; }
+.#{$fa-css-prefix}-folder:before { content: $fa-var-folder; }
+.#{$fa-css-prefix}-folder-open:before { content: $fa-var-folder-open; }
+.#{$fa-css-prefix}-arrows-v:before { content: $fa-var-arrows-v; }
+.#{$fa-css-prefix}-arrows-h:before { content: $fa-var-arrows-h; }
+.#{$fa-css-prefix}-bar-chart-o:before { content: $fa-var-bar-chart-o; }
+.#{$fa-css-prefix}-twitter-square:before { content: $fa-var-twitter-square; }
+.#{$fa-css-prefix}-facebook-square:before { content: $fa-var-facebook-square; }
+.#{$fa-css-prefix}-camera-retro:before { content: $fa-var-camera-retro; }
+.#{$fa-css-prefix}-key:before { content: $fa-var-key; }
+.#{$fa-css-prefix}-gears:before,
+.#{$fa-css-prefix}-cogs:before { content: $fa-var-cogs; }
+.#{$fa-css-prefix}-comments:before { content: $fa-var-comments; }
+.#{$fa-css-prefix}-thumbs-o-up:before { content: $fa-var-thumbs-o-up; }
+.#{$fa-css-prefix}-thumbs-o-down:before { content: $fa-var-thumbs-o-down; }
+.#{$fa-css-prefix}-star-half:before { content: $fa-var-star-half; }
+.#{$fa-css-prefix}-heart-o:before { content: $fa-var-heart-o; }
+.#{$fa-css-prefix}-sign-out:before { content: $fa-var-sign-out; }
+.#{$fa-css-prefix}-linkedin-square:before { content: $fa-var-linkedin-square; }
+.#{$fa-css-prefix}-thumb-tack:before { content: $fa-var-thumb-tack; }
+.#{$fa-css-prefix}-external-link:before { content: $fa-var-external-link; }
+.#{$fa-css-prefix}-sign-in:before { content: $fa-var-sign-in; }
+.#{$fa-css-prefix}-trophy:before { content: $fa-var-trophy; }
+.#{$fa-css-prefix}-github-square:before { content: $fa-var-github-square; }
+.#{$fa-css-prefix}-upload:before { content: $fa-var-upload; }
+.#{$fa-css-prefix}-lemon-o:before { content: $fa-var-lemon-o; }
+.#{$fa-css-prefix}-phone:before { content: $fa-var-phone; }
+.#{$fa-css-prefix}-square-o:before { content: $fa-var-square-o; }
+.#{$fa-css-prefix}-bookmark-o:before { content: $fa-var-bookmark-o; }
+.#{$fa-css-prefix}-phone-square:before { content: $fa-var-phone-square; }
+.#{$fa-css-prefix}-twitter:before { content: $fa-var-twitter; }
+.#{$fa-css-prefix}-facebook:before { content: $fa-var-facebook; }
+.#{$fa-css-prefix}-github:before { content: $fa-var-github; }
+.#{$fa-css-prefix}-unlock:before { content: $fa-var-unlock; }
+.#{$fa-css-prefix}-credit-card:before { content: $fa-var-credit-card; }
+.#{$fa-css-prefix}-rss:before { content: $fa-var-rss; }
+.#{$fa-css-prefix}-hdd-o:before { content: $fa-var-hdd-o; }
+.#{$fa-css-prefix}-bullhorn:before { content: $fa-var-bullhorn; }
+.#{$fa-css-prefix}-bell:before { content: $fa-var-bell; }
+.#{$fa-css-prefix}-certificate:before { content: $fa-var-certificate; }
+.#{$fa-css-prefix}-hand-o-right:before { content: $fa-var-hand-o-right; }
+.#{$fa-css-prefix}-hand-o-left:before { content: $fa-var-hand-o-left; }
+.#{$fa-css-prefix}-hand-o-up:before { content: $fa-var-hand-o-up; }
+.#{$fa-css-prefix}-hand-o-down:before { content: $fa-var-hand-o-down; }
+.#{$fa-css-prefix}-arrow-circle-left:before { content: $fa-var-arrow-circle-left; }
+.#{$fa-css-prefix}-arrow-circle-right:before { content: $fa-var-arrow-circle-right; }
+.#{$fa-css-prefix}-arrow-circle-up:before { content: $fa-var-arrow-circle-up; }
+.#{$fa-css-prefix}-arrow-circle-down:before { content: $fa-var-arrow-circle-down; }
+.#{$fa-css-prefix}-globe:before { content: $fa-var-globe; }
+.#{$fa-css-prefix}-wrench:before { content: $fa-var-wrench; }
+.#{$fa-css-prefix}-tasks:before { content: $fa-var-tasks; }
+.#{$fa-css-prefix}-filter:before { content: $fa-var-filter; }
+.#{$fa-css-prefix}-briefcase:before { content: $fa-var-briefcase; }
+.#{$fa-css-prefix}-arrows-alt:before { content: $fa-var-arrows-alt; }
+.#{$fa-css-prefix}-group:before,
+.#{$fa-css-prefix}-users:before { content: $fa-var-users; }
+.#{$fa-css-prefix}-chain:before,
+.#{$fa-css-prefix}-link:before { content: $fa-var-link; }
+.#{$fa-css-prefix}-cloud:before { content: $fa-var-cloud; }
+.#{$fa-css-prefix}-flask:before { content: $fa-var-flask; }
+.#{$fa-css-prefix}-cut:before,
+.#{$fa-css-prefix}-scissors:before { content: $fa-var-scissors; }
+.#{$fa-css-prefix}-copy:before,
+.#{$fa-css-prefix}-files-o:before { content: $fa-var-files-o; }
+.#{$fa-css-prefix}-paperclip:before { content: $fa-var-paperclip; }
+.#{$fa-css-prefix}-save:before,
+.#{$fa-css-prefix}-floppy-o:before { content: $fa-var-floppy-o; }
+.#{$fa-css-prefix}-square:before { content: $fa-var-square; }
+.#{$fa-css-prefix}-navicon:before,
+.#{$fa-css-prefix}-reorder:before,
+.#{$fa-css-prefix}-bars:before { content: $fa-var-bars; }
+.#{$fa-css-prefix}-list-ul:before { content: $fa-var-list-ul; }
+.#{$fa-css-prefix}-list-ol:before { content: $fa-var-list-ol; }
+.#{$fa-css-prefix}-strikethrough:before { content: $fa-var-strikethrough; }
+.#{$fa-css-prefix}-underline:before { content: $fa-var-underline; }
+.#{$fa-css-prefix}-table:before { content: $fa-var-table; }
+.#{$fa-css-prefix}-magic:before { content: $fa-var-magic; }
+.#{$fa-css-prefix}-truck:before { content: $fa-var-truck; }
+.#{$fa-css-prefix}-pinterest:before { content: $fa-var-pinterest; }
+.#{$fa-css-prefix}-pinterest-square:before { content: $fa-var-pinterest-square; }
+.#{$fa-css-prefix}-google-plus-square:before { content: $fa-var-google-plus-square; }
+.#{$fa-css-prefix}-google-plus:before { content: $fa-var-google-plus; }
+.#{$fa-css-prefix}-money:before { content: $fa-var-money; }
+.#{$fa-css-prefix}-caret-down:before { content: $fa-var-caret-down; }
+.#{$fa-css-prefix}-caret-up:before { content: $fa-var-caret-up; }
+.#{$fa-css-prefix}-caret-left:before { content: $fa-var-caret-left; }
+.#{$fa-css-prefix}-caret-right:before { content: $fa-var-caret-right; }
+.#{$fa-css-prefix}-columns:before { content: $fa-var-columns; }
+.#{$fa-css-prefix}-unsorted:before,
+.#{$fa-css-prefix}-sort:before { content: $fa-var-sort; }
+.#{$fa-css-prefix}-sort-down:before,
+.#{$fa-css-prefix}-sort-desc:before { content: $fa-var-sort-desc; }
+.#{$fa-css-prefix}-sort-up:before,
+.#{$fa-css-prefix}-sort-asc:before { content: $fa-var-sort-asc; }
+.#{$fa-css-prefix}-envelope:before { content: $fa-var-envelope; }
+.#{$fa-css-prefix}-linkedin:before { content: $fa-var-linkedin; }
+.#{$fa-css-prefix}-rotate-left:before,
+.#{$fa-css-prefix}-undo:before { content: $fa-var-undo; }
+.#{$fa-css-prefix}-legal:before,
+.#{$fa-css-prefix}-gavel:before { content: $fa-var-gavel; }
+.#{$fa-css-prefix}-dashboard:before,
+.#{$fa-css-prefix}-tachometer:before { content: $fa-var-tachometer; }
+.#{$fa-css-prefix}-comment-o:before { content: $fa-var-comment-o; }
+.#{$fa-css-prefix}-comments-o:before { content: $fa-var-comments-o; }
+.#{$fa-css-prefix}-flash:before,
+.#{$fa-css-prefix}-bolt:before { content: $fa-var-bolt; }
+.#{$fa-css-prefix}-sitemap:before { content: $fa-var-sitemap; }
+.#{$fa-css-prefix}-umbrella:before { content: $fa-var-umbrella; }
+.#{$fa-css-prefix}-paste:before,
+.#{$fa-css-prefix}-clipboard:before { content: $fa-var-clipboard; }
+.#{$fa-css-prefix}-lightbulb-o:before { content: $fa-var-lightbulb-o; }
+.#{$fa-css-prefix}-exchange:before { content: $fa-var-exchange; }
+.#{$fa-css-prefix}-cloud-download:before { content: $fa-var-cloud-download; }
+.#{$fa-css-prefix}-cloud-upload:before { content: $fa-var-cloud-upload; }
+.#{$fa-css-prefix}-user-md:before { content: $fa-var-user-md; }
+.#{$fa-css-prefix}-stethoscope:before { content: $fa-var-stethoscope; }
+.#{$fa-css-prefix}-suitcase:before { content: $fa-var-suitcase; }
+.#{$fa-css-prefix}-bell-o:before { content: $fa-var-bell-o; }
+.#{$fa-css-prefix}-coffee:before { content: $fa-var-coffee; }
+.#{$fa-css-prefix}-cutlery:before { content: $fa-var-cutlery; }
+.#{$fa-css-prefix}-file-text-o:before { content: $fa-var-file-text-o; }
+.#{$fa-css-prefix}-building-o:before { content: $fa-var-building-o; }
+.#{$fa-css-prefix}-hospital-o:before { content: $fa-var-hospital-o; }
+.#{$fa-css-prefix}-ambulance:before { content: $fa-var-ambulance; }
+.#{$fa-css-prefix}-medkit:before { content: $fa-var-medkit; }
+.#{$fa-css-prefix}-fighter-jet:before { content: $fa-var-fighter-jet; }
+.#{$fa-css-prefix}-beer:before { content: $fa-var-beer; }
+.#{$fa-css-prefix}-h-square:before { content: $fa-var-h-square; }
+.#{$fa-css-prefix}-plus-square:before { content: $fa-var-plus-square; }
+.#{$fa-css-prefix}-angle-double-left:before { content: $fa-var-angle-double-left; }
+.#{$fa-css-prefix}-angle-double-right:before { content: $fa-var-angle-double-right; }
+.#{$fa-css-prefix}-angle-double-up:before { content: $fa-var-angle-double-up; }
+.#{$fa-css-prefix}-angle-double-down:before { content: $fa-var-angle-double-down; }
+.#{$fa-css-prefix}-angle-left:before { content: $fa-var-angle-left; }
+.#{$fa-css-prefix}-angle-right:before { content: $fa-var-angle-right; }
+.#{$fa-css-prefix}-angle-up:before { content: $fa-var-angle-up; }
+.#{$fa-css-prefix}-angle-down:before { content: $fa-var-angle-down; }
+.#{$fa-css-prefix}-desktop:before { content: $fa-var-desktop; }
+.#{$fa-css-prefix}-laptop:before { content: $fa-var-laptop; }
+.#{$fa-css-prefix}-tablet:before { content: $fa-var-tablet; }
+.#{$fa-css-prefix}-mobile-phone:before,
+.#{$fa-css-prefix}-mobile:before { content: $fa-var-mobile; }
+.#{$fa-css-prefix}-circle-o:before { content: $fa-var-circle-o; }
+.#{$fa-css-prefix}-quote-left:before { content: $fa-var-quote-left; }
+.#{$fa-css-prefix}-quote-right:before { content: $fa-var-quote-right; }
+.#{$fa-css-prefix}-spinner:before { content: $fa-var-spinner; }
+.#{$fa-css-prefix}-circle:before { content: $fa-var-circle; }
+.#{$fa-css-prefix}-mail-reply:before,
+.#{$fa-css-prefix}-reply:before { content: $fa-var-reply; }
+.#{$fa-css-prefix}-github-alt:before { content: $fa-var-github-alt; }
+.#{$fa-css-prefix}-folder-o:before { content: $fa-var-folder-o; }
+.#{$fa-css-prefix}-folder-open-o:before { content: $fa-var-folder-open-o; }
+.#{$fa-css-prefix}-smile-o:before { content: $fa-var-smile-o; }
+.#{$fa-css-prefix}-frown-o:before { content: $fa-var-frown-o; }
+.#{$fa-css-prefix}-meh-o:before { content: $fa-var-meh-o; }
+.#{$fa-css-prefix}-gamepad:before { content: $fa-var-gamepad; }
+.#{$fa-css-prefix}-keyboard-o:before { content: $fa-var-keyboard-o; }
+.#{$fa-css-prefix}-flag-o:before { content: $fa-var-flag-o; }
+.#{$fa-css-prefix}-flag-checkered:before { content: $fa-var-flag-checkered; }
+.#{$fa-css-prefix}-terminal:before { content: $fa-var-terminal; }
+.#{$fa-css-prefix}-code:before { content: $fa-var-code; }
+.#{$fa-css-prefix}-mail-reply-all:before,
+.#{$fa-css-prefix}-reply-all:before { content: $fa-var-reply-all; }
+.#{$fa-css-prefix}-star-half-empty:before,
+.#{$fa-css-prefix}-star-half-full:before,
+.#{$fa-css-prefix}-star-half-o:before { content: $fa-var-star-half-o; }
+.#{$fa-css-prefix}-location-arrow:before { content: $fa-var-location-arrow; }
+.#{$fa-css-prefix}-crop:before { content: $fa-var-crop; }
+.#{$fa-css-prefix}-code-fork:before { content: $fa-var-code-fork; }
+.#{$fa-css-prefix}-unlink:before,
+.#{$fa-css-prefix}-chain-broken:before { content: $fa-var-chain-broken; }
+.#{$fa-css-prefix}-question:before { content: $fa-var-question; }
+.#{$fa-css-prefix}-info:before { content: $fa-var-info; }
+.#{$fa-css-prefix}-exclamation:before { content: $fa-var-exclamation; }
+.#{$fa-css-prefix}-superscript:before { content: $fa-var-superscript; }
+.#{$fa-css-prefix}-subscript:before { content: $fa-var-subscript; }
+.#{$fa-css-prefix}-eraser:before { content: $fa-var-eraser; }
+.#{$fa-css-prefix}-puzzle-piece:before { content: $fa-var-puzzle-piece; }
+.#{$fa-css-prefix}-microphone:before { content: $fa-var-microphone; }
+.#{$fa-css-prefix}-microphone-slash:before { content: $fa-var-microphone-slash; }
+.#{$fa-css-prefix}-shield:before { content: $fa-var-shield; }
+.#{$fa-css-prefix}-calendar-o:before { content: $fa-var-calendar-o; }
+.#{$fa-css-prefix}-fire-extinguisher:before { content: $fa-var-fire-extinguisher; }
+.#{$fa-css-prefix}-rocket:before { content: $fa-var-rocket; }
+.#{$fa-css-prefix}-maxcdn:before { content: $fa-var-maxcdn; }
+.#{$fa-css-prefix}-chevron-circle-left:before { content: $fa-var-chevron-circle-left; }
+.#{$fa-css-prefix}-chevron-circle-right:before { content: $fa-var-chevron-circle-right; }
+.#{$fa-css-prefix}-chevron-circle-up:before { content: $fa-var-chevron-circle-up; }
+.#{$fa-css-prefix}-chevron-circle-down:before { content: $fa-var-chevron-circle-down; }
+.#{$fa-css-prefix}-html5:before { content: $fa-var-html5; }
+.#{$fa-css-prefix}-css3:before { content: $fa-var-css3; }
+.#{$fa-css-prefix}-anchor:before { content: $fa-var-anchor; }
+.#{$fa-css-prefix}-unlock-alt:before { content: $fa-var-unlock-alt; }
+.#{$fa-css-prefix}-bullseye:before { content: $fa-var-bullseye; }
+.#{$fa-css-prefix}-ellipsis-h:before { content: $fa-var-ellipsis-h; }
+.#{$fa-css-prefix}-ellipsis-v:before { content: $fa-var-ellipsis-v; }
+.#{$fa-css-prefix}-rss-square:before { content: $fa-var-rss-square; }
+.#{$fa-css-prefix}-play-circle:before { content: $fa-var-play-circle; }
+.#{$fa-css-prefix}-ticket:before { content: $fa-var-ticket; }
+.#{$fa-css-prefix}-minus-square:before { content: $fa-var-minus-square; }
+.#{$fa-css-prefix}-minus-square-o:before { content: $fa-var-minus-square-o; }
+.#{$fa-css-prefix}-level-up:before { content: $fa-var-level-up; }
+.#{$fa-css-prefix}-level-down:before { content: $fa-var-level-down; }
+.#{$fa-css-prefix}-check-square:before { content: $fa-var-check-square; }
+.#{$fa-css-prefix}-pencil-square:before { content: $fa-var-pencil-square; }
+.#{$fa-css-prefix}-external-link-square:before { content: $fa-var-external-link-square; }
+.#{$fa-css-prefix}-share-square:before { content: $fa-var-share-square; }
+.#{$fa-css-prefix}-compass:before { content: $fa-var-compass; }
+.#{$fa-css-prefix}-toggle-down:before,
+.#{$fa-css-prefix}-caret-square-o-down:before { content: $fa-var-caret-square-o-down; }
+.#{$fa-css-prefix}-toggle-up:before,
+.#{$fa-css-prefix}-caret-square-o-up:before { content: $fa-var-caret-square-o-up; }
+.#{$fa-css-prefix}-toggle-right:before,
+.#{$fa-css-prefix}-caret-square-o-right:before { content: $fa-var-caret-square-o-right; }
+.#{$fa-css-prefix}-euro:before,
+.#{$fa-css-prefix}-eur:before { content: $fa-var-eur; }
+.#{$fa-css-prefix}-gbp:before { content: $fa-var-gbp; }
+.#{$fa-css-prefix}-dollar:before,
+.#{$fa-css-prefix}-usd:before { content: $fa-var-usd; }
+.#{$fa-css-prefix}-rupee:before,
+.#{$fa-css-prefix}-inr:before { content: $fa-var-inr; }
+.#{$fa-css-prefix}-cny:before,
+.#{$fa-css-prefix}-rmb:before,
+.#{$fa-css-prefix}-yen:before,
+.#{$fa-css-prefix}-jpy:before { content: $fa-var-jpy; }
+.#{$fa-css-prefix}-ruble:before,
+.#{$fa-css-prefix}-rouble:before,
+.#{$fa-css-prefix}-rub:before { content: $fa-var-rub; }
+.#{$fa-css-prefix}-won:before,
+.#{$fa-css-prefix}-krw:before { content: $fa-var-krw; }
+.#{$fa-css-prefix}-bitcoin:before,
+.#{$fa-css-prefix}-btc:before { content: $fa-var-btc; }
+.#{$fa-css-prefix}-file:before { content: $fa-var-file; }
+.#{$fa-css-prefix}-file-text:before { content: $fa-var-file-text; }
+.#{$fa-css-prefix}-sort-alpha-asc:before { content: $fa-var-sort-alpha-asc; }
+.#{$fa-css-prefix}-sort-alpha-desc:before { content: $fa-var-sort-alpha-desc; }
+.#{$fa-css-prefix}-sort-amount-asc:before { content: $fa-var-sort-amount-asc; }
+.#{$fa-css-prefix}-sort-amount-desc:before { content: $fa-var-sort-amount-desc; }
+.#{$fa-css-prefix}-sort-numeric-asc:before { content: $fa-var-sort-numeric-asc; }
+.#{$fa-css-prefix}-sort-numeric-desc:before { content: $fa-var-sort-numeric-desc; }
+.#{$fa-css-prefix}-thumbs-up:before { content: $fa-var-thumbs-up; }
+.#{$fa-css-prefix}-thumbs-down:before { content: $fa-var-thumbs-down; }
+.#{$fa-css-prefix}-youtube-square:before { content: $fa-var-youtube-square; }
+.#{$fa-css-prefix}-youtube:before { content: $fa-var-youtube; }
+.#{$fa-css-prefix}-xing:before { content: $fa-var-xing; }
+.#{$fa-css-prefix}-xing-square:before { content: $fa-var-xing-square; }
+.#{$fa-css-prefix}-youtube-play:before { content: $fa-var-youtube-play; }
+.#{$fa-css-prefix}-dropbox:before { content: $fa-var-dropbox; }
+.#{$fa-css-prefix}-stack-overflow:before { content: $fa-var-stack-overflow; }
+.#{$fa-css-prefix}-instagram:before { content: $fa-var-instagram; }
+.#{$fa-css-prefix}-flickr:before { content: $fa-var-flickr; }
+.#{$fa-css-prefix}-adn:before { content: $fa-var-adn; }
+.#{$fa-css-prefix}-bitbucket:before { content: $fa-var-bitbucket; }
+.#{$fa-css-prefix}-bitbucket-square:before { content: $fa-var-bitbucket-square; }
+.#{$fa-css-prefix}-tumblr:before { content: $fa-var-tumblr; }
+.#{$fa-css-prefix}-tumblr-square:before { content: $fa-var-tumblr-square; }
+.#{$fa-css-prefix}-long-arrow-down:before { content: $fa-var-long-arrow-down; }
+.#{$fa-css-prefix}-long-arrow-up:before { content: $fa-var-long-arrow-up; }
+.#{$fa-css-prefix}-long-arrow-left:before { content: $fa-var-long-arrow-left; }
+.#{$fa-css-prefix}-long-arrow-right:before { content: $fa-var-long-arrow-right; }
+.#{$fa-css-prefix}-apple:before { content: $fa-var-apple; }
+.#{$fa-css-prefix}-windows:before { content: $fa-var-windows; }
+.#{$fa-css-prefix}-android:before { content: $fa-var-android; }
+.#{$fa-css-prefix}-linux:before { content: $fa-var-linux; }
+.#{$fa-css-prefix}-dribbble:before { content: $fa-var-dribbble; }
+.#{$fa-css-prefix}-skype:before { content: $fa-var-skype; }
+.#{$fa-css-prefix}-foursquare:before { content: $fa-var-foursquare; }
+.#{$fa-css-prefix}-trello:before { content: $fa-var-trello; }
+.#{$fa-css-prefix}-female:before { content: $fa-var-female; }
+.#{$fa-css-prefix}-male:before { content: $fa-var-male; }
+.#{$fa-css-prefix}-gittip:before { content: $fa-var-gittip; }
+.#{$fa-css-prefix}-sun-o:before { content: $fa-var-sun-o; }
+.#{$fa-css-prefix}-moon-o:before { content: $fa-var-moon-o; }
+.#{$fa-css-prefix}-archive:before { content: $fa-var-archive; }
+.#{$fa-css-prefix}-bug:before { content: $fa-var-bug; }
+.#{$fa-css-prefix}-vk:before { content: $fa-var-vk; }
+.#{$fa-css-prefix}-weibo:before { content: $fa-var-weibo; }
+.#{$fa-css-prefix}-renren:before { content: $fa-var-renren; }
+.#{$fa-css-prefix}-pagelines:before { content: $fa-var-pagelines; }
+.#{$fa-css-prefix}-stack-exchange:before { content: $fa-var-stack-exchange; }
+.#{$fa-css-prefix}-arrow-circle-o-right:before { content: $fa-var-arrow-circle-o-right; }
+.#{$fa-css-prefix}-arrow-circle-o-left:before { content: $fa-var-arrow-circle-o-left; }
+.#{$fa-css-prefix}-toggle-left:before,
+.#{$fa-css-prefix}-caret-square-o-left:before { content: $fa-var-caret-square-o-left; }
+.#{$fa-css-prefix}-dot-circle-o:before { content: $fa-var-dot-circle-o; }
+.#{$fa-css-prefix}-wheelchair:before { content: $fa-var-wheelchair; }
+.#{$fa-css-prefix}-vimeo-square:before { content: $fa-var-vimeo-square; }
+.#{$fa-css-prefix}-turkish-lira:before,
+.#{$fa-css-prefix}-try:before { content: $fa-var-try; }
+.#{$fa-css-prefix}-plus-square-o:before { content: $fa-var-plus-square-o; }
+.#{$fa-css-prefix}-space-shuttle:before { content: $fa-var-space-shuttle; }
+.#{$fa-css-prefix}-slack:before { content: $fa-var-slack; }
+.#{$fa-css-prefix}-envelope-square:before { content: $fa-var-envelope-square; }
+.#{$fa-css-prefix}-wordpress:before { content: $fa-var-wordpress; }
+.#{$fa-css-prefix}-openid:before { content: $fa-var-openid; }
+.#{$fa-css-prefix}-institution:before,
+.#{$fa-css-prefix}-bank:before,
+.#{$fa-css-prefix}-university:before { content: $fa-var-university; }
+.#{$fa-css-prefix}-mortar-board:before,
+.#{$fa-css-prefix}-graduation-cap:before { content: $fa-var-graduation-cap; }
+.#{$fa-css-prefix}-yahoo:before { content: $fa-var-yahoo; }
+.#{$fa-css-prefix}-google:before { content: $fa-var-google; }
+.#{$fa-css-prefix}-reddit:before { content: $fa-var-reddit; }
+.#{$fa-css-prefix}-reddit-square:before { content: $fa-var-reddit-square; }
+.#{$fa-css-prefix}-stumbleupon-circle:before { content: $fa-var-stumbleupon-circle; }
+.#{$fa-css-prefix}-stumbleupon:before { content: $fa-var-stumbleupon; }
+.#{$fa-css-prefix}-delicious:before { content: $fa-var-delicious; }
+.#{$fa-css-prefix}-digg:before { content: $fa-var-digg; }
+.#{$fa-css-prefix}-pied-piper-square:before,
+.#{$fa-css-prefix}-pied-piper:before { content: $fa-var-pied-piper; }
+.#{$fa-css-prefix}-pied-piper-alt:before { content: $fa-var-pied-piper-alt; }
+.#{$fa-css-prefix}-drupal:before { content: $fa-var-drupal; }
+.#{$fa-css-prefix}-joomla:before { content: $fa-var-joomla; }
+.#{$fa-css-prefix}-language:before { content: $fa-var-language; }
+.#{$fa-css-prefix}-fax:before { content: $fa-var-fax; }
+.#{$fa-css-prefix}-building:before { content: $fa-var-building; }
+.#{$fa-css-prefix}-child:before { content: $fa-var-child; }
+.#{$fa-css-prefix}-paw:before { content: $fa-var-paw; }
+.#{$fa-css-prefix}-spoon:before { content: $fa-var-spoon; }
+.#{$fa-css-prefix}-cube:before { content: $fa-var-cube; }
+.#{$fa-css-prefix}-cubes:before { content: $fa-var-cubes; }
+.#{$fa-css-prefix}-behance:before { content: $fa-var-behance; }
+.#{$fa-css-prefix}-behance-square:before { content: $fa-var-behance-square; }
+.#{$fa-css-prefix}-steam:before { content: $fa-var-steam; }
+.#{$fa-css-prefix}-steam-square:before { content: $fa-var-steam-square; }
+.#{$fa-css-prefix}-recycle:before { content: $fa-var-recycle; }
+.#{$fa-css-prefix}-automobile:before,
+.#{$fa-css-prefix}-car:before { content: $fa-var-car; }
+.#{$fa-css-prefix}-cab:before,
+.#{$fa-css-prefix}-taxi:before { content: $fa-var-taxi; }
+.#{$fa-css-prefix}-tree:before { content: $fa-var-tree; }
+.#{$fa-css-prefix}-spotify:before { content: $fa-var-spotify; }
+.#{$fa-css-prefix}-deviantart:before { content: $fa-var-deviantart; }
+.#{$fa-css-prefix}-soundcloud:before { content: $fa-var-soundcloud; }
+.#{$fa-css-prefix}-database:before { content: $fa-var-database; }
+.#{$fa-css-prefix}-file-pdf-o:before { content: $fa-var-file-pdf-o; }
+.#{$fa-css-prefix}-file-word-o:before { content: $fa-var-file-word-o; }
+.#{$fa-css-prefix}-file-excel-o:before { content: $fa-var-file-excel-o; }
+.#{$fa-css-prefix}-file-powerpoint-o:before { content: $fa-var-file-powerpoint-o; }
+.#{$fa-css-prefix}-file-photo-o:before,
+.#{$fa-css-prefix}-file-picture-o:before,
+.#{$fa-css-prefix}-file-image-o:before { content: $fa-var-file-image-o; }
+.#{$fa-css-prefix}-file-zip-o:before,
+.#{$fa-css-prefix}-file-archive-o:before { content: $fa-var-file-archive-o; }
+.#{$fa-css-prefix}-file-sound-o:before,
+.#{$fa-css-prefix}-file-audio-o:before { content: $fa-var-file-audio-o; }
+.#{$fa-css-prefix}-file-movie-o:before,
+.#{$fa-css-prefix}-file-video-o:before { content: $fa-var-file-video-o; }
+.#{$fa-css-prefix}-file-code-o:before { content: $fa-var-file-code-o; }
+.#{$fa-css-prefix}-vine:before { content: $fa-var-vine; }
+.#{$fa-css-prefix}-codepen:before { content: $fa-var-codepen; }
+.#{$fa-css-prefix}-jsfiddle:before { content: $fa-var-jsfiddle; }
+.#{$fa-css-prefix}-life-bouy:before,
+.#{$fa-css-prefix}-life-saver:before,
+.#{$fa-css-prefix}-support:before,
+.#{$fa-css-prefix}-life-ring:before { content: $fa-var-life-ring; }
+.#{$fa-css-prefix}-circle-o-notch:before { content: $fa-var-circle-o-notch; }
+.#{$fa-css-prefix}-ra:before,
+.#{$fa-css-prefix}-rebel:before { content: $fa-var-rebel; }
+.#{$fa-css-prefix}-ge:before,
+.#{$fa-css-prefix}-empire:before { content: $fa-var-empire; }
+.#{$fa-css-prefix}-git-square:before { content: $fa-var-git-square; }
+.#{$fa-css-prefix}-git:before { content: $fa-var-git; }
+.#{$fa-css-prefix}-hacker-news:before { content: $fa-var-hacker-news; }
+.#{$fa-css-prefix}-tencent-weibo:before { content: $fa-var-tencent-weibo; }
+.#{$fa-css-prefix}-qq:before { content: $fa-var-qq; }
+.#{$fa-css-prefix}-wechat:before,
+.#{$fa-css-prefix}-weixin:before { content: $fa-var-weixin; }
+.#{$fa-css-prefix}-send:before,
+.#{$fa-css-prefix}-paper-plane:before { content: $fa-var-paper-plane; }
+.#{$fa-css-prefix}-send-o:before,
+.#{$fa-css-prefix}-paper-plane-o:before { content: $fa-var-paper-plane-o; }
+.#{$fa-css-prefix}-history:before { content: $fa-var-history; }
+.#{$fa-css-prefix}-circle-thin:before { content: $fa-var-circle-thin; }
+.#{$fa-css-prefix}-header:before { content: $fa-var-header; }
+.#{$fa-css-prefix}-paragraph:before { content: $fa-var-paragraph; }
+.#{$fa-css-prefix}-sliders:before { content: $fa-var-sliders; }
+.#{$fa-css-prefix}-share-alt:before { content: $fa-var-share-alt; }
+.#{$fa-css-prefix}-share-alt-square:before { content: $fa-var-share-alt-square; }
+.#{$fa-css-prefix}-bomb:before { content: $fa-var-bomb; }
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_larger.scss b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_larger.scss
new file mode 100755
index 0000000..41e9a81
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_larger.scss
@@ -0,0 +1,13 @@
+// Icon Sizes
+// -------------------------
+
+/* makes the font 33% larger relative to the icon container */
+.#{$fa-css-prefix}-lg {
+ font-size: (4em / 3);
+ line-height: (3em / 4);
+ vertical-align: -15%;
+}
+.#{$fa-css-prefix}-2x { font-size: 2em; }
+.#{$fa-css-prefix}-3x { font-size: 3em; }
+.#{$fa-css-prefix}-4x { font-size: 4em; }
+.#{$fa-css-prefix}-5x { font-size: 5em; }
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_list.scss b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_list.scss
new file mode 100755
index 0000000..7d1e4d5
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_list.scss
@@ -0,0 +1,19 @@
+// List Icons
+// -------------------------
+
+.#{$fa-css-prefix}-ul {
+ padding-left: 0;
+ margin-left: $fa-li-width;
+ list-style-type: none;
+ > li { position: relative; }
+}
+.#{$fa-css-prefix}-li {
+ position: absolute;
+ left: -$fa-li-width;
+ width: $fa-li-width;
+ top: (2em / 14);
+ text-align: center;
+ &.#{$fa-css-prefix}-lg {
+ left: -$fa-li-width + (4em / 14);
+ }
+}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_mixins.scss b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_mixins.scss
new file mode 100755
index 0000000..3354e69
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_mixins.scss
@@ -0,0 +1,20 @@
+// Mixins
+// --------------------------
+
+@mixin fa-icon-rotate($degrees, $rotation) {
+ filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation});
+ -webkit-transform: rotate($degrees);
+ -moz-transform: rotate($degrees);
+ -ms-transform: rotate($degrees);
+ -o-transform: rotate($degrees);
+ transform: rotate($degrees);
+}
+
+@mixin fa-icon-flip($horiz, $vert, $rotation) {
+ filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation});
+ -webkit-transform: scale($horiz, $vert);
+ -moz-transform: scale($horiz, $vert);
+ -ms-transform: scale($horiz, $vert);
+ -o-transform: scale($horiz, $vert);
+ transform: scale($horiz, $vert);
+}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_path.scss b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_path.scss
new file mode 100755
index 0000000..fd21c35
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_path.scss
@@ -0,0 +1,14 @@
+/* FONT PATH
+ * -------------------------- */
+
+@font-face {
+ font-family: 'FontAwesome';
+ src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
+ src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
+ url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
+ url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
+ url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
+ //src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
+ font-weight: normal;
+ font-style: normal;
+}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_rotated-flipped.scss b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_rotated-flipped.scss
new file mode 100755
index 0000000..343fa55
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_rotated-flipped.scss
@@ -0,0 +1,9 @@
+// Rotated & Flipped Icons
+// -------------------------
+
+.#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); }
+.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
+.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
+
+.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
+.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_spinning.scss b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_spinning.scss
new file mode 100755
index 0000000..c378744
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_spinning.scss
@@ -0,0 +1,32 @@
+// Spinning Icons
+// --------------------------
+
+.#{$fa-css-prefix}-spin {
+ -webkit-animation: spin 2s infinite linear;
+ -moz-animation: spin 2s infinite linear;
+ -o-animation: spin 2s infinite linear;
+ animation: spin 2s infinite linear;
+}
+
+@-moz-keyframes spin {
+ 0% { -moz-transform: rotate(0deg); }
+ 100% { -moz-transform: rotate(359deg); }
+}
+@-webkit-keyframes spin {
+ 0% { -webkit-transform: rotate(0deg); }
+ 100% { -webkit-transform: rotate(359deg); }
+}
+@-o-keyframes spin {
+ 0% { -o-transform: rotate(0deg); }
+ 100% { -o-transform: rotate(359deg); }
+}
+@keyframes spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+}
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_stacked.scss b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_stacked.scss
new file mode 100755
index 0000000..aef7403
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_stacked.scss
@@ -0,0 +1,20 @@
+// Stacked Icons
+// -------------------------
+
+.#{$fa-css-prefix}-stack {
+ position: relative;
+ display: inline-block;
+ width: 2em;
+ height: 2em;
+ line-height: 2em;
+ vertical-align: middle;
+}
+.#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {
+ position: absolute;
+ left: 0;
+ width: 100%;
+ text-align: center;
+}
+.#{$fa-css-prefix}-stack-1x { line-height: inherit; }
+.#{$fa-css-prefix}-stack-2x { font-size: 2em; }
+.#{$fa-css-prefix}-inverse { color: $fa-inverse; }
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_variables.scss b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_variables.scss
new file mode 100755
index 0000000..ac2b505
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/_variables.scss
@@ -0,0 +1,515 @@
+// Variables
+// --------------------------
+
+$fa-font-path: "../fonts" !default;
+//$fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.1.0/fonts" !default; // for referencing Bootstrap CDN font files directly
+$fa-css-prefix: fa !default;
+$fa-version: "4.1.0" !default;
+$fa-border-color: #eee !default;
+$fa-inverse: #fff !default;
+$fa-li-width: (30em / 14) !default;
+
+$fa-var-adjust: "\f042";
+$fa-var-adn: "\f170";
+$fa-var-align-center: "\f037";
+$fa-var-align-justify: "\f039";
+$fa-var-align-left: "\f036";
+$fa-var-align-right: "\f038";
+$fa-var-ambulance: "\f0f9";
+$fa-var-anchor: "\f13d";
+$fa-var-android: "\f17b";
+$fa-var-angle-double-down: "\f103";
+$fa-var-angle-double-left: "\f100";
+$fa-var-angle-double-right: "\f101";
+$fa-var-angle-double-up: "\f102";
+$fa-var-angle-down: "\f107";
+$fa-var-angle-left: "\f104";
+$fa-var-angle-right: "\f105";
+$fa-var-angle-up: "\f106";
+$fa-var-apple: "\f179";
+$fa-var-archive: "\f187";
+$fa-var-arrow-circle-down: "\f0ab";
+$fa-var-arrow-circle-left: "\f0a8";
+$fa-var-arrow-circle-o-down: "\f01a";
+$fa-var-arrow-circle-o-left: "\f190";
+$fa-var-arrow-circle-o-right: "\f18e";
+$fa-var-arrow-circle-o-up: "\f01b";
+$fa-var-arrow-circle-right: "\f0a9";
+$fa-var-arrow-circle-up: "\f0aa";
+$fa-var-arrow-down: "\f063";
+$fa-var-arrow-left: "\f060";
+$fa-var-arrow-right: "\f061";
+$fa-var-arrow-up: "\f062";
+$fa-var-arrows: "\f047";
+$fa-var-arrows-alt: "\f0b2";
+$fa-var-arrows-h: "\f07e";
+$fa-var-arrows-v: "\f07d";
+$fa-var-asterisk: "\f069";
+$fa-var-automobile: "\f1b9";
+$fa-var-backward: "\f04a";
+$fa-var-ban: "\f05e";
+$fa-var-bank: "\f19c";
+$fa-var-bar-chart-o: "\f080";
+$fa-var-barcode: "\f02a";
+$fa-var-bars: "\f0c9";
+$fa-var-beer: "\f0fc";
+$fa-var-behance: "\f1b4";
+$fa-var-behance-square: "\f1b5";
+$fa-var-bell: "\f0f3";
+$fa-var-bell-o: "\f0a2";
+$fa-var-bitbucket: "\f171";
+$fa-var-bitbucket-square: "\f172";
+$fa-var-bitcoin: "\f15a";
+$fa-var-bold: "\f032";
+$fa-var-bolt: "\f0e7";
+$fa-var-bomb: "\f1e2";
+$fa-var-book: "\f02d";
+$fa-var-bookmark: "\f02e";
+$fa-var-bookmark-o: "\f097";
+$fa-var-briefcase: "\f0b1";
+$fa-var-btc: "\f15a";
+$fa-var-bug: "\f188";
+$fa-var-building: "\f1ad";
+$fa-var-building-o: "\f0f7";
+$fa-var-bullhorn: "\f0a1";
+$fa-var-bullseye: "\f140";
+$fa-var-cab: "\f1ba";
+$fa-var-calendar: "\f073";
+$fa-var-calendar-o: "\f133";
+$fa-var-camera: "\f030";
+$fa-var-camera-retro: "\f083";
+$fa-var-car: "\f1b9";
+$fa-var-caret-down: "\f0d7";
+$fa-var-caret-left: "\f0d9";
+$fa-var-caret-right: "\f0da";
+$fa-var-caret-square-o-down: "\f150";
+$fa-var-caret-square-o-left: "\f191";
+$fa-var-caret-square-o-right: "\f152";
+$fa-var-caret-square-o-up: "\f151";
+$fa-var-caret-up: "\f0d8";
+$fa-var-certificate: "\f0a3";
+$fa-var-chain: "\f0c1";
+$fa-var-chain-broken: "\f127";
+$fa-var-check: "\f00c";
+$fa-var-check-circle: "\f058";
+$fa-var-check-circle-o: "\f05d";
+$fa-var-check-square: "\f14a";
+$fa-var-check-square-o: "\f046";
+$fa-var-chevron-circle-down: "\f13a";
+$fa-var-chevron-circle-left: "\f137";
+$fa-var-chevron-circle-right: "\f138";
+$fa-var-chevron-circle-up: "\f139";
+$fa-var-chevron-down: "\f078";
+$fa-var-chevron-left: "\f053";
+$fa-var-chevron-right: "\f054";
+$fa-var-chevron-up: "\f077";
+$fa-var-child: "\f1ae";
+$fa-var-circle: "\f111";
+$fa-var-circle-o: "\f10c";
+$fa-var-circle-o-notch: "\f1ce";
+$fa-var-circle-thin: "\f1db";
+$fa-var-clipboard: "\f0ea";
+$fa-var-clock-o: "\f017";
+$fa-var-cloud: "\f0c2";
+$fa-var-cloud-download: "\f0ed";
+$fa-var-cloud-upload: "\f0ee";
+$fa-var-cny: "\f157";
+$fa-var-code: "\f121";
+$fa-var-code-fork: "\f126";
+$fa-var-codepen: "\f1cb";
+$fa-var-coffee: "\f0f4";
+$fa-var-cog: "\f013";
+$fa-var-cogs: "\f085";
+$fa-var-columns: "\f0db";
+$fa-var-comment: "\f075";
+$fa-var-comment-o: "\f0e5";
+$fa-var-comments: "\f086";
+$fa-var-comments-o: "\f0e6";
+$fa-var-compass: "\f14e";
+$fa-var-compress: "\f066";
+$fa-var-copy: "\f0c5";
+$fa-var-credit-card: "\f09d";
+$fa-var-crop: "\f125";
+$fa-var-crosshairs: "\f05b";
+$fa-var-css3: "\f13c";
+$fa-var-cube: "\f1b2";
+$fa-var-cubes: "\f1b3";
+$fa-var-cut: "\f0c4";
+$fa-var-cutlery: "\f0f5";
+$fa-var-dashboard: "\f0e4";
+$fa-var-database: "\f1c0";
+$fa-var-dedent: "\f03b";
+$fa-var-delicious: "\f1a5";
+$fa-var-desktop: "\f108";
+$fa-var-deviantart: "\f1bd";
+$fa-var-digg: "\f1a6";
+$fa-var-dollar: "\f155";
+$fa-var-dot-circle-o: "\f192";
+$fa-var-download: "\f019";
+$fa-var-dribbble: "\f17d";
+$fa-var-dropbox: "\f16b";
+$fa-var-drupal: "\f1a9";
+$fa-var-edit: "\f044";
+$fa-var-eject: "\f052";
+$fa-var-ellipsis-h: "\f141";
+$fa-var-ellipsis-v: "\f142";
+$fa-var-empire: "\f1d1";
+$fa-var-envelope: "\f0e0";
+$fa-var-envelope-o: "\f003";
+$fa-var-envelope-square: "\f199";
+$fa-var-eraser: "\f12d";
+$fa-var-eur: "\f153";
+$fa-var-euro: "\f153";
+$fa-var-exchange: "\f0ec";
+$fa-var-exclamation: "\f12a";
+$fa-var-exclamation-circle: "\f06a";
+$fa-var-exclamation-triangle: "\f071";
+$fa-var-expand: "\f065";
+$fa-var-external-link: "\f08e";
+$fa-var-external-link-square: "\f14c";
+$fa-var-eye: "\f06e";
+$fa-var-eye-slash: "\f070";
+$fa-var-facebook: "\f09a";
+$fa-var-facebook-square: "\f082";
+$fa-var-fast-backward: "\f049";
+$fa-var-fast-forward: "\f050";
+$fa-var-fax: "\f1ac";
+$fa-var-female: "\f182";
+$fa-var-fighter-jet: "\f0fb";
+$fa-var-file: "\f15b";
+$fa-var-file-archive-o: "\f1c6";
+$fa-var-file-audio-o: "\f1c7";
+$fa-var-file-code-o: "\f1c9";
+$fa-var-file-excel-o: "\f1c3";
+$fa-var-file-image-o: "\f1c5";
+$fa-var-file-movie-o: "\f1c8";
+$fa-var-file-o: "\f016";
+$fa-var-file-pdf-o: "\f1c1";
+$fa-var-file-photo-o: "\f1c5";
+$fa-var-file-picture-o: "\f1c5";
+$fa-var-file-powerpoint-o: "\f1c4";
+$fa-var-file-sound-o: "\f1c7";
+$fa-var-file-text: "\f15c";
+$fa-var-file-text-o: "\f0f6";
+$fa-var-file-video-o: "\f1c8";
+$fa-var-file-word-o: "\f1c2";
+$fa-var-file-zip-o: "\f1c6";
+$fa-var-files-o: "\f0c5";
+$fa-var-film: "\f008";
+$fa-var-filter: "\f0b0";
+$fa-var-fire: "\f06d";
+$fa-var-fire-extinguisher: "\f134";
+$fa-var-flag: "\f024";
+$fa-var-flag-checkered: "\f11e";
+$fa-var-flag-o: "\f11d";
+$fa-var-flash: "\f0e7";
+$fa-var-flask: "\f0c3";
+$fa-var-flickr: "\f16e";
+$fa-var-floppy-o: "\f0c7";
+$fa-var-folder: "\f07b";
+$fa-var-folder-o: "\f114";
+$fa-var-folder-open: "\f07c";
+$fa-var-folder-open-o: "\f115";
+$fa-var-font: "\f031";
+$fa-var-forward: "\f04e";
+$fa-var-foursquare: "\f180";
+$fa-var-frown-o: "\f119";
+$fa-var-gamepad: "\f11b";
+$fa-var-gavel: "\f0e3";
+$fa-var-gbp: "\f154";
+$fa-var-ge: "\f1d1";
+$fa-var-gear: "\f013";
+$fa-var-gears: "\f085";
+$fa-var-gift: "\f06b";
+$fa-var-git: "\f1d3";
+$fa-var-git-square: "\f1d2";
+$fa-var-github: "\f09b";
+$fa-var-github-alt: "\f113";
+$fa-var-github-square: "\f092";
+$fa-var-gittip: "\f184";
+$fa-var-glass: "\f000";
+$fa-var-globe: "\f0ac";
+$fa-var-google: "\f1a0";
+$fa-var-google-plus: "\f0d5";
+$fa-var-google-plus-square: "\f0d4";
+$fa-var-graduation-cap: "\f19d";
+$fa-var-group: "\f0c0";
+$fa-var-h-square: "\f0fd";
+$fa-var-hacker-news: "\f1d4";
+$fa-var-hand-o-down: "\f0a7";
+$fa-var-hand-o-left: "\f0a5";
+$fa-var-hand-o-right: "\f0a4";
+$fa-var-hand-o-up: "\f0a6";
+$fa-var-hdd-o: "\f0a0";
+$fa-var-header: "\f1dc";
+$fa-var-headphones: "\f025";
+$fa-var-heart: "\f004";
+$fa-var-heart-o: "\f08a";
+$fa-var-history: "\f1da";
+$fa-var-home: "\f015";
+$fa-var-hospital-o: "\f0f8";
+$fa-var-html5: "\f13b";
+$fa-var-image: "\f03e";
+$fa-var-inbox: "\f01c";
+$fa-var-indent: "\f03c";
+$fa-var-info: "\f129";
+$fa-var-info-circle: "\f05a";
+$fa-var-inr: "\f156";
+$fa-var-instagram: "\f16d";
+$fa-var-institution: "\f19c";
+$fa-var-italic: "\f033";
+$fa-var-joomla: "\f1aa";
+$fa-var-jpy: "\f157";
+$fa-var-jsfiddle: "\f1cc";
+$fa-var-key: "\f084";
+$fa-var-keyboard-o: "\f11c";
+$fa-var-krw: "\f159";
+$fa-var-language: "\f1ab";
+$fa-var-laptop: "\f109";
+$fa-var-leaf: "\f06c";
+$fa-var-legal: "\f0e3";
+$fa-var-lemon-o: "\f094";
+$fa-var-level-down: "\f149";
+$fa-var-level-up: "\f148";
+$fa-var-life-bouy: "\f1cd";
+$fa-var-life-ring: "\f1cd";
+$fa-var-life-saver: "\f1cd";
+$fa-var-lightbulb-o: "\f0eb";
+$fa-var-link: "\f0c1";
+$fa-var-linkedin: "\f0e1";
+$fa-var-linkedin-square: "\f08c";
+$fa-var-linux: "\f17c";
+$fa-var-list: "\f03a";
+$fa-var-list-alt: "\f022";
+$fa-var-list-ol: "\f0cb";
+$fa-var-list-ul: "\f0ca";
+$fa-var-location-arrow: "\f124";
+$fa-var-lock: "\f023";
+$fa-var-long-arrow-down: "\f175";
+$fa-var-long-arrow-left: "\f177";
+$fa-var-long-arrow-right: "\f178";
+$fa-var-long-arrow-up: "\f176";
+$fa-var-magic: "\f0d0";
+$fa-var-magnet: "\f076";
+$fa-var-mail-forward: "\f064";
+$fa-var-mail-reply: "\f112";
+$fa-var-mail-reply-all: "\f122";
+$fa-var-male: "\f183";
+$fa-var-map-marker: "\f041";
+$fa-var-maxcdn: "\f136";
+$fa-var-medkit: "\f0fa";
+$fa-var-meh-o: "\f11a";
+$fa-var-microphone: "\f130";
+$fa-var-microphone-slash: "\f131";
+$fa-var-minus: "\f068";
+$fa-var-minus-circle: "\f056";
+$fa-var-minus-square: "\f146";
+$fa-var-minus-square-o: "\f147";
+$fa-var-mobile: "\f10b";
+$fa-var-mobile-phone: "\f10b";
+$fa-var-money: "\f0d6";
+$fa-var-moon-o: "\f186";
+$fa-var-mortar-board: "\f19d";
+$fa-var-music: "\f001";
+$fa-var-navicon: "\f0c9";
+$fa-var-openid: "\f19b";
+$fa-var-outdent: "\f03b";
+$fa-var-pagelines: "\f18c";
+$fa-var-paper-plane: "\f1d8";
+$fa-var-paper-plane-o: "\f1d9";
+$fa-var-paperclip: "\f0c6";
+$fa-var-paragraph: "\f1dd";
+$fa-var-paste: "\f0ea";
+$fa-var-pause: "\f04c";
+$fa-var-paw: "\f1b0";
+$fa-var-pencil: "\f040";
+$fa-var-pencil-square: "\f14b";
+$fa-var-pencil-square-o: "\f044";
+$fa-var-phone: "\f095";
+$fa-var-phone-square: "\f098";
+$fa-var-photo: "\f03e";
+$fa-var-picture-o: "\f03e";
+$fa-var-pied-piper: "\f1a7";
+$fa-var-pied-piper-alt: "\f1a8";
+$fa-var-pied-piper-square: "\f1a7";
+$fa-var-pinterest: "\f0d2";
+$fa-var-pinterest-square: "\f0d3";
+$fa-var-plane: "\f072";
+$fa-var-play: "\f04b";
+$fa-var-play-circle: "\f144";
+$fa-var-play-circle-o: "\f01d";
+$fa-var-plus: "\f067";
+$fa-var-plus-circle: "\f055";
+$fa-var-plus-square: "\f0fe";
+$fa-var-plus-square-o: "\f196";
+$fa-var-power-off: "\f011";
+$fa-var-print: "\f02f";
+$fa-var-puzzle-piece: "\f12e";
+$fa-var-qq: "\f1d6";
+$fa-var-qrcode: "\f029";
+$fa-var-question: "\f128";
+$fa-var-question-circle: "\f059";
+$fa-var-quote-left: "\f10d";
+$fa-var-quote-right: "\f10e";
+$fa-var-ra: "\f1d0";
+$fa-var-random: "\f074";
+$fa-var-rebel: "\f1d0";
+$fa-var-recycle: "\f1b8";
+$fa-var-reddit: "\f1a1";
+$fa-var-reddit-square: "\f1a2";
+$fa-var-refresh: "\f021";
+$fa-var-renren: "\f18b";
+$fa-var-reorder: "\f0c9";
+$fa-var-repeat: "\f01e";
+$fa-var-reply: "\f112";
+$fa-var-reply-all: "\f122";
+$fa-var-retweet: "\f079";
+$fa-var-rmb: "\f157";
+$fa-var-road: "\f018";
+$fa-var-rocket: "\f135";
+$fa-var-rotate-left: "\f0e2";
+$fa-var-rotate-right: "\f01e";
+$fa-var-rouble: "\f158";
+$fa-var-rss: "\f09e";
+$fa-var-rss-square: "\f143";
+$fa-var-rub: "\f158";
+$fa-var-ruble: "\f158";
+$fa-var-rupee: "\f156";
+$fa-var-save: "\f0c7";
+$fa-var-scissors: "\f0c4";
+$fa-var-search: "\f002";
+$fa-var-search-minus: "\f010";
+$fa-var-search-plus: "\f00e";
+$fa-var-send: "\f1d8";
+$fa-var-send-o: "\f1d9";
+$fa-var-share: "\f064";
+$fa-var-share-alt: "\f1e0";
+$fa-var-share-alt-square: "\f1e1";
+$fa-var-share-square: "\f14d";
+$fa-var-share-square-o: "\f045";
+$fa-var-shield: "\f132";
+$fa-var-shopping-cart: "\f07a";
+$fa-var-sign-in: "\f090";
+$fa-var-sign-out: "\f08b";
+$fa-var-signal: "\f012";
+$fa-var-sitemap: "\f0e8";
+$fa-var-skype: "\f17e";
+$fa-var-slack: "\f198";
+$fa-var-sliders: "\f1de";
+$fa-var-smile-o: "\f118";
+$fa-var-sort: "\f0dc";
+$fa-var-sort-alpha-asc: "\f15d";
+$fa-var-sort-alpha-desc: "\f15e";
+$fa-var-sort-amount-asc: "\f160";
+$fa-var-sort-amount-desc: "\f161";
+$fa-var-sort-asc: "\f0de";
+$fa-var-sort-desc: "\f0dd";
+$fa-var-sort-down: "\f0dd";
+$fa-var-sort-numeric-asc: "\f162";
+$fa-var-sort-numeric-desc: "\f163";
+$fa-var-sort-up: "\f0de";
+$fa-var-soundcloud: "\f1be";
+$fa-var-space-shuttle: "\f197";
+$fa-var-spinner: "\f110";
+$fa-var-spoon: "\f1b1";
+$fa-var-spotify: "\f1bc";
+$fa-var-square: "\f0c8";
+$fa-var-square-o: "\f096";
+$fa-var-stack-exchange: "\f18d";
+$fa-var-stack-overflow: "\f16c";
+$fa-var-star: "\f005";
+$fa-var-star-half: "\f089";
+$fa-var-star-half-empty: "\f123";
+$fa-var-star-half-full: "\f123";
+$fa-var-star-half-o: "\f123";
+$fa-var-star-o: "\f006";
+$fa-var-steam: "\f1b6";
+$fa-var-steam-square: "\f1b7";
+$fa-var-step-backward: "\f048";
+$fa-var-step-forward: "\f051";
+$fa-var-stethoscope: "\f0f1";
+$fa-var-stop: "\f04d";
+$fa-var-strikethrough: "\f0cc";
+$fa-var-stumbleupon: "\f1a4";
+$fa-var-stumbleupon-circle: "\f1a3";
+$fa-var-subscript: "\f12c";
+$fa-var-suitcase: "\f0f2";
+$fa-var-sun-o: "\f185";
+$fa-var-superscript: "\f12b";
+$fa-var-support: "\f1cd";
+$fa-var-table: "\f0ce";
+$fa-var-tablet: "\f10a";
+$fa-var-tachometer: "\f0e4";
+$fa-var-tag: "\f02b";
+$fa-var-tags: "\f02c";
+$fa-var-tasks: "\f0ae";
+$fa-var-taxi: "\f1ba";
+$fa-var-tencent-weibo: "\f1d5";
+$fa-var-terminal: "\f120";
+$fa-var-text-height: "\f034";
+$fa-var-text-width: "\f035";
+$fa-var-th: "\f00a";
+$fa-var-th-large: "\f009";
+$fa-var-th-list: "\f00b";
+$fa-var-thumb-tack: "\f08d";
+$fa-var-thumbs-down: "\f165";
+$fa-var-thumbs-o-down: "\f088";
+$fa-var-thumbs-o-up: "\f087";
+$fa-var-thumbs-up: "\f164";
+$fa-var-ticket: "\f145";
+$fa-var-times: "\f00d";
+$fa-var-times-circle: "\f057";
+$fa-var-times-circle-o: "\f05c";
+$fa-var-tint: "\f043";
+$fa-var-toggle-down: "\f150";
+$fa-var-toggle-left: "\f191";
+$fa-var-toggle-right: "\f152";
+$fa-var-toggle-up: "\f151";
+$fa-var-trash-o: "\f014";
+$fa-var-tree: "\f1bb";
+$fa-var-trello: "\f181";
+$fa-var-trophy: "\f091";
+$fa-var-truck: "\f0d1";
+$fa-var-try: "\f195";
+$fa-var-tumblr: "\f173";
+$fa-var-tumblr-square: "\f174";
+$fa-var-turkish-lira: "\f195";
+$fa-var-twitter: "\f099";
+$fa-var-twitter-square: "\f081";
+$fa-var-umbrella: "\f0e9";
+$fa-var-underline: "\f0cd";
+$fa-var-undo: "\f0e2";
+$fa-var-university: "\f19c";
+$fa-var-unlink: "\f127";
+$fa-var-unlock: "\f09c";
+$fa-var-unlock-alt: "\f13e";
+$fa-var-unsorted: "\f0dc";
+$fa-var-upload: "\f093";
+$fa-var-usd: "\f155";
+$fa-var-user: "\f007";
+$fa-var-user-md: "\f0f0";
+$fa-var-users: "\f0c0";
+$fa-var-video-camera: "\f03d";
+$fa-var-vimeo-square: "\f194";
+$fa-var-vine: "\f1ca";
+$fa-var-vk: "\f189";
+$fa-var-volume-down: "\f027";
+$fa-var-volume-off: "\f026";
+$fa-var-volume-up: "\f028";
+$fa-var-warning: "\f071";
+$fa-var-wechat: "\f1d7";
+$fa-var-weibo: "\f18a";
+$fa-var-weixin: "\f1d7";
+$fa-var-wheelchair: "\f193";
+$fa-var-windows: "\f17a";
+$fa-var-won: "\f159";
+$fa-var-wordpress: "\f19a";
+$fa-var-wrench: "\f0ad";
+$fa-var-xing: "\f168";
+$fa-var-xing-square: "\f169";
+$fa-var-yahoo: "\f19e";
+$fa-var-yen: "\f157";
+$fa-var-youtube: "\f167";
+$fa-var-youtube-play: "\f16a";
+$fa-var-youtube-square: "\f166";
+
diff --git a/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/font-awesome.scss b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/font-awesome.scss
new file mode 100755
index 0000000..2307dbd
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/font-awesome-4.1.0/scss/font-awesome.scss
@@ -0,0 +1,17 @@
+/*!
+ * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
+ * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+
+@import "variables";
+@import "mixins";
+@import "path";
+@import "core";
+@import "larger";
+@import "fixed-width";
+@import "list";
+@import "bordered-pulled";
+@import "spinning";
+@import "rotated-flipped";
+@import "stacked";
+@import "icons";
diff --git a/ungleich_page/static/ungleich_page/fonts/glyphicons-halflings-regular.eot b/ungleich_page/static/ungleich_page/fonts/glyphicons-halflings-regular.eot
new file mode 100755
index 0000000..4a4ca86
Binary files /dev/null and b/ungleich_page/static/ungleich_page/fonts/glyphicons-halflings-regular.eot differ
diff --git a/ungleich_page/static/ungleich_page/fonts/glyphicons-halflings-regular.svg b/ungleich_page/static/ungleich_page/fonts/glyphicons-halflings-regular.svg
new file mode 100755
index 0000000..25691af
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/fonts/glyphicons-halflings-regular.svg
@@ -0,0 +1,229 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ungleich_page/static/ungleich_page/fonts/glyphicons-halflings-regular.ttf b/ungleich_page/static/ungleich_page/fonts/glyphicons-halflings-regular.ttf
new file mode 100755
index 0000000..67fa00b
Binary files /dev/null and b/ungleich_page/static/ungleich_page/fonts/glyphicons-halflings-regular.ttf differ
diff --git a/ungleich_page/static/ungleich_page/fonts/glyphicons-halflings-regular.woff b/ungleich_page/static/ungleich_page/fonts/glyphicons-halflings-regular.woff
new file mode 100755
index 0000000..8c54182
Binary files /dev/null and b/ungleich_page/static/ungleich_page/fonts/glyphicons-halflings-regular.woff differ
diff --git a/ungleich_page/static/ungleich_page/img/about/2000.jpg b/ungleich_page/static/ungleich_page/img/about/2000.jpg
new file mode 100755
index 0000000..41590e3
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/about/2000.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/about/2013.jpg b/ungleich_page/static/ungleich_page/img/about/2013.jpg
new file mode 100755
index 0000000..b5e0bc8
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/about/2013.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/about/2014.jpg b/ungleich_page/static/ungleich_page/img/about/2014.jpg
new file mode 100755
index 0000000..b274040
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/about/2014.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/about/2015.jpg b/ungleich_page/static/ungleich_page/img/about/2015.jpg
new file mode 100755
index 0000000..4d65fe7
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/about/2015.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/about/2016a.jpg b/ungleich_page/static/ungleich_page/img/about/2016a.jpg
new file mode 100755
index 0000000..4a1248b
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/about/2016a.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/about/2016a.png b/ungleich_page/static/ungleich_page/img/about/2016a.png
new file mode 100755
index 0000000..b808879
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/about/2016a.png differ
diff --git a/ungleich_page/static/ungleich_page/img/about/2016b.jpg b/ungleich_page/static/ungleich_page/img/about/2016b.jpg
new file mode 100755
index 0000000..8be67f0
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/about/2016b.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/about/2017a.jpg b/ungleich_page/static/ungleich_page/img/about/2017a.jpg
new file mode 100755
index 0000000..d160297
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/about/2017a.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/about/2017b.jpg b/ungleich_page/static/ungleich_page/img/about/2017b.jpg
new file mode 100755
index 0000000..f813f25
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/about/2017b.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/about/3 copy.jpg b/ungleich_page/static/ungleich_page/img/about/3 copy.jpg
new file mode 100755
index 0000000..71ba43f
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/about/3 copy.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/about/3.jpg b/ungleich_page/static/ungleich_page/img/about/3.jpg
new file mode 100755
index 0000000..7df5bb7
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/about/3.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/about/3.png b/ungleich_page/static/ungleich_page/img/about/3.png
new file mode 100755
index 0000000..8a49ca3
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/about/3.png differ
diff --git a/ungleich_page/static/ungleich_page/img/about/4.jpg b/ungleich_page/static/ungleich_page/img/about/4.jpg
new file mode 100755
index 0000000..421fd0f
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/about/4.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/about/5.jpg b/ungleich_page/static/ungleich_page/img/about/5.jpg
new file mode 100755
index 0000000..678352f
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/about/5.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/client-logos/logo_ruag.jpg b/ungleich_page/static/ungleich_page/img/client-logos/logo_ruag.jpg
new file mode 100755
index 0000000..cac1469
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/client-logos/logo_ruag.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/client-logos/logo_ruag.png b/ungleich_page/static/ungleich_page/img/client-logos/logo_ruag.png
new file mode 100755
index 0000000..8809e97
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/client-logos/logo_ruag.png differ
diff --git a/ungleich_page/static/ungleich_page/img/client-logos/panter.png b/ungleich_page/static/ungleich_page/img/client-logos/panter.png
new file mode 100755
index 0000000..6a21bf7
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/client-logos/panter.png differ
diff --git a/ungleich_page/static/ungleich_page/img/client-logos/teralytics.png b/ungleich_page/static/ungleich_page/img/client-logos/teralytics.png
new file mode 100755
index 0000000..99a423a
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/client-logos/teralytics.png differ
diff --git a/ungleich_page/static/ungleich_page/img/favicon.ico b/ungleich_page/static/ungleich_page/img/favicon.ico
new file mode 100755
index 0000000..9cd0fe7
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/favicon.ico differ
diff --git a/ungleich_page/static/ungleich_page/img/glasfaser/a.jpg b/ungleich_page/static/ungleich_page/img/glasfaser/a.jpg
new file mode 100755
index 0000000..d4b0357
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/glasfaser/a.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/glasfaser/b.jpg b/ungleich_page/static/ungleich_page/img/glasfaser/b.jpg
new file mode 100755
index 0000000..5c23814
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/glasfaser/b.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/glasfaser/business.svg b/ungleich_page/static/ungleich_page/img/glasfaser/business.svg
new file mode 100755
index 0000000..ee18a4e
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/img/glasfaser/business.svg
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ IP-Adressen
+
+ IPv6
+
+
+
+ IPv4
+
+
diff --git a/ungleich_page/static/ungleich_page/img/glasfaser/c.jpg b/ungleich_page/static/ungleich_page/img/glasfaser/c.jpg
new file mode 100755
index 0000000..ba890bd
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/glasfaser/c.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/glasfaser/d.jpg b/ungleich_page/static/ungleich_page/img/glasfaser/d.jpg
new file mode 100755
index 0000000..284216d
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/glasfaser/d.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/glasfaser/header-nico-sans.jpg b/ungleich_page/static/ungleich_page/img/glasfaser/header-nico-sans.jpg
new file mode 100755
index 0000000..d6398b0
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/glasfaser/header-nico-sans.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/glasfaser/header-pricetag.png b/ungleich_page/static/ungleich_page/img/glasfaser/header-pricetag.png
new file mode 100755
index 0000000..68a9368
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/glasfaser/header-pricetag.png differ
diff --git a/ungleich_page/static/ungleich_page/img/glasfaser/ip.svg b/ungleich_page/static/ungleich_page/img/glasfaser/ip.svg
new file mode 100755
index 0000000..8067f11
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/img/glasfaser/ip.svg
@@ -0,0 +1,168 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ungleich_page/static/ungleich_page/img/glasfaser/switch.svg b/ungleich_page/static/ungleich_page/img/glasfaser/switch.svg
new file mode 100755
index 0000000..dde4ca5
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/img/glasfaser/switch.svg
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ungleich_page/static/ungleich_page/img/header-bg.jpg b/ungleich_page/static/ungleich_page/img/header-bg.jpg
new file mode 100755
index 0000000..f847d8e
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/header-bg.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/header_mountain.svg b/ungleich_page/static/ungleich_page/img/header_mountain.svg
new file mode 100755
index 0000000..3d3d83a
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/img/header_mountain.svg
@@ -0,0 +1,585 @@
+
+
+
+ header_mountain
+ Created with Sketch.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ungleich_page/static/ungleich_page/img/logo_200x200.svg b/ungleich_page/static/ungleich_page/img/logo_200x200.svg
new file mode 100755
index 0000000..6e8e076
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/img/logo_200x200.svg
@@ -0,0 +1,229 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ungleich_page/static/ungleich_page/img/logo_black.svg b/ungleich_page/static/ungleich_page/img/logo_black.svg
new file mode 100755
index 0000000..99e8f59
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/img/logo_black.svg
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ungleich_page/static/ungleich_page/img/logo_white.svg b/ungleich_page/static/ungleich_page/img/logo_white.svg
new file mode 100755
index 0000000..0f9de94
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/img/logo_white.svg
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ungleich_page/static/ungleich_page/img/logos/CentOS.jpg b/ungleich_page/static/ungleich_page/img/logos/CentOS.jpg
new file mode 100755
index 0000000..408b052
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/CentOS.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/Gentoo-site_logo.jpg b/ungleich_page/static/ungleich_page/img/logos/Gentoo-site_logo.jpg
new file mode 100755
index 0000000..fabf8d7
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/Gentoo-site_logo.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/NetBSD.jpg b/ungleich_page/static/ungleich_page/img/logos/NetBSD.jpg
new file mode 100755
index 0000000..0a56130
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/NetBSD.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/Puppet.jpg b/ungleich_page/static/ungleich_page/img/logos/Puppet.jpg
new file mode 100755
index 0000000..4962b5c
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/Puppet.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/aetuts.jpg b/ungleich_page/static/ungleich_page/img/logos/aetuts.jpg
new file mode 100755
index 0000000..c75adda
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/aetuts.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/apache.jpg b/ungleich_page/static/ungleich_page/img/logos/apache.jpg
new file mode 100755
index 0000000..0889552
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/apache.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/cdistbyungleich.jpg b/ungleich_page/static/ungleich_page/img/logos/cdistbyungleich.jpg
new file mode 100755
index 0000000..c5cb18c
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/cdistbyungleich.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/ceph.jpg b/ungleich_page/static/ungleich_page/img/logos/ceph.jpg
new file mode 100755
index 0000000..f13f2e1
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/ceph.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/creative-market.jpg b/ungleich_page/static/ungleich_page/img/logos/creative-market.jpg
new file mode 100755
index 0000000..639b5d9
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/creative-market.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/creative-market.psd b/ungleich_page/static/ungleich_page/img/logos/creative-market.psd
new file mode 100755
index 0000000..4000de4
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/creative-market.psd differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/debian.jpg b/ungleich_page/static/ungleich_page/img/logos/debian.jpg
new file mode 100755
index 0000000..5af4185
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/debian.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/designmodo.jpg b/ungleich_page/static/ungleich_page/img/logos/designmodo.jpg
new file mode 100755
index 0000000..e79048d
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/designmodo.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/envato.jpg b/ungleich_page/static/ungleich_page/img/logos/envato.jpg
new file mode 100755
index 0000000..0cdb2bd
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/envato.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/freebsd.jpg b/ungleich_page/static/ungleich_page/img/logos/freebsd.jpg
new file mode 100755
index 0000000..27dba9e
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/freebsd.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/gluster.jpg b/ungleich_page/static/ungleich_page/img/logos/gluster.jpg
new file mode 100755
index 0000000..e1be7ba
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/gluster.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/logobig.jpg b/ungleich_page/static/ungleich_page/img/logos/logobig.jpg
new file mode 100755
index 0000000..bc2e815
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/logobig.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/microlancer.jpg b/ungleich_page/static/ungleich_page/img/logos/microlancer.jpg
new file mode 100755
index 0000000..c4b9111
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/microlancer.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/mysql.jpg b/ungleich_page/static/ungleich_page/img/logos/mysql.jpg
new file mode 100755
index 0000000..5837d8f
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/mysql.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/openbsd.jpg b/ungleich_page/static/ungleich_page/img/logos/openbsd.jpg
new file mode 100755
index 0000000..89cff09
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/openbsd.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/opennebula.jpg b/ungleich_page/static/ungleich_page/img/logos/opennebula.jpg
new file mode 100755
index 0000000..b40b3b6
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/opennebula.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/postsql.jpg b/ungleich_page/static/ungleich_page/img/logos/postsql.jpg
new file mode 100755
index 0000000..791de7f
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/postsql.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/qemu.jpg b/ungleich_page/static/ungleich_page/img/logos/qemu.jpg
new file mode 100755
index 0000000..a93e6bc
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/qemu.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/themeforest.jpg b/ungleich_page/static/ungleich_page/img/logos/themeforest.jpg
new file mode 100755
index 0000000..7a43fd5
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/themeforest.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/logos/wordpress.jpg b/ungleich_page/static/ungleich_page/img/logos/wordpress.jpg
new file mode 100755
index 0000000..29be11d
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/logos/wordpress.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/map-image.png b/ungleich_page/static/ungleich_page/img/map-image.png
new file mode 100755
index 0000000..a34feda
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/map-image.png differ
diff --git a/ungleich_page/static/ungleich_page/img/partners/partner1.png b/ungleich_page/static/ungleich_page/img/partners/partner1.png
new file mode 100755
index 0000000..ff5a24a
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/partners/partner1.png differ
diff --git a/ungleich_page/static/ungleich_page/img/partners/partner2.png b/ungleich_page/static/ungleich_page/img/partners/partner2.png
new file mode 100755
index 0000000..667ae35
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/partners/partner2.png differ
diff --git a/ungleich_page/static/ungleich_page/img/partners/partner_bg.png b/ungleich_page/static/ungleich_page/img/partners/partner_bg.png
new file mode 100755
index 0000000..154cec1
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/partners/partner_bg.png differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/datacenterlight.png b/ungleich_page/static/ungleich_page/img/portfolio/datacenterlight.png
new file mode 100755
index 0000000..9b82ba5
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/datacenterlight.png differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/dreams-preview.png b/ungleich_page/static/ungleich_page/img/portfolio/dreams-preview.png
new file mode 100755
index 0000000..e2773b2
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/dreams-preview.png differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/dreams.png b/ungleich_page/static/ungleich_page/img/portfolio/dreams.png
new file mode 100755
index 0000000..1b925d8
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/dreams.png differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/escape-preview.png b/ungleich_page/static/ungleich_page/img/portfolio/escape-preview.png
new file mode 100755
index 0000000..a2343b4
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/escape-preview.png differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/escape.png b/ungleich_page/static/ungleich_page/img/portfolio/escape.png
new file mode 100755
index 0000000..d5fcee8
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/escape.png differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/glasfaser.png b/ungleich_page/static/ungleich_page/img/portfolio/glasfaser.png
new file mode 100755
index 0000000..9f43e4e
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/glasfaser.png differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/golden-preview.png b/ungleich_page/static/ungleich_page/img/portfolio/golden-preview.png
new file mode 100755
index 0000000..b8fe735
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/golden-preview.png differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/golden.png b/ungleich_page/static/ungleich_page/img/portfolio/golden.png
new file mode 100755
index 0000000..9b971ae
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/golden.png differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/roundicons-free.jpg b/ungleich_page/static/ungleich_page/img/portfolio/roundicons-free.jpg
new file mode 100755
index 0000000..52664cb
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/roundicons-free.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/roundicons-free.png b/ungleich_page/static/ungleich_page/img/portfolio/roundicons-free.png
new file mode 100755
index 0000000..997dd59
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/roundicons-free.png differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/roundicons.png b/ungleich_page/static/ungleich_page/img/portfolio/roundicons.png
new file mode 100755
index 0000000..6914493
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/roundicons.png differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/startup-framework copy.png b/ungleich_page/static/ungleich_page/img/portfolio/startup-framework copy.png
new file mode 100755
index 0000000..ee95bca
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/startup-framework copy.png differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/startup-framework-preview.jpg b/ungleich_page/static/ungleich_page/img/portfolio/startup-framework-preview.jpg
new file mode 100755
index 0000000..959b8ea
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/startup-framework-preview.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/startup-framework-preview.png b/ungleich_page/static/ungleich_page/img/portfolio/startup-framework-preview.png
new file mode 100755
index 0000000..22589fa
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/startup-framework-preview.png differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/startup-framework.png b/ungleich_page/static/ungleich_page/img/portfolio/startup-framework.png
new file mode 100755
index 0000000..c3e6611
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/startup-framework.png differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/treehouse-preview.png b/ungleich_page/static/ungleich_page/img/portfolio/treehouse-preview.png
new file mode 100755
index 0000000..0b001b3
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/treehouse-preview.png differ
diff --git a/ungleich_page/static/ungleich_page/img/portfolio/treehouse.png b/ungleich_page/static/ungleich_page/img/portfolio/treehouse.png
new file mode 100755
index 0000000..62e69d0
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/portfolio/treehouse.png differ
diff --git a/ungleich_page/static/ungleich_page/img/services/configuration.png b/ungleich_page/static/ungleich_page/img/services/configuration.png
new file mode 100755
index 0000000..d5448c5
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/services/configuration.png differ
diff --git a/ungleich_page/static/ungleich_page/img/services/hosting.png b/ungleich_page/static/ungleich_page/img/services/hosting.png
new file mode 100755
index 0000000..5b95e0d
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/services/hosting.png differ
diff --git a/ungleich_page/static/ungleich_page/img/services/linux.png b/ungleich_page/static/ungleich_page/img/services/linux.png
new file mode 100755
index 0000000..fc6910f
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/services/linux.png differ
diff --git a/ungleich_page/static/ungleich_page/img/team/1.jpg b/ungleich_page/static/ungleich_page/img/team/1.jpg
new file mode 100755
index 0000000..1c95d20
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/team/1.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/team/2.jpg b/ungleich_page/static/ungleich_page/img/team/2.jpg
new file mode 100755
index 0000000..c60f887
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/team/2.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/team/3.jpg b/ungleich_page/static/ungleich_page/img/team/3.jpg
new file mode 100755
index 0000000..d950f41
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/team/3.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/team/4.jpg b/ungleich_page/static/ungleich_page/img/team/4.jpg
new file mode 100755
index 0000000..3deee07
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/team/4.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/team/5.jpg b/ungleich_page/static/ungleich_page/img/team/5.jpg
new file mode 100755
index 0000000..6d9192e
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/team/5.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/team/6.jpg b/ungleich_page/static/ungleich_page/img/team/6.jpg
new file mode 100755
index 0000000..5b355bf
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/team/6.jpg differ
diff --git a/ungleich_page/static/ungleich_page/img/team/6.png b/ungleich_page/static/ungleich_page/img/team/6.png
new file mode 100755
index 0000000..31a067c
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/team/6.png differ
diff --git a/ungleich_page/static/ungleich_page/img/ungleich_logo.png b/ungleich_page/static/ungleich_page/img/ungleich_logo.png
new file mode 100755
index 0000000..9b104f4
Binary files /dev/null and b/ungleich_page/static/ungleich_page/img/ungleich_logo.png differ
diff --git a/ungleich_page/static/ungleich_page/img/ungleich_logo_round.svg b/ungleich_page/static/ungleich_page/img/ungleich_logo_round.svg
new file mode 100755
index 0000000..0df136f
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/img/ungleich_logo_round.svg
@@ -0,0 +1,234 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ungleich_page/static/ungleich_page/js/agency.js b/ungleich_page/static/ungleich_page/js/agency.js
new file mode 100755
index 0000000..30dffa0
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/js/agency.js
@@ -0,0 +1,26 @@
+/*!
+ * Start Bootstrap - Agnecy Bootstrap Theme (http://startbootstrap.com)
+ * Code licensed under the Apache License v2.0.
+ * For details, see http://www.apache.org/licenses/LICENSE-2.0.
+ */
+
+// jQuery for page scrolling feature - requires jQuery Easing plugin
+$(function() {
+ $('a.page-scroll').bind('click', function(event) {
+ var $anchor = $(this);
+ $('html, body').stop().animate({
+ scrollTop: $($anchor.attr('href')).offset().top
+ }, 1500, 'easeInOutExpo');
+ event.preventDefault();
+ });
+});
+
+// Highlight the top nav as scrolling occurs
+$('body').scrollspy({
+ target: '.navbar-fixed-top'
+})
+
+// Closes the Responsive Menu on Menu Item Click
+$('.navbar-collapse ul li a').click(function() {
+ $('.navbar-toggle:visible').click();
+});
\ No newline at end of file
diff --git a/ungleich_page/static/ungleich_page/js/bootstrap.js b/ungleich_page/static/ungleich_page/js/bootstrap.js
new file mode 100755
index 0000000..8dff365
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/js/bootstrap.js
@@ -0,0 +1,2276 @@
+/*!
+ * Bootstrap v3.3.0 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+if (typeof jQuery === 'undefined') {
+ throw new Error('Bootstrap\'s JavaScript requires jQuery')
+}
+
++function ($) {
+ var version = $.fn.jquery.split(' ')[0].split('.')
+ if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {
+ throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher')
+ }
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: transition.js v3.3.0
+ * http://getbootstrap.com/javascript/#transitions
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
+ // ============================================================
+
+ function transitionEnd() {
+ var el = document.createElement('bootstrap')
+
+ var transEndEventNames = {
+ WebkitTransition : 'webkitTransitionEnd',
+ MozTransition : 'transitionend',
+ OTransition : 'oTransitionEnd otransitionend',
+ transition : 'transitionend'
+ }
+
+ for (var name in transEndEventNames) {
+ if (el.style[name] !== undefined) {
+ return { end: transEndEventNames[name] }
+ }
+ }
+
+ return false // explicit for ie8 ( ._.)
+ }
+
+ // http://blog.alexmaccaw.com/css-transitions
+ $.fn.emulateTransitionEnd = function (duration) {
+ var called = false
+ var $el = this
+ $(this).one('bsTransitionEnd', function () { called = true })
+ var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
+ setTimeout(callback, duration)
+ return this
+ }
+
+ $(function () {
+ $.support.transition = transitionEnd()
+
+ if (!$.support.transition) return
+
+ $.event.special.bsTransitionEnd = {
+ bindType: $.support.transition.end,
+ delegateType: $.support.transition.end,
+ handle: function (e) {
+ if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
+ }
+ }
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: alert.js v3.3.0
+ * http://getbootstrap.com/javascript/#alerts
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // ALERT CLASS DEFINITION
+ // ======================
+
+ var dismiss = '[data-dismiss="alert"]'
+ var Alert = function (el) {
+ $(el).on('click', dismiss, this.close)
+ }
+
+ Alert.VERSION = '3.3.0'
+
+ Alert.TRANSITION_DURATION = 150
+
+ Alert.prototype.close = function (e) {
+ var $this = $(this)
+ var selector = $this.attr('data-target')
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
+ }
+
+ var $parent = $(selector)
+
+ if (e) e.preventDefault()
+
+ if (!$parent.length) {
+ $parent = $this.closest('.alert')
+ }
+
+ $parent.trigger(e = $.Event('close.bs.alert'))
+
+ if (e.isDefaultPrevented()) return
+
+ $parent.removeClass('in')
+
+ function removeElement() {
+ // detach from parent, fire event then clean up data
+ $parent.detach().trigger('closed.bs.alert').remove()
+ }
+
+ $.support.transition && $parent.hasClass('fade') ?
+ $parent
+ .one('bsTransitionEnd', removeElement)
+ .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
+ removeElement()
+ }
+
+
+ // ALERT PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.alert')
+
+ if (!data) $this.data('bs.alert', (data = new Alert(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ var old = $.fn.alert
+
+ $.fn.alert = Plugin
+ $.fn.alert.Constructor = Alert
+
+
+ // ALERT NO CONFLICT
+ // =================
+
+ $.fn.alert.noConflict = function () {
+ $.fn.alert = old
+ return this
+ }
+
+
+ // ALERT DATA-API
+ // ==============
+
+ $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: button.js v3.3.0
+ * http://getbootstrap.com/javascript/#buttons
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // BUTTON PUBLIC CLASS DEFINITION
+ // ==============================
+
+ var Button = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, Button.DEFAULTS, options)
+ this.isLoading = false
+ }
+
+ Button.VERSION = '3.3.0'
+
+ Button.DEFAULTS = {
+ loadingText: 'loading...'
+ }
+
+ Button.prototype.setState = function (state) {
+ var d = 'disabled'
+ var $el = this.$element
+ var val = $el.is('input') ? 'val' : 'html'
+ var data = $el.data()
+
+ state = state + 'Text'
+
+ if (data.resetText == null) $el.data('resetText', $el[val]())
+
+ // push to event loop to allow forms to submit
+ setTimeout($.proxy(function () {
+ $el[val](data[state] == null ? this.options[state] : data[state])
+
+ if (state == 'loadingText') {
+ this.isLoading = true
+ $el.addClass(d).attr(d, d)
+ } else if (this.isLoading) {
+ this.isLoading = false
+ $el.removeClass(d).removeAttr(d)
+ }
+ }, this), 0)
+ }
+
+ Button.prototype.toggle = function () {
+ var changed = true
+ var $parent = this.$element.closest('[data-toggle="buttons"]')
+
+ if ($parent.length) {
+ var $input = this.$element.find('input')
+ if ($input.prop('type') == 'radio') {
+ if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
+ else $parent.find('.active').removeClass('active')
+ }
+ if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
+ } else {
+ this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
+ }
+
+ if (changed) this.$element.toggleClass('active')
+ }
+
+
+ // BUTTON PLUGIN DEFINITION
+ // ========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.button')
+ var options = typeof option == 'object' && option
+
+ if (!data) $this.data('bs.button', (data = new Button(this, options)))
+
+ if (option == 'toggle') data.toggle()
+ else if (option) data.setState(option)
+ })
+ }
+
+ var old = $.fn.button
+
+ $.fn.button = Plugin
+ $.fn.button.Constructor = Button
+
+
+ // BUTTON NO CONFLICT
+ // ==================
+
+ $.fn.button.noConflict = function () {
+ $.fn.button = old
+ return this
+ }
+
+
+ // BUTTON DATA-API
+ // ===============
+
+ $(document)
+ .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
+ var $btn = $(e.target)
+ if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
+ Plugin.call($btn, 'toggle')
+ e.preventDefault()
+ })
+ .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
+ $(e.target).closest('.btn').toggleClass('focus', e.type == 'focus')
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: carousel.js v3.3.0
+ * http://getbootstrap.com/javascript/#carousel
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // CAROUSEL CLASS DEFINITION
+ // =========================
+
+ var Carousel = function (element, options) {
+ this.$element = $(element)
+ this.$indicators = this.$element.find('.carousel-indicators')
+ this.options = options
+ this.paused =
+ this.sliding =
+ this.interval =
+ this.$active =
+ this.$items = null
+
+ this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
+
+ this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
+ .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
+ .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
+ }
+
+ Carousel.VERSION = '3.3.0'
+
+ Carousel.TRANSITION_DURATION = 600
+
+ Carousel.DEFAULTS = {
+ interval: 5000,
+ pause: 'hover',
+ wrap: true,
+ keyboard: true
+ }
+
+ Carousel.prototype.keydown = function (e) {
+ switch (e.which) {
+ case 37: this.prev(); break
+ case 39: this.next(); break
+ default: return
+ }
+
+ e.preventDefault()
+ }
+
+ Carousel.prototype.cycle = function (e) {
+ e || (this.paused = false)
+
+ this.interval && clearInterval(this.interval)
+
+ this.options.interval
+ && !this.paused
+ && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
+
+ return this
+ }
+
+ Carousel.prototype.getItemIndex = function (item) {
+ this.$items = item.parent().children('.item')
+ return this.$items.index(item || this.$active)
+ }
+
+ Carousel.prototype.getItemForDirection = function (direction, active) {
+ var delta = direction == 'prev' ? -1 : 1
+ var activeIndex = this.getItemIndex(active)
+ var itemIndex = (activeIndex + delta) % this.$items.length
+ return this.$items.eq(itemIndex)
+ }
+
+ Carousel.prototype.to = function (pos) {
+ var that = this
+ var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
+
+ if (pos > (this.$items.length - 1) || pos < 0) return
+
+ if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
+ if (activeIndex == pos) return this.pause().cycle()
+
+ return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
+ }
+
+ Carousel.prototype.pause = function (e) {
+ e || (this.paused = true)
+
+ if (this.$element.find('.next, .prev').length && $.support.transition) {
+ this.$element.trigger($.support.transition.end)
+ this.cycle(true)
+ }
+
+ this.interval = clearInterval(this.interval)
+
+ return this
+ }
+
+ Carousel.prototype.next = function () {
+ if (this.sliding) return
+ return this.slide('next')
+ }
+
+ Carousel.prototype.prev = function () {
+ if (this.sliding) return
+ return this.slide('prev')
+ }
+
+ Carousel.prototype.slide = function (type, next) {
+ var $active = this.$element.find('.item.active')
+ var $next = next || this.getItemForDirection(type, $active)
+ var isCycling = this.interval
+ var direction = type == 'next' ? 'left' : 'right'
+ var fallback = type == 'next' ? 'first' : 'last'
+ var that = this
+
+ if (!$next.length) {
+ if (!this.options.wrap) return
+ $next = this.$element.find('.item')[fallback]()
+ }
+
+ if ($next.hasClass('active')) return (this.sliding = false)
+
+ var relatedTarget = $next[0]
+ var slideEvent = $.Event('slide.bs.carousel', {
+ relatedTarget: relatedTarget,
+ direction: direction
+ })
+ this.$element.trigger(slideEvent)
+ if (slideEvent.isDefaultPrevented()) return
+
+ this.sliding = true
+
+ isCycling && this.pause()
+
+ if (this.$indicators.length) {
+ this.$indicators.find('.active').removeClass('active')
+ var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
+ $nextIndicator && $nextIndicator.addClass('active')
+ }
+
+ var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
+ if ($.support.transition && this.$element.hasClass('slide')) {
+ $next.addClass(type)
+ $next[0].offsetWidth // force reflow
+ $active.addClass(direction)
+ $next.addClass(direction)
+ $active
+ .one('bsTransitionEnd', function () {
+ $next.removeClass([type, direction].join(' ')).addClass('active')
+ $active.removeClass(['active', direction].join(' '))
+ that.sliding = false
+ setTimeout(function () {
+ that.$element.trigger(slidEvent)
+ }, 0)
+ })
+ .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
+ } else {
+ $active.removeClass('active')
+ $next.addClass('active')
+ this.sliding = false
+ this.$element.trigger(slidEvent)
+ }
+
+ isCycling && this.cycle()
+
+ return this
+ }
+
+
+ // CAROUSEL PLUGIN DEFINITION
+ // ==========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.carousel')
+ var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
+ var action = typeof option == 'string' ? option : options.slide
+
+ if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
+ if (typeof option == 'number') data.to(option)
+ else if (action) data[action]()
+ else if (options.interval) data.pause().cycle()
+ })
+ }
+
+ var old = $.fn.carousel
+
+ $.fn.carousel = Plugin
+ $.fn.carousel.Constructor = Carousel
+
+
+ // CAROUSEL NO CONFLICT
+ // ====================
+
+ $.fn.carousel.noConflict = function () {
+ $.fn.carousel = old
+ return this
+ }
+
+
+ // CAROUSEL DATA-API
+ // =================
+
+ var clickHandler = function (e) {
+ var href
+ var $this = $(this)
+ var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
+ if (!$target.hasClass('carousel')) return
+ var options = $.extend({}, $target.data(), $this.data())
+ var slideIndex = $this.attr('data-slide-to')
+ if (slideIndex) options.interval = false
+
+ Plugin.call($target, options)
+
+ if (slideIndex) {
+ $target.data('bs.carousel').to(slideIndex)
+ }
+
+ e.preventDefault()
+ }
+
+ $(document)
+ .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
+ .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
+
+ $(window).on('load', function () {
+ $('[data-ride="carousel"]').each(function () {
+ var $carousel = $(this)
+ Plugin.call($carousel, $carousel.data())
+ })
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: collapse.js v3.3.0
+ * http://getbootstrap.com/javascript/#collapse
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // COLLAPSE PUBLIC CLASS DEFINITION
+ // ================================
+
+ var Collapse = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, Collapse.DEFAULTS, options)
+ this.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]')
+ this.transitioning = null
+
+ if (this.options.parent) {
+ this.$parent = this.getParent()
+ } else {
+ this.addAriaAndCollapsedClass(this.$element, this.$trigger)
+ }
+
+ if (this.options.toggle) this.toggle()
+ }
+
+ Collapse.VERSION = '3.3.0'
+
+ Collapse.TRANSITION_DURATION = 350
+
+ Collapse.DEFAULTS = {
+ toggle: true,
+ trigger: '[data-toggle="collapse"]'
+ }
+
+ Collapse.prototype.dimension = function () {
+ var hasWidth = this.$element.hasClass('width')
+ return hasWidth ? 'width' : 'height'
+ }
+
+ Collapse.prototype.show = function () {
+ if (this.transitioning || this.$element.hasClass('in')) return
+
+ var activesData
+ var actives = this.$parent && this.$parent.find('> .panel').children('.in, .collapsing')
+
+ if (actives && actives.length) {
+ activesData = actives.data('bs.collapse')
+ if (activesData && activesData.transitioning) return
+ }
+
+ var startEvent = $.Event('show.bs.collapse')
+ this.$element.trigger(startEvent)
+ if (startEvent.isDefaultPrevented()) return
+
+ if (actives && actives.length) {
+ Plugin.call(actives, 'hide')
+ activesData || actives.data('bs.collapse', null)
+ }
+
+ var dimension = this.dimension()
+
+ this.$element
+ .removeClass('collapse')
+ .addClass('collapsing')[dimension](0)
+ .attr('aria-expanded', true)
+
+ this.$trigger
+ .removeClass('collapsed')
+ .attr('aria-expanded', true)
+
+ this.transitioning = 1
+
+ var complete = function () {
+ this.$element
+ .removeClass('collapsing')
+ .addClass('collapse in')[dimension]('')
+ this.transitioning = 0
+ this.$element
+ .trigger('shown.bs.collapse')
+ }
+
+ if (!$.support.transition) return complete.call(this)
+
+ var scrollSize = $.camelCase(['scroll', dimension].join('-'))
+
+ this.$element
+ .one('bsTransitionEnd', $.proxy(complete, this))
+ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
+ }
+
+ Collapse.prototype.hide = function () {
+ if (this.transitioning || !this.$element.hasClass('in')) return
+
+ var startEvent = $.Event('hide.bs.collapse')
+ this.$element.trigger(startEvent)
+ if (startEvent.isDefaultPrevented()) return
+
+ var dimension = this.dimension()
+
+ this.$element[dimension](this.$element[dimension]())[0].offsetHeight
+
+ this.$element
+ .addClass('collapsing')
+ .removeClass('collapse in')
+ .attr('aria-expanded', false)
+
+ this.$trigger
+ .addClass('collapsed')
+ .attr('aria-expanded', false)
+
+ this.transitioning = 1
+
+ var complete = function () {
+ this.transitioning = 0
+ this.$element
+ .removeClass('collapsing')
+ .addClass('collapse')
+ .trigger('hidden.bs.collapse')
+ }
+
+ if (!$.support.transition) return complete.call(this)
+
+ this.$element
+ [dimension](0)
+ .one('bsTransitionEnd', $.proxy(complete, this))
+ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
+ }
+
+ Collapse.prototype.toggle = function () {
+ this[this.$element.hasClass('in') ? 'hide' : 'show']()
+ }
+
+ Collapse.prototype.getParent = function () {
+ return $(this.options.parent)
+ .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
+ .each($.proxy(function (i, element) {
+ var $element = $(element)
+ this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
+ }, this))
+ .end()
+ }
+
+ Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
+ var isOpen = $element.hasClass('in')
+
+ $element.attr('aria-expanded', isOpen)
+ $trigger
+ .toggleClass('collapsed', !isOpen)
+ .attr('aria-expanded', isOpen)
+ }
+
+ function getTargetFromTrigger($trigger) {
+ var href
+ var target = $trigger.attr('data-target')
+ || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
+
+ return $(target)
+ }
+
+
+ // COLLAPSE PLUGIN DEFINITION
+ // ==========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.collapse')
+ var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
+
+ if (!data && options.toggle && option == 'show') options.toggle = false
+ if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.collapse
+
+ $.fn.collapse = Plugin
+ $.fn.collapse.Constructor = Collapse
+
+
+ // COLLAPSE NO CONFLICT
+ // ====================
+
+ $.fn.collapse.noConflict = function () {
+ $.fn.collapse = old
+ return this
+ }
+
+
+ // COLLAPSE DATA-API
+ // =================
+
+ $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
+ var $this = $(this)
+
+ if (!$this.attr('data-target')) e.preventDefault()
+
+ var $target = getTargetFromTrigger($this)
+ var data = $target.data('bs.collapse')
+ var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this })
+
+ Plugin.call($target, option)
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: dropdown.js v3.3.0
+ * http://getbootstrap.com/javascript/#dropdowns
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // DROPDOWN CLASS DEFINITION
+ // =========================
+
+ var backdrop = '.dropdown-backdrop'
+ var toggle = '[data-toggle="dropdown"]'
+ var Dropdown = function (element) {
+ $(element).on('click.bs.dropdown', this.toggle)
+ }
+
+ Dropdown.VERSION = '3.3.0'
+
+ Dropdown.prototype.toggle = function (e) {
+ var $this = $(this)
+
+ if ($this.is('.disabled, :disabled')) return
+
+ var $parent = getParent($this)
+ var isActive = $parent.hasClass('open')
+
+ clearMenus()
+
+ if (!isActive) {
+ if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
+ // if mobile we use a backdrop because click events don't delegate
+ $('
').insertAfter($(this)).on('click', clearMenus)
+ }
+
+ var relatedTarget = { relatedTarget: this }
+ $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
+
+ if (e.isDefaultPrevented()) return
+
+ $this
+ .trigger('focus')
+ .attr('aria-expanded', 'true')
+
+ $parent
+ .toggleClass('open')
+ .trigger('shown.bs.dropdown', relatedTarget)
+ }
+
+ return false
+ }
+
+ Dropdown.prototype.keydown = function (e) {
+ if (!/(38|40|27|32)/.test(e.which)) return
+
+ var $this = $(this)
+
+ e.preventDefault()
+ e.stopPropagation()
+
+ if ($this.is('.disabled, :disabled')) return
+
+ var $parent = getParent($this)
+ var isActive = $parent.hasClass('open')
+
+ if ((!isActive && e.which != 27) || (isActive && e.which == 27)) {
+ if (e.which == 27) $parent.find(toggle).trigger('focus')
+ return $this.trigger('click')
+ }
+
+ var desc = ' li:not(.divider):visible a'
+ var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
+
+ if (!$items.length) return
+
+ var index = $items.index(e.target)
+
+ if (e.which == 38 && index > 0) index-- // up
+ if (e.which == 40 && index < $items.length - 1) index++ // down
+ if (!~index) index = 0
+
+ $items.eq(index).trigger('focus')
+ }
+
+ function clearMenus(e) {
+ if (e && e.which === 3) return
+ $(backdrop).remove()
+ $(toggle).each(function () {
+ var $this = $(this)
+ var $parent = getParent($this)
+ var relatedTarget = { relatedTarget: this }
+
+ if (!$parent.hasClass('open')) return
+
+ $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
+
+ if (e.isDefaultPrevented()) return
+
+ $this.attr('aria-expanded', 'false')
+ $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
+ })
+ }
+
+ function getParent($this) {
+ var selector = $this.attr('data-target')
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
+ }
+
+ var $parent = selector && $(selector)
+
+ return $parent && $parent.length ? $parent : $this.parent()
+ }
+
+
+ // DROPDOWN PLUGIN DEFINITION
+ // ==========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.dropdown')
+
+ if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ var old = $.fn.dropdown
+
+ $.fn.dropdown = Plugin
+ $.fn.dropdown.Constructor = Dropdown
+
+
+ // DROPDOWN NO CONFLICT
+ // ====================
+
+ $.fn.dropdown.noConflict = function () {
+ $.fn.dropdown = old
+ return this
+ }
+
+
+ // APPLY TO STANDARD DROPDOWN ELEMENTS
+ // ===================================
+
+ $(document)
+ .on('click.bs.dropdown.data-api', clearMenus)
+ .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
+ .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
+ .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
+ .on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown)
+ .on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: modal.js v3.3.0
+ * http://getbootstrap.com/javascript/#modals
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // MODAL CLASS DEFINITION
+ // ======================
+
+ var Modal = function (element, options) {
+ this.options = options
+ this.$body = $(document.body)
+ this.$element = $(element)
+ this.$backdrop =
+ this.isShown = null
+ this.scrollbarWidth = 0
+
+ if (this.options.remote) {
+ this.$element
+ .find('.modal-content')
+ .load(this.options.remote, $.proxy(function () {
+ this.$element.trigger('loaded.bs.modal')
+ }, this))
+ }
+ }
+
+ Modal.VERSION = '3.3.0'
+
+ Modal.TRANSITION_DURATION = 300
+ Modal.BACKDROP_TRANSITION_DURATION = 150
+
+ Modal.DEFAULTS = {
+ backdrop: true,
+ keyboard: true,
+ show: true
+ }
+
+ Modal.prototype.toggle = function (_relatedTarget) {
+ return this.isShown ? this.hide() : this.show(_relatedTarget)
+ }
+
+ Modal.prototype.show = function (_relatedTarget) {
+ var that = this
+ var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
+
+ this.$element.trigger(e)
+
+ if (this.isShown || e.isDefaultPrevented()) return
+
+ this.isShown = true
+
+ this.checkScrollbar()
+ this.$body.addClass('modal-open')
+
+ this.setScrollbar()
+ this.escape()
+
+ this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
+
+ this.backdrop(function () {
+ var transition = $.support.transition && that.$element.hasClass('fade')
+
+ if (!that.$element.parent().length) {
+ that.$element.appendTo(that.$body) // don't move modals dom position
+ }
+
+ that.$element
+ .show()
+ .scrollTop(0)
+
+ if (transition) {
+ that.$element[0].offsetWidth // force reflow
+ }
+
+ that.$element
+ .addClass('in')
+ .attr('aria-hidden', false)
+
+ that.enforceFocus()
+
+ var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
+
+ transition ?
+ that.$element.find('.modal-dialog') // wait for modal to slide in
+ .one('bsTransitionEnd', function () {
+ that.$element.trigger('focus').trigger(e)
+ })
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
+ that.$element.trigger('focus').trigger(e)
+ })
+ }
+
+ Modal.prototype.hide = function (e) {
+ if (e) e.preventDefault()
+
+ e = $.Event('hide.bs.modal')
+
+ this.$element.trigger(e)
+
+ if (!this.isShown || e.isDefaultPrevented()) return
+
+ this.isShown = false
+
+ this.escape()
+
+ $(document).off('focusin.bs.modal')
+
+ this.$element
+ .removeClass('in')
+ .attr('aria-hidden', true)
+ .off('click.dismiss.bs.modal')
+
+ $.support.transition && this.$element.hasClass('fade') ?
+ this.$element
+ .one('bsTransitionEnd', $.proxy(this.hideModal, this))
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
+ this.hideModal()
+ }
+
+ Modal.prototype.enforceFocus = function () {
+ $(document)
+ .off('focusin.bs.modal') // guard against infinite focus loop
+ .on('focusin.bs.modal', $.proxy(function (e) {
+ if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
+ this.$element.trigger('focus')
+ }
+ }, this))
+ }
+
+ Modal.prototype.escape = function () {
+ if (this.isShown && this.options.keyboard) {
+ this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
+ e.which == 27 && this.hide()
+ }, this))
+ } else if (!this.isShown) {
+ this.$element.off('keydown.dismiss.bs.modal')
+ }
+ }
+
+ Modal.prototype.hideModal = function () {
+ var that = this
+ this.$element.hide()
+ this.backdrop(function () {
+ that.$body.removeClass('modal-open')
+ that.resetScrollbar()
+ that.$element.trigger('hidden.bs.modal')
+ })
+ }
+
+ Modal.prototype.removeBackdrop = function () {
+ this.$backdrop && this.$backdrop.remove()
+ this.$backdrop = null
+ }
+
+ Modal.prototype.backdrop = function (callback) {
+ var that = this
+ var animate = this.$element.hasClass('fade') ? 'fade' : ''
+
+ if (this.isShown && this.options.backdrop) {
+ var doAnimate = $.support.transition && animate
+
+ this.$backdrop = $('
')
+ .prependTo(this.$element)
+ .on('click.dismiss.bs.modal', $.proxy(function (e) {
+ if (e.target !== e.currentTarget) return
+ this.options.backdrop == 'static'
+ ? this.$element[0].focus.call(this.$element[0])
+ : this.hide.call(this)
+ }, this))
+
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
+
+ this.$backdrop.addClass('in')
+
+ if (!callback) return
+
+ doAnimate ?
+ this.$backdrop
+ .one('bsTransitionEnd', callback)
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
+ callback()
+
+ } else if (!this.isShown && this.$backdrop) {
+ this.$backdrop.removeClass('in')
+
+ var callbackRemove = function () {
+ that.removeBackdrop()
+ callback && callback()
+ }
+ $.support.transition && this.$element.hasClass('fade') ?
+ this.$backdrop
+ .one('bsTransitionEnd', callbackRemove)
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
+ callbackRemove()
+
+ } else if (callback) {
+ callback()
+ }
+ }
+
+ Modal.prototype.checkScrollbar = function () {
+ this.scrollbarWidth = this.measureScrollbar()
+ }
+
+ Modal.prototype.setScrollbar = function () {
+ var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
+ if (this.scrollbarWidth) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
+ }
+
+ Modal.prototype.resetScrollbar = function () {
+ this.$body.css('padding-right', '')
+ }
+
+ Modal.prototype.measureScrollbar = function () { // thx walsh
+ if (document.body.clientWidth >= window.innerWidth) return 0
+ var scrollDiv = document.createElement('div')
+ scrollDiv.className = 'modal-scrollbar-measure'
+ this.$body.append(scrollDiv)
+ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
+ this.$body[0].removeChild(scrollDiv)
+ return scrollbarWidth
+ }
+
+
+ // MODAL PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option, _relatedTarget) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.modal')
+ var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
+
+ if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
+ if (typeof option == 'string') data[option](_relatedTarget)
+ else if (options.show) data.show(_relatedTarget)
+ })
+ }
+
+ var old = $.fn.modal
+
+ $.fn.modal = Plugin
+ $.fn.modal.Constructor = Modal
+
+
+ // MODAL NO CONFLICT
+ // =================
+
+ $.fn.modal.noConflict = function () {
+ $.fn.modal = old
+ return this
+ }
+
+
+ // MODAL DATA-API
+ // ==============
+
+ $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
+ var $this = $(this)
+ var href = $this.attr('href')
+ var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
+ var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
+
+ if ($this.is('a')) e.preventDefault()
+
+ $target.one('show.bs.modal', function (showEvent) {
+ if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
+ $target.one('hidden.bs.modal', function () {
+ $this.is(':visible') && $this.trigger('focus')
+ })
+ })
+ Plugin.call($target, option, this)
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: tooltip.js v3.3.0
+ * http://getbootstrap.com/javascript/#tooltip
+ * Inspired by the original jQuery.tipsy by Jason Frame
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // TOOLTIP PUBLIC CLASS DEFINITION
+ // ===============================
+
+ var Tooltip = function (element, options) {
+ this.type =
+ this.options =
+ this.enabled =
+ this.timeout =
+ this.hoverState =
+ this.$element = null
+
+ this.init('tooltip', element, options)
+ }
+
+ Tooltip.VERSION = '3.3.0'
+
+ Tooltip.TRANSITION_DURATION = 150
+
+ Tooltip.DEFAULTS = {
+ animation: true,
+ placement: 'top',
+ selector: false,
+ template: '',
+ trigger: 'hover focus',
+ title: '',
+ delay: 0,
+ html: false,
+ container: false,
+ viewport: {
+ selector: 'body',
+ padding: 0
+ }
+ }
+
+ Tooltip.prototype.init = function (type, element, options) {
+ this.enabled = true
+ this.type = type
+ this.$element = $(element)
+ this.options = this.getOptions(options)
+ this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
+
+ var triggers = this.options.trigger.split(' ')
+
+ for (var i = triggers.length; i--;) {
+ var trigger = triggers[i]
+
+ if (trigger == 'click') {
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
+ } else if (trigger != 'manual') {
+ var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
+ var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
+
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
+ }
+ }
+
+ this.options.selector ?
+ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
+ this.fixTitle()
+ }
+
+ Tooltip.prototype.getDefaults = function () {
+ return Tooltip.DEFAULTS
+ }
+
+ Tooltip.prototype.getOptions = function (options) {
+ options = $.extend({}, this.getDefaults(), this.$element.data(), options)
+
+ if (options.delay && typeof options.delay == 'number') {
+ options.delay = {
+ show: options.delay,
+ hide: options.delay
+ }
+ }
+
+ return options
+ }
+
+ Tooltip.prototype.getDelegateOptions = function () {
+ var options = {}
+ var defaults = this.getDefaults()
+
+ this._options && $.each(this._options, function (key, value) {
+ if (defaults[key] != value) options[key] = value
+ })
+
+ return options
+ }
+
+ Tooltip.prototype.enter = function (obj) {
+ var self = obj instanceof this.constructor ?
+ obj : $(obj.currentTarget).data('bs.' + this.type)
+
+ if (self && self.$tip && self.$tip.is(':visible')) {
+ self.hoverState = 'in'
+ return
+ }
+
+ if (!self) {
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
+ $(obj.currentTarget).data('bs.' + this.type, self)
+ }
+
+ clearTimeout(self.timeout)
+
+ self.hoverState = 'in'
+
+ if (!self.options.delay || !self.options.delay.show) return self.show()
+
+ self.timeout = setTimeout(function () {
+ if (self.hoverState == 'in') self.show()
+ }, self.options.delay.show)
+ }
+
+ Tooltip.prototype.leave = function (obj) {
+ var self = obj instanceof this.constructor ?
+ obj : $(obj.currentTarget).data('bs.' + this.type)
+
+ if (!self) {
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
+ $(obj.currentTarget).data('bs.' + this.type, self)
+ }
+
+ clearTimeout(self.timeout)
+
+ self.hoverState = 'out'
+
+ if (!self.options.delay || !self.options.delay.hide) return self.hide()
+
+ self.timeout = setTimeout(function () {
+ if (self.hoverState == 'out') self.hide()
+ }, self.options.delay.hide)
+ }
+
+ Tooltip.prototype.show = function () {
+ var e = $.Event('show.bs.' + this.type)
+
+ if (this.hasContent() && this.enabled) {
+ this.$element.trigger(e)
+
+ var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
+ if (e.isDefaultPrevented() || !inDom) return
+ var that = this
+
+ var $tip = this.tip()
+
+ var tipId = this.getUID(this.type)
+
+ this.setContent()
+ $tip.attr('id', tipId)
+ this.$element.attr('aria-describedby', tipId)
+
+ if (this.options.animation) $tip.addClass('fade')
+
+ var placement = typeof this.options.placement == 'function' ?
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
+ this.options.placement
+
+ var autoToken = /\s?auto?\s?/i
+ var autoPlace = autoToken.test(placement)
+ if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
+
+ $tip
+ .detach()
+ .css({ top: 0, left: 0, display: 'block' })
+ .addClass(placement)
+ .data('bs.' + this.type, this)
+
+ this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
+
+ var pos = this.getPosition()
+ var actualWidth = $tip[0].offsetWidth
+ var actualHeight = $tip[0].offsetHeight
+
+ if (autoPlace) {
+ var orgPlacement = placement
+ var $container = this.options.container ? $(this.options.container) : this.$element.parent()
+ var containerDim = this.getPosition($container)
+
+ placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' :
+ placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' :
+ placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' :
+ placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' :
+ placement
+
+ $tip
+ .removeClass(orgPlacement)
+ .addClass(placement)
+ }
+
+ var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
+
+ this.applyPlacement(calculatedOffset, placement)
+
+ var complete = function () {
+ var prevHoverState = that.hoverState
+ that.$element.trigger('shown.bs.' + that.type)
+ that.hoverState = null
+
+ if (prevHoverState == 'out') that.leave(that)
+ }
+
+ $.support.transition && this.$tip.hasClass('fade') ?
+ $tip
+ .one('bsTransitionEnd', complete)
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+ complete()
+ }
+ }
+
+ Tooltip.prototype.applyPlacement = function (offset, placement) {
+ var $tip = this.tip()
+ var width = $tip[0].offsetWidth
+ var height = $tip[0].offsetHeight
+
+ // manually read margins because getBoundingClientRect includes difference
+ var marginTop = parseInt($tip.css('margin-top'), 10)
+ var marginLeft = parseInt($tip.css('margin-left'), 10)
+
+ // we must check for NaN for ie 8/9
+ if (isNaN(marginTop)) marginTop = 0
+ if (isNaN(marginLeft)) marginLeft = 0
+
+ offset.top = offset.top + marginTop
+ offset.left = offset.left + marginLeft
+
+ // $.fn.offset doesn't round pixel values
+ // so we use setOffset directly with our own function B-0
+ $.offset.setOffset($tip[0], $.extend({
+ using: function (props) {
+ $tip.css({
+ top: Math.round(props.top),
+ left: Math.round(props.left)
+ })
+ }
+ }, offset), 0)
+
+ $tip.addClass('in')
+
+ // check to see if placing tip in new offset caused the tip to resize itself
+ var actualWidth = $tip[0].offsetWidth
+ var actualHeight = $tip[0].offsetHeight
+
+ if (placement == 'top' && actualHeight != height) {
+ offset.top = offset.top + height - actualHeight
+ }
+
+ var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
+
+ if (delta.left) offset.left += delta.left
+ else offset.top += delta.top
+
+ var isVertical = /top|bottom/.test(placement)
+ var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
+ var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
+
+ $tip.offset(offset)
+ this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
+ }
+
+ Tooltip.prototype.replaceArrow = function (delta, dimension, isHorizontal) {
+ this.arrow()
+ .css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
+ .css(isHorizontal ? 'top' : 'left', '')
+ }
+
+ Tooltip.prototype.setContent = function () {
+ var $tip = this.tip()
+ var title = this.getTitle()
+
+ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
+ $tip.removeClass('fade in top bottom left right')
+ }
+
+ Tooltip.prototype.hide = function (callback) {
+ var that = this
+ var $tip = this.tip()
+ var e = $.Event('hide.bs.' + this.type)
+
+ function complete() {
+ if (that.hoverState != 'in') $tip.detach()
+ that.$element
+ .removeAttr('aria-describedby')
+ .trigger('hidden.bs.' + that.type)
+ callback && callback()
+ }
+
+ this.$element.trigger(e)
+
+ if (e.isDefaultPrevented()) return
+
+ $tip.removeClass('in')
+
+ $.support.transition && this.$tip.hasClass('fade') ?
+ $tip
+ .one('bsTransitionEnd', complete)
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+ complete()
+
+ this.hoverState = null
+
+ return this
+ }
+
+ Tooltip.prototype.fixTitle = function () {
+ var $e = this.$element
+ if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
+ $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
+ }
+ }
+
+ Tooltip.prototype.hasContent = function () {
+ return this.getTitle()
+ }
+
+ Tooltip.prototype.getPosition = function ($element) {
+ $element = $element || this.$element
+
+ var el = $element[0]
+ var isBody = el.tagName == 'BODY'
+
+ var elRect = el.getBoundingClientRect()
+ if (elRect.width == null) {
+ // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
+ elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
+ }
+ var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
+ var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
+ var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
+
+ return $.extend({}, elRect, scroll, outerDims, elOffset)
+ }
+
+ Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
+ return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
+ placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
+ placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
+ /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
+
+ }
+
+ Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
+ var delta = { top: 0, left: 0 }
+ if (!this.$viewport) return delta
+
+ var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
+ var viewportDimensions = this.getPosition(this.$viewport)
+
+ if (/right|left/.test(placement)) {
+ var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
+ var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
+ if (topEdgeOffset < viewportDimensions.top) { // top overflow
+ delta.top = viewportDimensions.top - topEdgeOffset
+ } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
+ delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
+ }
+ } else {
+ var leftEdgeOffset = pos.left - viewportPadding
+ var rightEdgeOffset = pos.left + viewportPadding + actualWidth
+ if (leftEdgeOffset < viewportDimensions.left) { // left overflow
+ delta.left = viewportDimensions.left - leftEdgeOffset
+ } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
+ delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
+ }
+ }
+
+ return delta
+ }
+
+ Tooltip.prototype.getTitle = function () {
+ var title
+ var $e = this.$element
+ var o = this.options
+
+ title = $e.attr('data-original-title')
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
+
+ return title
+ }
+
+ Tooltip.prototype.getUID = function (prefix) {
+ do prefix += ~~(Math.random() * 1000000)
+ while (document.getElementById(prefix))
+ return prefix
+ }
+
+ Tooltip.prototype.tip = function () {
+ return (this.$tip = this.$tip || $(this.options.template))
+ }
+
+ Tooltip.prototype.arrow = function () {
+ return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
+ }
+
+ Tooltip.prototype.enable = function () {
+ this.enabled = true
+ }
+
+ Tooltip.prototype.disable = function () {
+ this.enabled = false
+ }
+
+ Tooltip.prototype.toggleEnabled = function () {
+ this.enabled = !this.enabled
+ }
+
+ Tooltip.prototype.toggle = function (e) {
+ var self = this
+ if (e) {
+ self = $(e.currentTarget).data('bs.' + this.type)
+ if (!self) {
+ self = new this.constructor(e.currentTarget, this.getDelegateOptions())
+ $(e.currentTarget).data('bs.' + this.type, self)
+ }
+ }
+
+ self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
+ }
+
+ Tooltip.prototype.destroy = function () {
+ var that = this
+ clearTimeout(this.timeout)
+ this.hide(function () {
+ that.$element.off('.' + that.type).removeData('bs.' + that.type)
+ })
+ }
+
+
+ // TOOLTIP PLUGIN DEFINITION
+ // =========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.tooltip')
+ var options = typeof option == 'object' && option
+ var selector = options && options.selector
+
+ if (!data && option == 'destroy') return
+ if (selector) {
+ if (!data) $this.data('bs.tooltip', (data = {}))
+ if (!data[selector]) data[selector] = new Tooltip(this, options)
+ } else {
+ if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
+ }
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.tooltip
+
+ $.fn.tooltip = Plugin
+ $.fn.tooltip.Constructor = Tooltip
+
+
+ // TOOLTIP NO CONFLICT
+ // ===================
+
+ $.fn.tooltip.noConflict = function () {
+ $.fn.tooltip = old
+ return this
+ }
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: popover.js v3.3.0
+ * http://getbootstrap.com/javascript/#popovers
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // POPOVER PUBLIC CLASS DEFINITION
+ // ===============================
+
+ var Popover = function (element, options) {
+ this.init('popover', element, options)
+ }
+
+ if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
+
+ Popover.VERSION = '3.3.0'
+
+ Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
+ placement: 'right',
+ trigger: 'click',
+ content: '',
+ template: ''
+ })
+
+
+ // NOTE: POPOVER EXTENDS tooltip.js
+ // ================================
+
+ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
+
+ Popover.prototype.constructor = Popover
+
+ Popover.prototype.getDefaults = function () {
+ return Popover.DEFAULTS
+ }
+
+ Popover.prototype.setContent = function () {
+ var $tip = this.tip()
+ var title = this.getTitle()
+ var content = this.getContent()
+
+ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
+ $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
+ this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
+ ](content)
+
+ $tip.removeClass('fade top bottom left right in')
+
+ // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
+ // this manually by checking the contents.
+ if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
+ }
+
+ Popover.prototype.hasContent = function () {
+ return this.getTitle() || this.getContent()
+ }
+
+ Popover.prototype.getContent = function () {
+ var $e = this.$element
+ var o = this.options
+
+ return $e.attr('data-content')
+ || (typeof o.content == 'function' ?
+ o.content.call($e[0]) :
+ o.content)
+ }
+
+ Popover.prototype.arrow = function () {
+ return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
+ }
+
+ Popover.prototype.tip = function () {
+ if (!this.$tip) this.$tip = $(this.options.template)
+ return this.$tip
+ }
+
+
+ // POPOVER PLUGIN DEFINITION
+ // =========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.popover')
+ var options = typeof option == 'object' && option
+ var selector = options && options.selector
+
+ if (!data && option == 'destroy') return
+ if (selector) {
+ if (!data) $this.data('bs.popover', (data = {}))
+ if (!data[selector]) data[selector] = new Popover(this, options)
+ } else {
+ if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
+ }
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.popover
+
+ $.fn.popover = Plugin
+ $.fn.popover.Constructor = Popover
+
+
+ // POPOVER NO CONFLICT
+ // ===================
+
+ $.fn.popover.noConflict = function () {
+ $.fn.popover = old
+ return this
+ }
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: scrollspy.js v3.3.0
+ * http://getbootstrap.com/javascript/#scrollspy
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // SCROLLSPY CLASS DEFINITION
+ // ==========================
+
+ function ScrollSpy(element, options) {
+ var process = $.proxy(this.process, this)
+
+ this.$body = $('body')
+ this.$scrollElement = $(element).is('body') ? $(window) : $(element)
+ this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
+ this.selector = (this.options.target || '') + ' .nav li > a'
+ this.offsets = []
+ this.targets = []
+ this.activeTarget = null
+ this.scrollHeight = 0
+
+ this.$scrollElement.on('scroll.bs.scrollspy', process)
+ this.refresh()
+ this.process()
+ }
+
+ ScrollSpy.VERSION = '3.3.0'
+
+ ScrollSpy.DEFAULTS = {
+ offset: 10
+ }
+
+ ScrollSpy.prototype.getScrollHeight = function () {
+ return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
+ }
+
+ ScrollSpy.prototype.refresh = function () {
+ var offsetMethod = 'offset'
+ var offsetBase = 0
+
+ if (!$.isWindow(this.$scrollElement[0])) {
+ offsetMethod = 'position'
+ offsetBase = this.$scrollElement.scrollTop()
+ }
+
+ this.offsets = []
+ this.targets = []
+ this.scrollHeight = this.getScrollHeight()
+
+ var self = this
+
+ this.$body
+ .find(this.selector)
+ .map(function () {
+ var $el = $(this)
+ var href = $el.data('target') || $el.attr('href')
+ var $href = /^#./.test(href) && $(href)
+
+ return ($href
+ && $href.length
+ && $href.is(':visible')
+ && [[$href[offsetMethod]().top + offsetBase, href]]) || null
+ })
+ .sort(function (a, b) { return a[0] - b[0] })
+ .each(function () {
+ self.offsets.push(this[0])
+ self.targets.push(this[1])
+ })
+ }
+
+ ScrollSpy.prototype.process = function () {
+ var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
+ var scrollHeight = this.getScrollHeight()
+ var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
+ var offsets = this.offsets
+ var targets = this.targets
+ var activeTarget = this.activeTarget
+ var i
+
+ if (this.scrollHeight != scrollHeight) {
+ this.refresh()
+ }
+
+ if (scrollTop >= maxScroll) {
+ return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
+ }
+
+ if (activeTarget && scrollTop < offsets[0]) {
+ this.activeTarget = null
+ return this.clear()
+ }
+
+ for (i = offsets.length; i--;) {
+ activeTarget != targets[i]
+ && scrollTop >= offsets[i]
+ && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
+ && this.activate(targets[i])
+ }
+ }
+
+ ScrollSpy.prototype.activate = function (target) {
+ this.activeTarget = target
+
+ this.clear()
+
+ var selector = this.selector +
+ '[data-target="' + target + '"],' +
+ this.selector + '[href="' + target + '"]'
+
+ var active = $(selector)
+ .parents('li')
+ .addClass('active')
+
+ if (active.parent('.dropdown-menu').length) {
+ active = active
+ .closest('li.dropdown')
+ .addClass('active')
+ }
+
+ active.trigger('activate.bs.scrollspy')
+ }
+
+ ScrollSpy.prototype.clear = function () {
+ $(this.selector)
+ .parentsUntil(this.options.target, '.active')
+ .removeClass('active')
+ }
+
+
+ // SCROLLSPY PLUGIN DEFINITION
+ // ===========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.scrollspy')
+ var options = typeof option == 'object' && option
+
+ if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.scrollspy
+
+ $.fn.scrollspy = Plugin
+ $.fn.scrollspy.Constructor = ScrollSpy
+
+
+ // SCROLLSPY NO CONFLICT
+ // =====================
+
+ $.fn.scrollspy.noConflict = function () {
+ $.fn.scrollspy = old
+ return this
+ }
+
+
+ // SCROLLSPY DATA-API
+ // ==================
+
+ $(window).on('load.bs.scrollspy.data-api', function () {
+ $('[data-spy="scroll"]').each(function () {
+ var $spy = $(this)
+ Plugin.call($spy, $spy.data())
+ })
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: tab.js v3.3.0
+ * http://getbootstrap.com/javascript/#tabs
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // TAB CLASS DEFINITION
+ // ====================
+
+ var Tab = function (element) {
+ this.element = $(element)
+ }
+
+ Tab.VERSION = '3.3.0'
+
+ Tab.TRANSITION_DURATION = 150
+
+ Tab.prototype.show = function () {
+ var $this = this.element
+ var $ul = $this.closest('ul:not(.dropdown-menu)')
+ var selector = $this.data('target')
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
+ }
+
+ if ($this.parent('li').hasClass('active')) return
+
+ var $previous = $ul.find('.active:last a')
+ var hideEvent = $.Event('hide.bs.tab', {
+ relatedTarget: $this[0]
+ })
+ var showEvent = $.Event('show.bs.tab', {
+ relatedTarget: $previous[0]
+ })
+
+ $previous.trigger(hideEvent)
+ $this.trigger(showEvent)
+
+ if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
+
+ var $target = $(selector)
+
+ this.activate($this.closest('li'), $ul)
+ this.activate($target, $target.parent(), function () {
+ $previous.trigger({
+ type: 'hidden.bs.tab',
+ relatedTarget: $this[0]
+ })
+ $this.trigger({
+ type: 'shown.bs.tab',
+ relatedTarget: $previous[0]
+ })
+ })
+ }
+
+ Tab.prototype.activate = function (element, container, callback) {
+ var $active = container.find('> .active')
+ var transition = callback
+ && $.support.transition
+ && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length)
+
+ function next() {
+ $active
+ .removeClass('active')
+ .find('> .dropdown-menu > .active')
+ .removeClass('active')
+ .end()
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', false)
+
+ element
+ .addClass('active')
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', true)
+
+ if (transition) {
+ element[0].offsetWidth // reflow for transition
+ element.addClass('in')
+ } else {
+ element.removeClass('fade')
+ }
+
+ if (element.parent('.dropdown-menu')) {
+ element
+ .closest('li.dropdown')
+ .addClass('active')
+ .end()
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', true)
+ }
+
+ callback && callback()
+ }
+
+ $active.length && transition ?
+ $active
+ .one('bsTransitionEnd', next)
+ .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
+ next()
+
+ $active.removeClass('in')
+ }
+
+
+ // TAB PLUGIN DEFINITION
+ // =====================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.tab')
+
+ if (!data) $this.data('bs.tab', (data = new Tab(this)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.tab
+
+ $.fn.tab = Plugin
+ $.fn.tab.Constructor = Tab
+
+
+ // TAB NO CONFLICT
+ // ===============
+
+ $.fn.tab.noConflict = function () {
+ $.fn.tab = old
+ return this
+ }
+
+
+ // TAB DATA-API
+ // ============
+
+ var clickHandler = function (e) {
+ e.preventDefault()
+ Plugin.call($(this), 'show')
+ }
+
+ $(document)
+ .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
+ .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: affix.js v3.3.0
+ * http://getbootstrap.com/javascript/#affix
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // AFFIX CLASS DEFINITION
+ // ======================
+
+ var Affix = function (element, options) {
+ this.options = $.extend({}, Affix.DEFAULTS, options)
+
+ this.$target = $(this.options.target)
+ .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
+ .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
+
+ this.$element = $(element)
+ this.affixed =
+ this.unpin =
+ this.pinnedOffset = null
+
+ this.checkPosition()
+ }
+
+ Affix.VERSION = '3.3.0'
+
+ Affix.RESET = 'affix affix-top affix-bottom'
+
+ Affix.DEFAULTS = {
+ offset: 0,
+ target: window
+ }
+
+ Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
+ var scrollTop = this.$target.scrollTop()
+ var position = this.$element.offset()
+ var targetHeight = this.$target.height()
+
+ if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
+
+ if (this.affixed == 'bottom') {
+ if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
+ return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
+ }
+
+ var initializing = this.affixed == null
+ var colliderTop = initializing ? scrollTop : position.top
+ var colliderHeight = initializing ? targetHeight : height
+
+ if (offsetTop != null && colliderTop <= offsetTop) return 'top'
+ if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
+
+ return false
+ }
+
+ Affix.prototype.getPinnedOffset = function () {
+ if (this.pinnedOffset) return this.pinnedOffset
+ this.$element.removeClass(Affix.RESET).addClass('affix')
+ var scrollTop = this.$target.scrollTop()
+ var position = this.$element.offset()
+ return (this.pinnedOffset = position.top - scrollTop)
+ }
+
+ Affix.prototype.checkPositionWithEventLoop = function () {
+ setTimeout($.proxy(this.checkPosition, this), 1)
+ }
+
+ Affix.prototype.checkPosition = function () {
+ if (!this.$element.is(':visible')) return
+
+ var height = this.$element.height()
+ var offset = this.options.offset
+ var offsetTop = offset.top
+ var offsetBottom = offset.bottom
+ var scrollHeight = $('body').height()
+
+ if (typeof offset != 'object') offsetBottom = offsetTop = offset
+ if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
+ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
+
+ var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
+
+ if (this.affixed != affix) {
+ if (this.unpin != null) this.$element.css('top', '')
+
+ var affixType = 'affix' + (affix ? '-' + affix : '')
+ var e = $.Event(affixType + '.bs.affix')
+
+ this.$element.trigger(e)
+
+ if (e.isDefaultPrevented()) return
+
+ this.affixed = affix
+ this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
+
+ this.$element
+ .removeClass(Affix.RESET)
+ .addClass(affixType)
+ .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
+ }
+
+ if (affix == 'bottom') {
+ this.$element.offset({
+ top: scrollHeight - height - offsetBottom
+ })
+ }
+ }
+
+
+ // AFFIX PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.affix')
+ var options = typeof option == 'object' && option
+
+ if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.affix
+
+ $.fn.affix = Plugin
+ $.fn.affix.Constructor = Affix
+
+
+ // AFFIX NO CONFLICT
+ // =================
+
+ $.fn.affix.noConflict = function () {
+ $.fn.affix = old
+ return this
+ }
+
+
+ // AFFIX DATA-API
+ // ==============
+
+ $(window).on('load', function () {
+ $('[data-spy="affix"]').each(function () {
+ var $spy = $(this)
+ var data = $spy.data()
+
+ data.offset = data.offset || {}
+
+ if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
+ if (data.offsetTop != null) data.offset.top = data.offsetTop
+
+ Plugin.call($spy, data)
+ })
+ })
+
+}(jQuery);
diff --git a/ungleich_page/static/ungleich_page/js/bootstrap.min.js b/ungleich_page/static/ungleich_page/js/bootstrap.min.js
new file mode 100755
index 0000000..63866bc
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/js/bootstrap.min.js
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v3.3.0 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.0",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.0",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus","focus"==b.type)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.0",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c="prev"==a?-1:1,d=this.getItemIndex(b),e=(d+c)%this.$items.length;return this.$items.eq(e)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i="next"==b?"first":"last",j=this;if(!f.length){if(!this.options.wrap)return;f=this.$element.find(".item")[i]()}if(f.hasClass("active"))return this.sliding=!1;var k=f[0],l=a.Event("slide.bs.carousel",{relatedTarget:k,direction:h});if(this.$element.trigger(l),!l.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var m=a(this.$indicators.children()[this.getItemIndex(f)]);m&&m.addClass("active")}var n=a.Event("slid.bs.carousel",{relatedTarget:k,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),j.sliding=!1,setTimeout(function(){j.$element.trigger(n)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(n)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a(this.options.trigger).filter('[href="#'+b.id+'"], [data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.0",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0,trigger:'[data-toggle="collapse"]'},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.find("> .panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":a.extend({},e.data(),{trigger:this});c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.0",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('
').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27|32)/.test(b.which)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g&&27!=b.which||g&&27==b.which)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.divider):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(b.target);38==b.which&&j>0&&j--,40==b.which&&j ').prependTo(this.$element).on("click.dismiss.bs.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.checkScrollbar=function(){this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.scrollbarWidth&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right","")},c.prototype.measureScrollbar=function(){if(document.body.clientWidth>=window.innerWidth)return 0;var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b,g=f&&f.selector;(e||"destroy"!=b)&&(g?(e||d.data("bs.tooltip",e={}),e[g]||(e[g]=new c(this,f))):e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};c.VERSION="3.3.0",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c&&c.$tip&&c.$tip.is(":visible")?void(c.hoverState="in"):(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.options.container?a(this.options.container):this.$element.parent(),p=this.getPosition(o);h="bottom"==h&&k.bottom+m>p.bottom?"top":"top"==h&&k.top-mp.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type)})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b,g=f&&f.selector;(e||"destroy"!=b)&&(g?(e||d.data("bs.popover",e={}),e[g]||(e[g]=new c(this,f))):e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.0",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},c.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){var e=a.proxy(this.process,this);this.$body=a("body"),this.$scrollElement=a(a(c).is("body")?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",e),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.0",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b="offset",c=0;a.isWindow(this.$scrollElement[0])||(b="position",c=this.$scrollElement.scrollTop()),this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight();var d=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+c,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){d.offsets.push(this[0]),d.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.0",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)
+}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.0",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=i?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a("body").height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
\ No newline at end of file
diff --git a/ungleich_page/static/ungleich_page/js/cbpAnimatedHeader.js b/ungleich_page/static/ungleich_page/js/cbpAnimatedHeader.js
new file mode 100755
index 0000000..4554e2e
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/js/cbpAnimatedHeader.js
@@ -0,0 +1,44 @@
+/**
+ * cbpAnimatedHeader.js v1.0.0
+ * http://www.codrops.com
+ *
+ * Licensed under the MIT license.
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * Copyright 2013, Codrops
+ * http://www.codrops.com
+ */
+var cbpAnimatedHeader = (function() {
+
+ var docElem = document.documentElement,
+ header = document.querySelector( '.navbar-default' ),
+ didScroll = false,
+ changeHeaderOn = 300;
+
+ function init() {
+ window.addEventListener( 'scroll', function( event ) {
+ if( !didScroll ) {
+ didScroll = true;
+ setTimeout( scrollPage, 250 );
+ }
+ }, false );
+ }
+
+ function scrollPage() {
+ var sy = scrollY();
+ if ( sy >= changeHeaderOn ) {
+ classie.add( header, 'navbar-shrink' );
+ }
+ else {
+ classie.remove( header, 'navbar-shrink' );
+ }
+ didScroll = false;
+ }
+
+ function scrollY() {
+ return window.pageYOffset || docElem.scrollTop;
+ }
+
+ init();
+
+})();
\ No newline at end of file
diff --git a/ungleich_page/static/ungleich_page/js/cbpAnimatedHeader.min.js b/ungleich_page/static/ungleich_page/js/cbpAnimatedHeader.min.js
new file mode 100755
index 0000000..58743a6
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/js/cbpAnimatedHeader.min.js
@@ -0,0 +1,11 @@
+/**
+ * cbpAnimatedHeader.min.js v1.0.0
+ * http://www.codrops.com
+ *
+ * Licensed under the MIT license.
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * Copyright 2013, Codrops
+ * http://www.codrops.com
+ */
+var cbpAnimatedHeader=(function(){var b=document.documentElement,g=document.querySelector(".navbar-default"),e=false,a=300;function f(){window.addEventListener("scroll",function(h){if(!e){e=true;setTimeout(d,250)}},false)}function d(){var h=c();if(h>=a){classie.add(g,"cbp-af-header-shrink")}else{classie.remove(g,"cbp-af-header-shrink")}e=false}function c(){return window.pageYOffset||b.scrollTop}f()})();
\ No newline at end of file
diff --git a/ungleich_page/static/ungleich_page/js/classie.js b/ungleich_page/static/ungleich_page/js/classie.js
new file mode 100755
index 0000000..a967554
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/js/classie.js
@@ -0,0 +1,80 @@
+/*!
+ * classie - class helper functions
+ * from bonzo https://github.com/ded/bonzo
+ *
+ * classie.has( elem, 'my-class' ) -> true/false
+ * classie.add( elem, 'my-new-class' )
+ * classie.remove( elem, 'my-unwanted-class' )
+ * classie.toggle( elem, 'my-class' )
+ */
+
+/*jshint browser: true, strict: true, undef: true */
+/*global define: false */
+
+( function( window ) {
+
+'use strict';
+
+// class helper functions from bonzo https://github.com/ded/bonzo
+
+function classReg( className ) {
+ return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
+}
+
+// classList support for class management
+// altho to be fair, the api sucks because it won't accept multiple classes at once
+var hasClass, addClass, removeClass;
+
+if ( 'classList' in document.documentElement ) {
+ hasClass = function( elem, c ) {
+ return elem.classList.contains( c );
+ };
+ addClass = function( elem, c ) {
+ elem.classList.add( c );
+ };
+ removeClass = function( elem, c ) {
+ elem.classList.remove( c );
+ };
+}
+else {
+ hasClass = function( elem, c ) {
+ return classReg( c ).test( elem.className );
+ };
+ addClass = function( elem, c ) {
+ if ( !hasClass( elem, c ) ) {
+ elem.className = elem.className + ' ' + c;
+ }
+ };
+ removeClass = function( elem, c ) {
+ elem.className = elem.className.replace( classReg( c ), ' ' );
+ };
+}
+
+function toggleClass( elem, c ) {
+ var fn = hasClass( elem, c ) ? removeClass : addClass;
+ fn( elem, c );
+}
+
+var classie = {
+ // full names
+ hasClass: hasClass,
+ addClass: addClass,
+ removeClass: removeClass,
+ toggleClass: toggleClass,
+ // short names
+ has: hasClass,
+ add: addClass,
+ remove: removeClass,
+ toggle: toggleClass
+};
+
+// transport
+if ( typeof define === 'function' && define.amd ) {
+ // AMD
+ define( classie );
+} else {
+ // browser global
+ window.classie = classie;
+}
+
+})( window );
diff --git a/ungleich_page/static/ungleich_page/js/contact_me.js b/ungleich_page/static/ungleich_page/js/contact_me.js
new file mode 100755
index 0000000..0567067
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/js/contact_me.js
@@ -0,0 +1,70 @@
+$(function() {
+
+ $("input,textarea").jqBootstrapValidation({
+ preventSubmit: true,
+ submitError: function($form, event, errors) {
+ // additional error messages or events
+ },
+ submitSuccess: function($form, event) {
+ event.preventDefault(); // prevent default submit behaviour
+ // get values from FORM
+ var name = $("input#name").val();
+ var email = $("input#email").val();
+ var phone = $("input#phone").val();
+ var message = $("textarea#message").val();
+ var firstName = name; // For Success/Failure Message
+ // Check for white space in name for Success/Fail message
+ if (firstName.indexOf(' ') >= 0) {
+ firstName = name.split(' ').slice(0, -1).join(' ');
+ }
+ $.ajax({
+ url: "././mail/contact_me.php",
+ type: "POST",
+ data: {
+ name: name,
+ phone: phone,
+ email: email,
+ message: message
+ },
+ cache: false,
+ success: function() {
+ // Success message
+ $('#success').html("");
+ $('#success > .alert-success').html("×")
+ .append(" ");
+ $('#success > .alert-success')
+ .append("Your message has been sent. ");
+ $('#success > .alert-success')
+ .append('
');
+
+ //clear all fields
+ $('#contactForm').trigger("reset");
+ },
+ error: function() {
+ // Fail message
+ $('#success').html("");
+ $('#success > .alert-danger').html("×")
+ .append(" ");
+ $('#success > .alert-danger').append("Sorry " + firstName + ", it seems that my mail server is not responding. Please try again later!");
+ $('#success > .alert-danger').append('
');
+ //clear all fields
+ $('#contactForm').trigger("reset");
+ },
+ })
+ },
+ filter: function() {
+ return $(this).is(":visible");
+ },
+ });
+
+ $("a[data-toggle=\"tab\"]").click(function(e) {
+ e.preventDefault();
+ $(this).tab("show");
+ });
+});
+
+
+/*When clicking on Full hide fail/success boxes */
+$('#name').focus(function() {
+ $('#success').html('');
+});
diff --git a/ungleich_page/static/ungleich_page/js/jqBootstrapValidation.js b/ungleich_page/static/ungleich_page/js/jqBootstrapValidation.js
new file mode 100755
index 0000000..7b3b922
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/js/jqBootstrapValidation.js
@@ -0,0 +1,912 @@
+/* jqBootstrapValidation
+ * A plugin for automating validation on Twitter Bootstrap formatted forms.
+ *
+ * v1.3.6
+ *
+ * License: MIT - see LICENSE file
+ *
+ * http://ReactiveRaven.github.com/jqBootstrapValidation/
+ */
+
+(function( $ ){
+
+ var createdElements = [];
+
+ var defaults = {
+ options: {
+ prependExistingHelpBlock: false,
+ sniffHtml: true, // sniff for 'required', 'maxlength', etc
+ preventSubmit: true, // stop the form submit event from firing if validation fails
+ submitError: false, // function called if there is an error when trying to submit
+ submitSuccess: false, // function called just before a successful submit event is sent to the server
+ semanticallyStrict: false, // set to true to tidy up generated HTML output
+ autoAdd: {
+ helpBlocks: true
+ },
+ filter: function () {
+ // return $(this).is(":visible"); // only validate elements you can see
+ return true; // validate everything
+ }
+ },
+ methods: {
+ init : function( options ) {
+
+ var settings = $.extend(true, {}, defaults);
+
+ settings.options = $.extend(true, settings.options, options);
+
+ var $siblingElements = this;
+
+ var uniqueForms = $.unique(
+ $siblingElements.map( function () {
+ return $(this).parents("form")[0];
+ }).toArray()
+ );
+
+ $(uniqueForms).bind("submit", function (e) {
+ var $form = $(this);
+ var warningsFound = 0;
+ var $inputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter);
+ $inputs.trigger("submit.validation").trigger("validationLostFocus.validation");
+
+ $inputs.each(function (i, el) {
+ var $this = $(el),
+ $controlGroup = $this.parents(".form-group").first();
+ if (
+ $controlGroup.hasClass("warning")
+ ) {
+ $controlGroup.removeClass("warning").addClass("error");
+ warningsFound++;
+ }
+ });
+
+ $inputs.trigger("validationLostFocus.validation");
+
+ if (warningsFound) {
+ if (settings.options.preventSubmit) {
+ e.preventDefault();
+ }
+ $form.addClass("error");
+ if ($.isFunction(settings.options.submitError)) {
+ settings.options.submitError($form, e, $inputs.jqBootstrapValidation("collectErrors", true));
+ }
+ } else {
+ $form.removeClass("error");
+ if ($.isFunction(settings.options.submitSuccess)) {
+ settings.options.submitSuccess($form, e);
+ }
+ }
+ });
+
+ return this.each(function(){
+
+ // Get references to everything we're interested in
+ var $this = $(this),
+ $controlGroup = $this.parents(".form-group").first(),
+ $helpBlock = $controlGroup.find(".help-block").first(),
+ $form = $this.parents("form").first(),
+ validatorNames = [];
+
+ // create message container if not exists
+ if (!$helpBlock.length && settings.options.autoAdd && settings.options.autoAdd.helpBlocks) {
+ $helpBlock = $('
');
+ $controlGroup.find('.controls').append($helpBlock);
+ createdElements.push($helpBlock[0]);
+ }
+
+ // =============================================================
+ // SNIFF HTML FOR VALIDATORS
+ // =============================================================
+
+ // *snort sniff snuffle*
+
+ if (settings.options.sniffHtml) {
+ var message = "";
+ // ---------------------------------------------------------
+ // PATTERN
+ // ---------------------------------------------------------
+ if ($this.attr("pattern") !== undefined) {
+ message = "Not in the expected format";
+ if ($this.data("validationPatternMessage")) {
+ message = $this.data("validationPatternMessage");
+ }
+ $this.data("validationPatternMessage", message);
+ $this.data("validationPatternRegex", $this.attr("pattern"));
+ }
+ // ---------------------------------------------------------
+ // MAX
+ // ---------------------------------------------------------
+ if ($this.attr("max") !== undefined || $this.attr("aria-valuemax") !== undefined) {
+ var max = ($this.attr("max") !== undefined ? $this.attr("max") : $this.attr("aria-valuemax"));
+ message = "Too high: Maximum of '" + max + "'";
+ if ($this.data("validationMaxMessage")) {
+ message = $this.data("validationMaxMessage");
+ }
+ $this.data("validationMaxMessage", message);
+ $this.data("validationMaxMax", max);
+ }
+ // ---------------------------------------------------------
+ // MIN
+ // ---------------------------------------------------------
+ if ($this.attr("min") !== undefined || $this.attr("aria-valuemin") !== undefined) {
+ var min = ($this.attr("min") !== undefined ? $this.attr("min") : $this.attr("aria-valuemin"));
+ message = "Too low: Minimum of '" + min + "'";
+ if ($this.data("validationMinMessage")) {
+ message = $this.data("validationMinMessage");
+ }
+ $this.data("validationMinMessage", message);
+ $this.data("validationMinMin", min);
+ }
+ // ---------------------------------------------------------
+ // MAXLENGTH
+ // ---------------------------------------------------------
+ if ($this.attr("maxlength") !== undefined) {
+ message = "Too long: Maximum of '" + $this.attr("maxlength") + "' characters";
+ if ($this.data("validationMaxlengthMessage")) {
+ message = $this.data("validationMaxlengthMessage");
+ }
+ $this.data("validationMaxlengthMessage", message);
+ $this.data("validationMaxlengthMaxlength", $this.attr("maxlength"));
+ }
+ // ---------------------------------------------------------
+ // MINLENGTH
+ // ---------------------------------------------------------
+ if ($this.attr("minlength") !== undefined) {
+ message = "Too short: Minimum of '" + $this.attr("minlength") + "' characters";
+ if ($this.data("validationMinlengthMessage")) {
+ message = $this.data("validationMinlengthMessage");
+ }
+ $this.data("validationMinlengthMessage", message);
+ $this.data("validationMinlengthMinlength", $this.attr("minlength"));
+ }
+ // ---------------------------------------------------------
+ // REQUIRED
+ // ---------------------------------------------------------
+ if ($this.attr("required") !== undefined || $this.attr("aria-required") !== undefined) {
+ message = settings.builtInValidators.required.message;
+ if ($this.data("validationRequiredMessage")) {
+ message = $this.data("validationRequiredMessage");
+ }
+ $this.data("validationRequiredMessage", message);
+ }
+ // ---------------------------------------------------------
+ // NUMBER
+ // ---------------------------------------------------------
+ if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "number") {
+ message = settings.builtInValidators.number.message;
+ if ($this.data("validationNumberMessage")) {
+ message = $this.data("validationNumberMessage");
+ }
+ $this.data("validationNumberMessage", message);
+ }
+ // ---------------------------------------------------------
+ // EMAIL
+ // ---------------------------------------------------------
+ if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "email") {
+ message = "Not a valid email address";
+ if ($this.data("validationValidemailMessage")) {
+ message = $this.data("validationValidemailMessage");
+ } else if ($this.data("validationEmailMessage")) {
+ message = $this.data("validationEmailMessage");
+ }
+ $this.data("validationValidemailMessage", message);
+ }
+ // ---------------------------------------------------------
+ // MINCHECKED
+ // ---------------------------------------------------------
+ if ($this.attr("minchecked") !== undefined) {
+ message = "Not enough options checked; Minimum of '" + $this.attr("minchecked") + "' required";
+ if ($this.data("validationMincheckedMessage")) {
+ message = $this.data("validationMincheckedMessage");
+ }
+ $this.data("validationMincheckedMessage", message);
+ $this.data("validationMincheckedMinchecked", $this.attr("minchecked"));
+ }
+ // ---------------------------------------------------------
+ // MAXCHECKED
+ // ---------------------------------------------------------
+ if ($this.attr("maxchecked") !== undefined) {
+ message = "Too many options checked; Maximum of '" + $this.attr("maxchecked") + "' required";
+ if ($this.data("validationMaxcheckedMessage")) {
+ message = $this.data("validationMaxcheckedMessage");
+ }
+ $this.data("validationMaxcheckedMessage", message);
+ $this.data("validationMaxcheckedMaxchecked", $this.attr("maxchecked"));
+ }
+ }
+
+ // =============================================================
+ // COLLECT VALIDATOR NAMES
+ // =============================================================
+
+ // Get named validators
+ if ($this.data("validation") !== undefined) {
+ validatorNames = $this.data("validation").split(",");
+ }
+
+ // Get extra ones defined on the element's data attributes
+ $.each($this.data(), function (i, el) {
+ var parts = i.replace(/([A-Z])/g, ",$1").split(",");
+ if (parts[0] === "validation" && parts[1]) {
+ validatorNames.push(parts[1]);
+ }
+ });
+
+ // =============================================================
+ // NORMALISE VALIDATOR NAMES
+ // =============================================================
+
+ var validatorNamesToInspect = validatorNames;
+ var newValidatorNamesToInspect = [];
+
+ do // repeatedly expand 'shortcut' validators into their real validators
+ {
+ // Uppercase only the first letter of each name
+ $.each(validatorNames, function (i, el) {
+ validatorNames[i] = formatValidatorName(el);
+ });
+
+ // Remove duplicate validator names
+ validatorNames = $.unique(validatorNames);
+
+ // Pull out the new validator names from each shortcut
+ newValidatorNamesToInspect = [];
+ $.each(validatorNamesToInspect, function(i, el) {
+ if ($this.data("validation" + el + "Shortcut") !== undefined) {
+ // Are these custom validators?
+ // Pull them out!
+ $.each($this.data("validation" + el + "Shortcut").split(","), function(i2, el2) {
+ newValidatorNamesToInspect.push(el2);
+ });
+ } else if (settings.builtInValidators[el.toLowerCase()]) {
+ // Is this a recognised built-in?
+ // Pull it out!
+ var validator = settings.builtInValidators[el.toLowerCase()];
+ if (validator.type.toLowerCase() === "shortcut") {
+ $.each(validator.shortcut.split(","), function (i, el) {
+ el = formatValidatorName(el);
+ newValidatorNamesToInspect.push(el);
+ validatorNames.push(el);
+ });
+ }
+ }
+ });
+
+ validatorNamesToInspect = newValidatorNamesToInspect;
+
+ } while (validatorNamesToInspect.length > 0)
+
+ // =============================================================
+ // SET UP VALIDATOR ARRAYS
+ // =============================================================
+
+ var validators = {};
+
+ $.each(validatorNames, function (i, el) {
+ // Set up the 'override' message
+ var message = $this.data("validation" + el + "Message");
+ var hasOverrideMessage = (message !== undefined);
+ var foundValidator = false;
+ message =
+ (
+ message
+ ? message
+ : "'" + el + "' validation failed "
+ )
+ ;
+
+ $.each(
+ settings.validatorTypes,
+ function (validatorType, validatorTemplate) {
+ if (validators[validatorType] === undefined) {
+ validators[validatorType] = [];
+ }
+ if (!foundValidator && $this.data("validation" + el + formatValidatorName(validatorTemplate.name)) !== undefined) {
+ validators[validatorType].push(
+ $.extend(
+ true,
+ {
+ name: formatValidatorName(validatorTemplate.name),
+ message: message
+ },
+ validatorTemplate.init($this, el)
+ )
+ );
+ foundValidator = true;
+ }
+ }
+ );
+
+ if (!foundValidator && settings.builtInValidators[el.toLowerCase()]) {
+
+ var validator = $.extend(true, {}, settings.builtInValidators[el.toLowerCase()]);
+ if (hasOverrideMessage) {
+ validator.message = message;
+ }
+ var validatorType = validator.type.toLowerCase();
+
+ if (validatorType === "shortcut") {
+ foundValidator = true;
+ } else {
+ $.each(
+ settings.validatorTypes,
+ function (validatorTemplateType, validatorTemplate) {
+ if (validators[validatorTemplateType] === undefined) {
+ validators[validatorTemplateType] = [];
+ }
+ if (!foundValidator && validatorType === validatorTemplateType.toLowerCase()) {
+ $this.data("validation" + el + formatValidatorName(validatorTemplate.name), validator[validatorTemplate.name.toLowerCase()]);
+ validators[validatorType].push(
+ $.extend(
+ validator,
+ validatorTemplate.init($this, el)
+ )
+ );
+ foundValidator = true;
+ }
+ }
+ );
+ }
+ }
+
+ if (! foundValidator) {
+ $.error("Cannot find validation info for '" + el + "'");
+ }
+ });
+
+ // =============================================================
+ // STORE FALLBACK VALUES
+ // =============================================================
+
+ $helpBlock.data(
+ "original-contents",
+ (
+ $helpBlock.data("original-contents")
+ ? $helpBlock.data("original-contents")
+ : $helpBlock.html()
+ )
+ );
+
+ $helpBlock.data(
+ "original-role",
+ (
+ $helpBlock.data("original-role")
+ ? $helpBlock.data("original-role")
+ : $helpBlock.attr("role")
+ )
+ );
+
+ $controlGroup.data(
+ "original-classes",
+ (
+ $controlGroup.data("original-clases")
+ ? $controlGroup.data("original-classes")
+ : $controlGroup.attr("class")
+ )
+ );
+
+ $this.data(
+ "original-aria-invalid",
+ (
+ $this.data("original-aria-invalid")
+ ? $this.data("original-aria-invalid")
+ : $this.attr("aria-invalid")
+ )
+ );
+
+ // =============================================================
+ // VALIDATION
+ // =============================================================
+
+ $this.bind(
+ "validation.validation",
+ function (event, params) {
+
+ var value = getValue($this);
+
+ // Get a list of the errors to apply
+ var errorsFound = [];
+
+ $.each(validators, function (validatorType, validatorTypeArray) {
+ if (value || value.length || (params && params.includeEmpty) || (!!settings.validatorTypes[validatorType].blockSubmit && params && !!params.submitting)) {
+ $.each(validatorTypeArray, function (i, validator) {
+ if (settings.validatorTypes[validatorType].validate($this, value, validator)) {
+ errorsFound.push(validator.message);
+ }
+ });
+ }
+ });
+
+ return errorsFound;
+ }
+ );
+
+ $this.bind(
+ "getValidators.validation",
+ function () {
+ return validators;
+ }
+ );
+
+ // =============================================================
+ // WATCH FOR CHANGES
+ // =============================================================
+ $this.bind(
+ "submit.validation",
+ function () {
+ return $this.triggerHandler("change.validation", {submitting: true});
+ }
+ );
+ $this.bind(
+ [
+ "keyup",
+ "focus",
+ "blur",
+ "click",
+ "keydown",
+ "keypress",
+ "change"
+ ].join(".validation ") + ".validation",
+ function (e, params) {
+
+ var value = getValue($this);
+
+ var errorsFound = [];
+
+ $controlGroup.find("input,textarea,select").each(function (i, el) {
+ var oldCount = errorsFound.length;
+ $.each($(el).triggerHandler("validation.validation", params), function (j, message) {
+ errorsFound.push(message);
+ });
+ if (errorsFound.length > oldCount) {
+ $(el).attr("aria-invalid", "true");
+ } else {
+ var original = $this.data("original-aria-invalid");
+ $(el).attr("aria-invalid", (original !== undefined ? original : false));
+ }
+ });
+
+ $form.find("input,select,textarea").not($this).not("[name=\"" + $this.attr("name") + "\"]").trigger("validationLostFocus.validation");
+
+ errorsFound = $.unique(errorsFound.sort());
+
+ // Were there any errors?
+ if (errorsFound.length) {
+ // Better flag it up as a warning.
+ $controlGroup.removeClass("success error").addClass("warning");
+
+ // How many errors did we find?
+ if (settings.options.semanticallyStrict && errorsFound.length === 1) {
+ // Only one? Being strict? Just output it.
+ $helpBlock.html(errorsFound[0] +
+ ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" ));
+ } else {
+ // Multiple? Being sloppy? Glue them together into an UL.
+ $helpBlock.html("" + errorsFound.join(" ") + " " +
+ ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" ));
+ }
+ } else {
+ $controlGroup.removeClass("warning error success");
+ if (value.length > 0) {
+ $controlGroup.addClass("success");
+ }
+ $helpBlock.html($helpBlock.data("original-contents"));
+ }
+
+ if (e.type === "blur") {
+ $controlGroup.removeClass("success");
+ }
+ }
+ );
+ $this.bind("validationLostFocus.validation", function () {
+ $controlGroup.removeClass("success");
+ });
+ });
+ },
+ destroy : function( ) {
+
+ return this.each(
+ function() {
+
+ var
+ $this = $(this),
+ $controlGroup = $this.parents(".form-group").first(),
+ $helpBlock = $controlGroup.find(".help-block").first();
+
+ // remove our events
+ $this.unbind('.validation'); // events are namespaced.
+ // reset help text
+ $helpBlock.html($helpBlock.data("original-contents"));
+ // reset classes
+ $controlGroup.attr("class", $controlGroup.data("original-classes"));
+ // reset aria
+ $this.attr("aria-invalid", $this.data("original-aria-invalid"));
+ // reset role
+ $helpBlock.attr("role", $this.data("original-role"));
+ // remove all elements we created
+ if (createdElements.indexOf($helpBlock[0]) > -1) {
+ $helpBlock.remove();
+ }
+
+ }
+ );
+
+ },
+ collectErrors : function(includeEmpty) {
+
+ var errorMessages = {};
+ this.each(function (i, el) {
+ var $el = $(el);
+ var name = $el.attr("name");
+ var errors = $el.triggerHandler("validation.validation", {includeEmpty: true});
+ errorMessages[name] = $.extend(true, errors, errorMessages[name]);
+ });
+
+ $.each(errorMessages, function (i, el) {
+ if (el.length === 0) {
+ delete errorMessages[i];
+ }
+ });
+
+ return errorMessages;
+
+ },
+ hasErrors: function() {
+
+ var errorMessages = [];
+
+ this.each(function (i, el) {
+ errorMessages = errorMessages.concat(
+ $(el).triggerHandler("getValidators.validation") ? $(el).triggerHandler("validation.validation", {submitting: true}) : []
+ );
+ });
+
+ return (errorMessages.length > 0);
+ },
+ override : function (newDefaults) {
+ defaults = $.extend(true, defaults, newDefaults);
+ }
+ },
+ validatorTypes: {
+ callback: {
+ name: "callback",
+ init: function ($this, name) {
+ return {
+ validatorName: name,
+ callback: $this.data("validation" + name + "Callback"),
+ lastValue: $this.val(),
+ lastValid: true,
+ lastFinished: true
+ };
+ },
+ validate: function ($this, value, validator) {
+ if (validator.lastValue === value && validator.lastFinished) {
+ return !validator.lastValid;
+ }
+
+ if (validator.lastFinished === true)
+ {
+ validator.lastValue = value;
+ validator.lastValid = true;
+ validator.lastFinished = false;
+
+ var rrjqbvValidator = validator;
+ var rrjqbvThis = $this;
+ executeFunctionByName(
+ validator.callback,
+ window,
+ $this,
+ value,
+ function (data) {
+ if (rrjqbvValidator.lastValue === data.value) {
+ rrjqbvValidator.lastValid = data.valid;
+ if (data.message) {
+ rrjqbvValidator.message = data.message;
+ }
+ rrjqbvValidator.lastFinished = true;
+ rrjqbvThis.data("validation" + rrjqbvValidator.validatorName + "Message", rrjqbvValidator.message);
+ // Timeout is set to avoid problems with the events being considered 'already fired'
+ setTimeout(function () {
+ rrjqbvThis.trigger("change.validation");
+ }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
+ }
+ }
+ );
+ }
+
+ return false;
+
+ }
+ },
+ ajax: {
+ name: "ajax",
+ init: function ($this, name) {
+ return {
+ validatorName: name,
+ url: $this.data("validation" + name + "Ajax"),
+ lastValue: $this.val(),
+ lastValid: true,
+ lastFinished: true
+ };
+ },
+ validate: function ($this, value, validator) {
+ if (""+validator.lastValue === ""+value && validator.lastFinished === true) {
+ return validator.lastValid === false;
+ }
+
+ if (validator.lastFinished === true)
+ {
+ validator.lastValue = value;
+ validator.lastValid = true;
+ validator.lastFinished = false;
+ $.ajax({
+ url: validator.url,
+ data: "value=" + value + "&field=" + $this.attr("name"),
+ dataType: "json",
+ success: function (data) {
+ if (""+validator.lastValue === ""+data.value) {
+ validator.lastValid = !!(data.valid);
+ if (data.message) {
+ validator.message = data.message;
+ }
+ validator.lastFinished = true;
+ $this.data("validation" + validator.validatorName + "Message", validator.message);
+ // Timeout is set to avoid problems with the events being considered 'already fired'
+ setTimeout(function () {
+ $this.trigger("change.validation");
+ }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
+ }
+ },
+ failure: function () {
+ validator.lastValid = true;
+ validator.message = "ajax call failed";
+ validator.lastFinished = true;
+ $this.data("validation" + validator.validatorName + "Message", validator.message);
+ // Timeout is set to avoid problems with the events being considered 'already fired'
+ setTimeout(function () {
+ $this.trigger("change.validation");
+ }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
+ }
+ });
+ }
+
+ return false;
+
+ }
+ },
+ regex: {
+ name: "regex",
+ init: function ($this, name) {
+ return {regex: regexFromString($this.data("validation" + name + "Regex"))};
+ },
+ validate: function ($this, value, validator) {
+ return (!validator.regex.test(value) && ! validator.negative)
+ || (validator.regex.test(value) && validator.negative);
+ }
+ },
+ required: {
+ name: "required",
+ init: function ($this, name) {
+ return {};
+ },
+ validate: function ($this, value, validator) {
+ return !!(value.length === 0 && ! validator.negative)
+ || !!(value.length > 0 && validator.negative);
+ },
+ blockSubmit: true
+ },
+ match: {
+ name: "match",
+ init: function ($this, name) {
+ var element = $this.parents("form").first().find("[name=\"" + $this.data("validation" + name + "Match") + "\"]").first();
+ element.bind("validation.validation", function () {
+ $this.trigger("change.validation", {submitting: true});
+ });
+ return {"element": element};
+ },
+ validate: function ($this, value, validator) {
+ return (value !== validator.element.val() && ! validator.negative)
+ || (value === validator.element.val() && validator.negative);
+ },
+ blockSubmit: true
+ },
+ max: {
+ name: "max",
+ init: function ($this, name) {
+ return {max: $this.data("validation" + name + "Max")};
+ },
+ validate: function ($this, value, validator) {
+ return (parseFloat(value, 10) > parseFloat(validator.max, 10) && ! validator.negative)
+ || (parseFloat(value, 10) <= parseFloat(validator.max, 10) && validator.negative);
+ }
+ },
+ min: {
+ name: "min",
+ init: function ($this, name) {
+ return {min: $this.data("validation" + name + "Min")};
+ },
+ validate: function ($this, value, validator) {
+ return (parseFloat(value) < parseFloat(validator.min) && ! validator.negative)
+ || (parseFloat(value) >= parseFloat(validator.min) && validator.negative);
+ }
+ },
+ maxlength: {
+ name: "maxlength",
+ init: function ($this, name) {
+ return {maxlength: $this.data("validation" + name + "Maxlength")};
+ },
+ validate: function ($this, value, validator) {
+ return ((value.length > validator.maxlength) && ! validator.negative)
+ || ((value.length <= validator.maxlength) && validator.negative);
+ }
+ },
+ minlength: {
+ name: "minlength",
+ init: function ($this, name) {
+ return {minlength: $this.data("validation" + name + "Minlength")};
+ },
+ validate: function ($this, value, validator) {
+ return ((value.length < validator.minlength) && ! validator.negative)
+ || ((value.length >= validator.minlength) && validator.negative);
+ }
+ },
+ maxchecked: {
+ name: "maxchecked",
+ init: function ($this, name) {
+ var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]");
+ elements.bind("click.validation", function () {
+ $this.trigger("change.validation", {includeEmpty: true});
+ });
+ return {maxchecked: $this.data("validation" + name + "Maxchecked"), elements: elements};
+ },
+ validate: function ($this, value, validator) {
+ return (validator.elements.filter(":checked").length > validator.maxchecked && ! validator.negative)
+ || (validator.elements.filter(":checked").length <= validator.maxchecked && validator.negative);
+ },
+ blockSubmit: true
+ },
+ minchecked: {
+ name: "minchecked",
+ init: function ($this, name) {
+ var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]");
+ elements.bind("click.validation", function () {
+ $this.trigger("change.validation", {includeEmpty: true});
+ });
+ return {minchecked: $this.data("validation" + name + "Minchecked"), elements: elements};
+ },
+ validate: function ($this, value, validator) {
+ return (validator.elements.filter(":checked").length < validator.minchecked && ! validator.negative)
+ || (validator.elements.filter(":checked").length >= validator.minchecked && validator.negative);
+ },
+ blockSubmit: true
+ }
+ },
+ builtInValidators: {
+ email: {
+ name: "Email",
+ type: "shortcut",
+ shortcut: "validemail"
+ },
+ validemail: {
+ name: "Validemail",
+ type: "regex",
+ regex: "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\.[A-Za-z]{2,4}",
+ message: "Not a valid email address"
+ },
+ passwordagain: {
+ name: "Passwordagain",
+ type: "match",
+ match: "password",
+ message: "Does not match the given password"
+ },
+ positive: {
+ name: "Positive",
+ type: "shortcut",
+ shortcut: "number,positivenumber"
+ },
+ negative: {
+ name: "Negative",
+ type: "shortcut",
+ shortcut: "number,negativenumber"
+ },
+ number: {
+ name: "Number",
+ type: "regex",
+ regex: "([+-]?\\\d+(\\\.\\\d*)?([eE][+-]?[0-9]+)?)?",
+ message: "Must be a number"
+ },
+ integer: {
+ name: "Integer",
+ type: "regex",
+ regex: "[+-]?\\\d+",
+ message: "No decimal places allowed"
+ },
+ positivenumber: {
+ name: "Positivenumber",
+ type: "min",
+ min: 0,
+ message: "Must be a positive number"
+ },
+ negativenumber: {
+ name: "Negativenumber",
+ type: "max",
+ max: 0,
+ message: "Must be a negative number"
+ },
+ required: {
+ name: "Required",
+ type: "required",
+ message: "This is required"
+ },
+ checkone: {
+ name: "Checkone",
+ type: "minchecked",
+ minchecked: 1,
+ message: "Check at least one option"
+ }
+ }
+ };
+
+ var formatValidatorName = function (name) {
+ return name
+ .toLowerCase()
+ .replace(
+ /(^|\s)([a-z])/g ,
+ function(m,p1,p2) {
+ return p1+p2.toUpperCase();
+ }
+ )
+ ;
+ };
+
+ var getValue = function ($this) {
+ // Extract the value we're talking about
+ var value = $this.val();
+ var type = $this.attr("type");
+ if (type === "checkbox") {
+ value = ($this.is(":checked") ? value : "");
+ }
+ if (type === "radio") {
+ value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? value : "");
+ }
+ return value;
+ };
+
+ function regexFromString(inputstring) {
+ return new RegExp("^" + inputstring + "$");
+ }
+
+ /**
+ * Thanks to Jason Bunting via StackOverflow.com
+ *
+ * http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string#answer-359910
+ * Short link: http://tinyurl.com/executeFunctionByName
+ **/
+ function executeFunctionByName(functionName, context /*, args*/) {
+ var args = Array.prototype.slice.call(arguments).splice(2);
+ var namespaces = functionName.split(".");
+ var func = namespaces.pop();
+ for(var i = 0; i < namespaces.length; i++) {
+ context = context[namespaces[i]];
+ }
+ return context[func].apply(this, args);
+ }
+
+ $.fn.jqBootstrapValidation = function( method ) {
+
+ if ( defaults.methods[method] ) {
+ return defaults.methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
+ } else if ( typeof method === 'object' || ! method ) {
+ return defaults.methods.init.apply( this, arguments );
+ } else {
+ $.error( 'Method ' + method + ' does not exist on jQuery.jqBootstrapValidation' );
+ return null;
+ }
+
+ };
+
+ $.jqBootstrapValidation = function (options) {
+ $(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this,arguments);
+ };
+
+})( jQuery );
diff --git a/ungleich_page/static/ungleich_page/js/jquery.js b/ungleich_page/static/ungleich_page/js/jquery.js
new file mode 100755
index 0000000..d1608e3
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/js/jquery.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
+!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML=" ",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML=" ","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML=" ",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;
+if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" a ",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="x ",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML=" ",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h ]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/\s*$/g,rb={option:[1,""," "],legend:[1,""," "],area:[1,""," "],param:[1,""," "],thead:[1,""],tr:[2,""],col:[2,""],td:[3,""],_default:k.htmlSerialize?[0,"",""]:[1,"X","
"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1>$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?""!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" a ",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight)),b.innerHTML="",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Mb=/alpha\([^)]*\)/i,Nb=/opacity\s*=\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp("^("+S+")(.*)$","i"),Qb=new RegExp("^([+-])=("+S+")","i"),Rb={position:"absolute",visibility:"hidden",display:"block"},Sb={letterSpacing:"0",fontWeight:"400"},Tb=["Webkit","O","Moz","ms"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fb(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Yb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),"normal"===f&&b in Sb&&(f=Sb[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Mb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+" "+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Jb,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e)}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")
+},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc("show"),slideUp:gc("hide"),slideToggle:gc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();ca ",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lc=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lc,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var uc=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(uc," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vc=m.now(),wc=/\?/,xc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\/\//,Gc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hc={},Ic={},Jc="*/".concat("*");try{zc=location.href}catch(Kc){zc=y.createElement("a"),zc.href="",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:"GET",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zc)+"").replace(Ac,"").replace(Fc,yc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yc[3]||("http:"===yc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,"$1_="+vc++):e+(wc.test(e)?"&":"?")+"_="+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\[\]$/,Sc=/\r?\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vc(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join("&").replace(Qc,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,"\r\n")}}):{name:b.name,value:c.replace(Sc,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.ActiveXObject&&m(a).on("unload",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&"withCredentials"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_c.pop()||m.expando+"_"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ad.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,"$1"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});
\ No newline at end of file
diff --git a/ungleich_page/static/ungleich_page/js/lib/skrollr.menu.min.js b/ungleich_page/static/ungleich_page/js/lib/skrollr.menu.min.js
new file mode 100755
index 0000000..b125a7b
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/js/lib/skrollr.menu.min.js
@@ -0,0 +1,2 @@
+/*! skrollr-menu 1.0.3 (2015-06-19) | Alexander Prinzhorn - https://github.com/Prinzhorn/skrollr-menu | Free to use under terms of MIT license */
+(function(t,e){"use strict";var n=500,a="sqrt",o=1,r="data-menu-top",i="data-menu-offset",u="data-menu-duration",c="data-menu-ignore",l=e.skrollr,s=e.history,f=!!s.pushState,h=function(e){return e!==t&&e?"A"===e.tagName.toUpperCase()?e:h(e.parentNode):!1},p=function(t){if(1===t.which||0===t.button){var e=h(t.target);e&&m(e)&&t.preventDefault()}},m=function(n,a){var o;if(y){if(n.hostname!==e.location.hostname)return!1;if(n.pathname!==t.location.pathname)return!1;o=n.hash}else o=n.getAttribute("href");if(!/^#/.test(o))return!1;if(!a&&null!==n.getAttribute(c))return!1;var l,h;if(h=T?T(n):n.getAttribute(r),null!==h)l=/p$/.test(h)?h.slice(0,-1)/100*t.documentElement.clientHeight:+h*k;else{var p=t.getElementById(o.substr(1));if(!p)return!1;l=v.relativeToAbsolute(p,"top","top");var m=p.getAttribute(i);null!==m&&(l+=+m)}f&&N&&!a&&s.pushState({top:l},"",o);var d=parseInt(n.getAttribute(u),10),q=A(v.getScrollTop(),l);return isNaN(d)||(q=d),E&&E(o,l),S&&!a?v.animateTo(l,{duration:q,easing:b}):g(function(){v.setScrollTop(l)}),!0},d=function(){if(e.location.hash&&t.querySelector){var n=t.querySelector('a[href="'+e.location.hash+'"]');n||(n=t.createElement("a"),n.href=e.location.hash),m(n,!0)}},g=function(t){e.setTimeout(t,1)};l.menu={},l.menu.init=function(r,i){v=r,i=i||{},b=i.easing||a,S=i.animate!==!1,A=i.duration||n,T=i.handleLink,k=i.scale||o,y=i.complexLinks===!0,E=i.change,N=i.updateUrl!==!1,"number"==typeof A&&(A=function(t){return function(){return t}}(A)),l.addEvent(t,"click",p),f&&l.addEvent(e,"popstate",function(t){var e=t.state||{},n=e.top||0;g(function(){v.setScrollTop(n)})},!1),d()},l.menu.click=function(t){m(t)};var v,b,A,S,T,k,y,E,N;g(function(){e.location.hash&&e.scrollTo(0,0)})})(document,window);
\ No newline at end of file
diff --git a/ungleich_page/static/ungleich_page/js/lib/skrollr.min.js b/ungleich_page/static/ungleich_page/js/lib/skrollr.min.js
new file mode 100755
index 0000000..d869915
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/js/lib/skrollr.min.js
@@ -0,0 +1,2 @@
+/*! skrollr 0.6.30 (2015-08-12) | Alexander Prinzhorn - https://github.com/Prinzhorn/skrollr | Free to use under terms of MIT license */
+!function(a,b,c){"use strict";function d(c){if(e=b.documentElement,f=b.body,T(),ha=this,c=c||{},ma=c.constants||{},c.easing)for(var d in c.easing)W[d]=c.easing[d];ta=c.edgeStrategy||"set",ka={beforerender:c.beforerender,render:c.render,keyframe:c.keyframe},la=c.forceHeight!==!1,la&&(Ka=c.scale||1),na=c.mobileDeceleration||y,pa=c.smoothScrolling!==!1,qa=c.smoothScrollingDuration||A,ra={targetTop:ha.getScrollTop()},Sa=(c.mobileCheck||function(){return/Android|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent||navigator.vendor||a.opera)})(),Sa?(ja=b.getElementById(c.skrollrBody||z),ja&&ga(),X(),Ea(e,[s,v],[t])):Ea(e,[s,u],[t]),ha.refresh(),wa(a,"resize orientationchange",function(){var a=e.clientWidth,b=e.clientHeight;(b!==Pa||a!==Oa)&&(Pa=b,Oa=a,Qa=!0)});var g=U();return function h(){$(),va=g(h)}(),ha}var e,f,g={get:function(){return ha},init:function(a){return ha||new d(a)},VERSION:"0.6.30"},h=Object.prototype.hasOwnProperty,i=a.Math,j=a.getComputedStyle,k="touchstart",l="touchmove",m="touchcancel",n="touchend",o="skrollable",p=o+"-before",q=o+"-between",r=o+"-after",s="skrollr",t="no-"+s,u=s+"-desktop",v=s+"-mobile",w="linear",x=1e3,y=.004,z="skrollr-body",A=200,B="start",C="end",D="center",E="bottom",F="___skrollable_id",G=/^(?:input|textarea|button|select)$/i,H=/^\s+|\s+$/g,I=/^data(?:-(_\w+))?(?:-?(-?\d*\.?\d+p?))?(?:-?(start|end|top|center|bottom))?(?:-?(top|center|bottom))?$/,J=/\s*(@?[\w\-\[\]]+)\s*:\s*(.+?)\s*(?:;|$)/gi,K=/^(@?[a-z\-]+)\[(\w+)\]$/,L=/-([a-z0-9_])/g,M=function(a,b){return b.toUpperCase()},N=/[\-+]?[\d]*\.?[\d]+/g,O=/\{\?\}/g,P=/rgba?\(\s*-?\d+\s*,\s*-?\d+\s*,\s*-?\d+/g,Q=/[a-z\-]+-gradient/g,R="",S="",T=function(){var a=/^(?:O|Moz|webkit|ms)|(?:-(?:o|moz|webkit|ms)-)/;if(j){var b=j(f,null);for(var c in b)if(R=c.match(a)||+c==c&&b[c].match(a))break;if(!R)return void(R=S="");R=R[0],"-"===R.slice(0,1)?(S=R,R={"-webkit-":"webkit","-moz-":"Moz","-ms-":"ms","-o-":"O"}[R]):S="-"+R.toLowerCase()+"-"}},U=function(){var b=a.requestAnimationFrame||a[R.toLowerCase()+"RequestAnimationFrame"],c=Ha();return(Sa||!b)&&(b=function(b){var d=Ha()-c,e=i.max(0,1e3/60-d);return a.setTimeout(function(){c=Ha(),b()},e)}),b},V=function(){var b=a.cancelAnimationFrame||a[R.toLowerCase()+"CancelAnimationFrame"];return(Sa||!b)&&(b=function(b){return a.clearTimeout(b)}),b},W={begin:function(){return 0},end:function(){return 1},linear:function(a){return a},quadratic:function(a){return a*a},cubic:function(a){return a*a*a},swing:function(a){return-i.cos(a*i.PI)/2+.5},sqrt:function(a){return i.sqrt(a)},outCubic:function(a){return i.pow(a-1,3)+1},bounce:function(a){var b;if(.5083>=a)b=3;else if(.8489>=a)b=9;else if(.96208>=a)b=27;else{if(!(.99981>=a))return 1;b=91}return 1-i.abs(3*i.cos(a*b*1.028)/b)}};d.prototype.refresh=function(a){var d,e,f=!1;for(a===c?(f=!0,ia=[],Ra=0,a=b.getElementsByTagName("*")):a.length===c&&(a=[a]),d=0,e=a.length;e>d;d++){var g=a[d],h=g,i=[],j=pa,k=ta,l=!1;if(f&&F in g&&delete g[F],g.attributes){for(var m=0,n=g.attributes.length;n>m;m++){var p=g.attributes[m];if("data-anchor-target"!==p.name)if("data-smooth-scrolling"!==p.name)if("data-edge-strategy"!==p.name)if("data-emit-events"!==p.name){var q=p.name.match(I);if(null!==q){var r={props:p.value,element:g,eventType:p.name.replace(L,M)};i.push(r);var s=q[1];s&&(r.constant=s.substr(1));var t=q[2];/p$/.test(t)?(r.isPercentage=!0,r.offset=(0|t.slice(0,-1))/100):r.offset=0|t;var u=q[3],v=q[4]||u;u&&u!==B&&u!==C?(r.mode="relative",r.anchors=[u,v]):(r.mode="absolute",u===C?r.isEnd=!0:r.isPercentage||(r.offset=r.offset*Ka))}}else l=!0;else k=p.value;else j="off"!==p.value;else if(h=b.querySelector(p.value),null===h)throw'Unable to find anchor target "'+p.value+'"'}if(i.length){var w,x,y;!f&&F in g?(y=g[F],w=ia[y].styleAttr,x=ia[y].classAttr):(y=g[F]=Ra++,w=g.style.cssText,x=Da(g)),ia[y]={element:g,styleAttr:w,classAttr:x,anchorTarget:h,keyFrames:i,smoothScrolling:j,edgeStrategy:k,emitEvents:l,lastFrameIndex:-1},Ea(g,[o],[])}}}for(Aa(),d=0,e=a.length;e>d;d++){var z=ia[a[d][F]];z!==c&&(_(z),ba(z))}return ha},d.prototype.relativeToAbsolute=function(a,b,c){var d=e.clientHeight,f=a.getBoundingClientRect(),g=f.top,h=f.bottom-f.top;return b===E?g-=d:b===D&&(g-=d/2),c===E?g+=h:c===D&&(g+=h/2),g+=ha.getScrollTop(),g+.5|0},d.prototype.animateTo=function(a,b){b=b||{};var d=Ha(),e=ha.getScrollTop(),f=b.duration===c?x:b.duration;return oa={startTop:e,topDiff:a-e,targetTop:a,duration:f,startTime:d,endTime:d+f,easing:W[b.easing||w],done:b.done},oa.topDiff||(oa.done&&oa.done.call(ha,!1),oa=c),ha},d.prototype.stopAnimateTo=function(){oa&&oa.done&&oa.done.call(ha,!0),oa=c},d.prototype.isAnimatingTo=function(){return!!oa},d.prototype.isMobile=function(){return Sa},d.prototype.setScrollTop=function(b,c){return sa=c===!0,Sa?Ta=i.min(i.max(b,0),Ja):a.scrollTo(0,b),ha},d.prototype.getScrollTop=function(){return Sa?Ta:a.pageYOffset||e.scrollTop||f.scrollTop||0},d.prototype.getMaxScrollTop=function(){return Ja},d.prototype.on=function(a,b){return ka[a]=b,ha},d.prototype.off=function(a){return delete ka[a],ha},d.prototype.destroy=function(){var a=V();a(va),ya(),Ea(e,[t],[s,u,v]);for(var b=0,d=ia.length;d>b;b++)fa(ia[b].element);e.style.overflow=f.style.overflow="",e.style.height=f.style.height="",ja&&g.setStyle(ja,"transform","none"),ha=c,ja=c,ka=c,la=c,Ja=0,Ka=1,ma=c,na=c,La="down",Ma=-1,Oa=0,Pa=0,Qa=!1,oa=c,pa=c,qa=c,ra=c,sa=c,Ra=0,ta=c,Sa=!1,Ta=0,ua=c};var X=function(){var d,g,h,j,o,p,q,r,s,t,u,v;wa(e,[k,l,m,n].join(" "),function(a){var e=a.changedTouches[0];for(j=a.target;3===j.nodeType;)j=j.parentNode;switch(o=e.clientY,p=e.clientX,t=a.timeStamp,G.test(j.tagName)||a.preventDefault(),a.type){case k:d&&d.blur(),ha.stopAnimateTo(),d=j,g=q=o,h=p,s=t;break;case l:G.test(j.tagName)&&b.activeElement!==j&&a.preventDefault(),r=o-q,v=t-u,ha.setScrollTop(Ta-r,!0),q=o,u=t;break;default:case m:case n:var f=g-o,w=h-p,x=w*w+f*f;if(49>x){if(!G.test(d.tagName)){d.focus();var y=b.createEvent("MouseEvents");y.initMouseEvent("click",!0,!0,a.view,1,e.screenX,e.screenY,e.clientX,e.clientY,a.ctrlKey,a.altKey,a.shiftKey,a.metaKey,0,null),d.dispatchEvent(y)}return}d=c;var z=r/v;z=i.max(i.min(z,3),-3);var A=i.abs(z/na),B=z*A+.5*na*A*A,C=ha.getScrollTop()-B,D=0;C>Ja?(D=(Ja-C)/B,C=Ja):0>C&&(D=-C/B,C=0),A*=1-D,ha.animateTo(C+.5|0,{easing:"outCubic",duration:A})}}),a.scrollTo(0,0),e.style.overflow=f.style.overflow="hidden"},Y=function(){var a,b,c,d,f,g,h,j,k,l,m,n=e.clientHeight,o=Ba();for(j=0,k=ia.length;k>j;j++)for(a=ia[j],b=a.element,c=a.anchorTarget,d=a.keyFrames,f=0,g=d.length;g>f;f++)h=d[f],l=h.offset,m=o[h.constant]||0,h.frame=l,h.isPercentage&&(l*=n,h.frame=l),"relative"===h.mode&&(fa(b),h.frame=ha.relativeToAbsolute(c,h.anchors[0],h.anchors[1])-l,fa(b,!0)),h.frame+=m,la&&!h.isEnd&&h.frame>Ja&&(Ja=h.frame);for(Ja=i.max(Ja,Ca()),j=0,k=ia.length;k>j;j++){for(a=ia[j],d=a.keyFrames,f=0,g=d.length;g>f;f++)h=d[f],m=o[h.constant]||0,h.isEnd&&(h.frame=Ja-h.offset+m);a.keyFrames.sort(Ia)}},Z=function(a,b){for(var c=0,d=ia.length;d>c;c++){var e,f,i=ia[c],j=i.element,k=i.smoothScrolling?a:b,l=i.keyFrames,m=l.length,n=l[0],s=l[l.length-1],t=k
s.frame,v=t?n:s,w=i.emitEvents,x=i.lastFrameIndex;if(t||u){if(t&&-1===i.edge||u&&1===i.edge)continue;switch(t?(Ea(j,[p],[r,q]),w&&x>-1&&(za(j,n.eventType,La),i.lastFrameIndex=-1)):(Ea(j,[r],[p,q]),w&&m>x&&(za(j,s.eventType,La),i.lastFrameIndex=m)),i.edge=t?-1:1,i.edgeStrategy){case"reset":fa(j);continue;case"ease":k=v.frame;break;default:case"set":var y=v.props;for(e in y)h.call(y,e)&&(f=ea(y[e].value),0===e.indexOf("@")?j.setAttribute(e.substr(1),f):g.setStyle(j,e,f));continue}}else 0!==i.edge&&(Ea(j,[o,q],[p,r]),i.edge=0);for(var z=0;m-1>z;z++)if(k>=l[z].frame&&k<=l[z+1].frame){var A=l[z],B=l[z+1];for(e in A.props)if(h.call(A.props,e)){var C=(k-A.frame)/(B.frame-A.frame);C=A.props[e].easing(C),f=da(A.props[e].value,B.props[e].value,C),f=ea(f),0===e.indexOf("@")?j.setAttribute(e.substr(1),f):g.setStyle(j,e,f)}w&&x!==z&&("down"===La?za(j,A.eventType,La):za(j,B.eventType,La),i.lastFrameIndex=z);break}}},$=function(){Qa&&(Qa=!1,Aa());var a,b,d=ha.getScrollTop(),e=Ha();if(oa)e>=oa.endTime?(d=oa.targetTop,a=oa.done,oa=c):(b=oa.easing((e-oa.startTime)/oa.duration),d=oa.startTop+b*oa.topDiff|0),ha.setScrollTop(d,!0);else if(!sa){var f=ra.targetTop-d;f&&(ra={startTop:Ma,topDiff:d-Ma,targetTop:d,startTime:Na,endTime:Na+qa}),e<=ra.endTime&&(b=W.sqrt((e-ra.startTime)/qa),d=ra.startTop+b*ra.topDiff|0)}if(sa||Ma!==d){La=d>Ma?"down":Ma>d?"up":La,sa=!1;var h={curTop:d,lastTop:Ma,maxTop:Ja,direction:La},i=ka.beforerender&&ka.beforerender.call(ha,h);i!==!1&&(Z(d,ha.getScrollTop()),Sa&&ja&&g.setStyle(ja,"transform","translate(0, "+-Ta+"px) "+ua),Ma=d,ka.render&&ka.render.call(ha,h)),a&&a.call(ha,!1)}Na=e},_=function(a){for(var b=0,c=a.keyFrames.length;c>b;b++){for(var d,e,f,g,h=a.keyFrames[b],i={};null!==(g=J.exec(h.props));)f=g[1],e=g[2],d=f.match(K),null!==d?(f=d[1],d=d[2]):d=w,e=e.indexOf("!")?aa(e):[e.slice(1)],i[f]={value:e,easing:W[d]};h.props=i}},aa=function(a){var b=[];return P.lastIndex=0,a=a.replace(P,function(a){return a.replace(N,function(a){return a/255*100+"%"})}),S&&(Q.lastIndex=0,a=a.replace(Q,function(a){return S+a})),a=a.replace(N,function(a){return b.push(+a),"{?}"}),b.unshift(a),b},ba=function(a){var b,c,d={};for(b=0,c=a.keyFrames.length;c>b;b++)ca(a.keyFrames[b],d);for(d={},b=a.keyFrames.length-1;b>=0;b--)ca(a.keyFrames[b],d)},ca=function(a,b){var c;for(c in b)h.call(a.props,c)||(a.props[c]=b[c]);for(c in a.props)b[c]=a.props[c]},da=function(a,b,c){var d,e=a.length;if(e!==b.length)throw"Can't interpolate between \""+a[0]+'" and "'+b[0]+'"';var f=[a[0]];for(d=1;e>d;d++)f[d]=a[d]+(b[d]-a[d])*c;return f},ea=function(a){var b=1;return O.lastIndex=0,a[0].replace(O,function(){return a[b++]})},fa=function(a,b){a=[].concat(a);for(var c,d,e=0,f=a.length;f>e;e++)d=a[e],c=ia[d[F]],c&&(b?(d.style.cssText=c.dirtyStyleAttr,Ea(d,c.dirtyClassAttr)):(c.dirtyStyleAttr=d.style.cssText,c.dirtyClassAttr=Da(d),d.style.cssText=c.styleAttr,Ea(d,c.classAttr)))},ga=function(){ua="translateZ(0)",g.setStyle(ja,"transform",ua);var a=j(ja),b=a.getPropertyValue("transform"),c=a.getPropertyValue(S+"transform"),d=b&&"none"!==b||c&&"none"!==c;d||(ua="")};g.setStyle=function(a,b,c){var d=a.style;if(b=b.replace(L,M).replace("-",""),"zIndex"===b)isNaN(c)?d[b]=c:d[b]=""+(0|c);else if("float"===b)d.styleFloat=d.cssFloat=c;else try{R&&(d[R+b.slice(0,1).toUpperCase()+b.slice(1)]=c),d[b]=c}catch(e){}};var ha,ia,ja,ka,la,ma,na,oa,pa,qa,ra,sa,ta,ua,va,wa=g.addEvent=function(b,c,d){var e=function(b){return b=b||a.event,b.target||(b.target=b.srcElement),b.preventDefault||(b.preventDefault=function(){b.returnValue=!1,b.defaultPrevented=!0}),d.call(this,b)};c=c.split(" ");for(var f,g=0,h=c.length;h>g;g++)f=c[g],b.addEventListener?b.addEventListener(f,d,!1):b.attachEvent("on"+f,e),Ua.push({element:b,name:f,listener:d})},xa=g.removeEvent=function(a,b,c){b=b.split(" ");for(var d=0,e=b.length;e>d;d++)a.removeEventListener?a.removeEventListener(b[d],c,!1):a.detachEvent("on"+b[d],c)},ya=function(){for(var a,b=0,c=Ua.length;c>b;b++)a=Ua[b],xa(a.element,a.name,a.listener);Ua=[]},za=function(a,b,c){ka.keyframe&&ka.keyframe.call(ha,a,b,c)},Aa=function(){var a=ha.getScrollTop();Ja=0,la&&!Sa&&(f.style.height=""),Y(),la&&!Sa&&(f.style.height=Ja+e.clientHeight+"px"),Sa?ha.setScrollTop(i.min(ha.getScrollTop(),Ja)):ha.setScrollTop(a,!0),sa=!0},Ba=function(){var a,b,c=e.clientHeight,d={};for(a in ma)b=ma[a],"function"==typeof b?b=b.call(ha):/p$/.test(b)&&(b=b.slice(0,-1)/100*c),d[a]=b;return d},Ca=function(){var a,b=0;return ja&&(b=i.max(ja.offsetHeight,ja.scrollHeight)),a=i.max(b,f.scrollHeight,f.offsetHeight,e.scrollHeight,e.offsetHeight,e.clientHeight),a-e.clientHeight},Da=function(b){var c="className";return a.SVGElement&&b instanceof a.SVGElement&&(b=b[c],c="baseVal"),b[c]},Ea=function(b,d,e){var f="className";if(a.SVGElement&&b instanceof a.SVGElement&&(b=b[f],f="baseVal"),e===c)return void(b[f]=d);for(var g=b[f],h=0,i=e.length;i>h;h++)g=Ga(g).replace(Ga(e[h])," ");g=Fa(g);for(var j=0,k=d.length;k>j;j++)-1===Ga(g).indexOf(Ga(d[j]))&&(g+=" "+d[j]);b[f]=Fa(g)},Fa=function(a){return a.replace(H,"")},Ga=function(a){return" "+a+" "},Ha=Date.now||function(){return+new Date},Ia=function(a,b){return a.frame-b.frame},Ja=0,Ka=1,La="down",Ma=-1,Na=Ha(),Oa=0,Pa=0,Qa=!1,Ra=0,Sa=!1,Ta=0,Ua=[];"function"==typeof define&&define.amd?define([],function(){return g}):"undefined"!=typeof module&&module.exports?module.exports=g:a.skrollr=g}(window,document);
\ No newline at end of file
diff --git a/ungleich_page/static/ungleich_page/js/lib/wow.min.js b/ungleich_page/static/ungleich_page/js/lib/wow.min.js
new file mode 100755
index 0000000..25609b8
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/js/lib/wow.min.js
@@ -0,0 +1,2 @@
+/*! WOW - v1.1.2 - 2015-08-19
+* Copyright (c) 2015 Matthieu Aussaguel; Licensed MIT */(function(){var a,b,c,d,e,f=function(a,b){return function(){return a.apply(b,arguments)}},g=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1};b=function(){function a(){}return a.prototype.extend=function(a,b){var c,d;for(c in b)d=b[c],null==a[c]&&(a[c]=d);return a},a.prototype.isMobile=function(a){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(a)},a.prototype.createEvent=function(a,b,c,d){var e;return null==b&&(b=!1),null==c&&(c=!1),null==d&&(d=null),null!=document.createEvent?(e=document.createEvent("CustomEvent"),e.initCustomEvent(a,b,c,d)):null!=document.createEventObject?(e=document.createEventObject(),e.eventType=a):e.eventName=a,e},a.prototype.emitEvent=function(a,b){return null!=a.dispatchEvent?a.dispatchEvent(b):b in(null!=a)?a[b]():"on"+b in(null!=a)?a["on"+b]():void 0},a.prototype.addEvent=function(a,b,c){return null!=a.addEventListener?a.addEventListener(b,c,!1):null!=a.attachEvent?a.attachEvent("on"+b,c):a[b]=c},a.prototype.removeEvent=function(a,b,c){return null!=a.removeEventListener?a.removeEventListener(b,c,!1):null!=a.detachEvent?a.detachEvent("on"+b,c):delete a[b]},a.prototype.innerHeight=function(){return"innerHeight"in window?window.innerHeight:document.documentElement.clientHeight},a}(),c=this.WeakMap||this.MozWeakMap||(c=function(){function a(){this.keys=[],this.values=[]}return a.prototype.get=function(a){var b,c,d,e,f;for(f=this.keys,b=d=0,e=f.length;e>d;b=++d)if(c=f[b],c===a)return this.values[b]},a.prototype.set=function(a,b){var c,d,e,f,g;for(g=this.keys,c=e=0,f=g.length;f>e;c=++e)if(d=g[c],d===a)return void(this.values[c]=b);return this.keys.push(a),this.values.push(b)},a}()),a=this.MutationObserver||this.WebkitMutationObserver||this.MozMutationObserver||(a=function(){function a(){"undefined"!=typeof console&&null!==console&&console.warn("MutationObserver is not supported by your browser."),"undefined"!=typeof console&&null!==console&&console.warn("WOW.js cannot detect dom mutations, please call .sync() after loading new content.")}return a.notSupported=!0,a.prototype.observe=function(){},a}()),d=this.getComputedStyle||function(a){return this.getPropertyValue=function(b){var c;return"float"===b&&(b="styleFloat"),e.test(b)&&b.replace(e,function(a,b){return b.toUpperCase()}),(null!=(c=a.currentStyle)?c[b]:void 0)||null},this},e=/(\-([a-z]){1})/g,this.WOW=function(){function e(a){null==a&&(a={}),this.scrollCallback=f(this.scrollCallback,this),this.scrollHandler=f(this.scrollHandler,this),this.resetAnimation=f(this.resetAnimation,this),this.start=f(this.start,this),this.scrolled=!0,this.config=this.util().extend(a,this.defaults),null!=a.scrollContainer&&(this.config.scrollContainer=document.querySelector(a.scrollContainer)),this.animationNameCache=new c,this.wowEvent=this.util().createEvent(this.config.boxClass)}return e.prototype.defaults={boxClass:"wow",animateClass:"animated",offset:0,mobile:!0,live:!0,callback:null,scrollContainer:null},e.prototype.init=function(){var a;return this.element=window.document.documentElement,"interactive"===(a=document.readyState)||"complete"===a?this.start():this.util().addEvent(document,"DOMContentLoaded",this.start),this.finished=[]},e.prototype.start=function(){var b,c,d,e;if(this.stopped=!1,this.boxes=function(){var a,c,d,e;for(d=this.element.querySelectorAll("."+this.config.boxClass),e=[],a=0,c=d.length;c>a;a++)b=d[a],e.push(b);return e}.call(this),this.all=function(){var a,c,d,e;for(d=this.boxes,e=[],a=0,c=d.length;c>a;a++)b=d[a],e.push(b);return e}.call(this),this.boxes.length)if(this.disabled())this.resetStyle();else for(e=this.boxes,c=0,d=e.length;d>c;c++)b=e[c],this.applyStyle(b,!0);return this.disabled()||(this.util().addEvent(this.config.scrollContainer||window,"scroll",this.scrollHandler),this.util().addEvent(window,"resize",this.scrollHandler),this.interval=setInterval(this.scrollCallback,50)),this.config.live?new a(function(a){return function(b){var c,d,e,f,g;for(g=[],c=0,d=b.length;d>c;c++)f=b[c],g.push(function(){var a,b,c,d;for(c=f.addedNodes||[],d=[],a=0,b=c.length;b>a;a++)e=c[a],d.push(this.doSync(e));return d}.call(a));return g}}(this)).observe(document.body,{childList:!0,subtree:!0}):void 0},e.prototype.stop=function(){return this.stopped=!0,this.util().removeEvent(this.config.scrollContainer||window,"scroll",this.scrollHandler),this.util().removeEvent(window,"resize",this.scrollHandler),null!=this.interval?clearInterval(this.interval):void 0},e.prototype.sync=function(){return a.notSupported?this.doSync(this.element):void 0},e.prototype.doSync=function(a){var b,c,d,e,f;if(null==a&&(a=this.element),1===a.nodeType){for(a=a.parentNode||a,e=a.querySelectorAll("."+this.config.boxClass),f=[],c=0,d=e.length;d>c;c++)b=e[c],g.call(this.all,b)<0?(this.boxes.push(b),this.all.push(b),this.stopped||this.disabled()?this.resetStyle():this.applyStyle(b,!0),f.push(this.scrolled=!0)):f.push(void 0);return f}},e.prototype.show=function(a){return this.applyStyle(a),a.className=a.className+" "+this.config.animateClass,null!=this.config.callback&&this.config.callback(a),this.util().emitEvent(a,this.wowEvent),this.util().addEvent(a,"animationend",this.resetAnimation),this.util().addEvent(a,"oanimationend",this.resetAnimation),this.util().addEvent(a,"webkitAnimationEnd",this.resetAnimation),this.util().addEvent(a,"MSAnimationEnd",this.resetAnimation),a},e.prototype.applyStyle=function(a,b){var c,d,e;return d=a.getAttribute("data-wow-duration"),c=a.getAttribute("data-wow-delay"),e=a.getAttribute("data-wow-iteration"),this.animate(function(f){return function(){return f.customStyle(a,b,d,c,e)}}(this))},e.prototype.animate=function(){return"requestAnimationFrame"in window?function(a){return window.requestAnimationFrame(a)}:function(a){return a()}}(),e.prototype.resetStyle=function(){var a,b,c,d,e;for(d=this.boxes,e=[],b=0,c=d.length;c>b;b++)a=d[b],e.push(a.style.visibility="visible");return e},e.prototype.resetAnimation=function(a){var b;return a.type.toLowerCase().indexOf("animationend")>=0?(b=a.target||a.srcElement,b.className=b.className.replace(this.config.animateClass,"").trim()):void 0},e.prototype.customStyle=function(a,b,c,d,e){return b&&this.cacheAnimationName(a),a.style.visibility=b?"hidden":"visible",c&&this.vendorSet(a.style,{animationDuration:c}),d&&this.vendorSet(a.style,{animationDelay:d}),e&&this.vendorSet(a.style,{animationIterationCount:e}),this.vendorSet(a.style,{animationName:b?"none":this.cachedAnimationName(a)}),a},e.prototype.vendors=["moz","webkit"],e.prototype.vendorSet=function(a,b){var c,d,e,f;d=[];for(c in b)e=b[c],a[""+c]=e,d.push(function(){var b,d,g,h;for(g=this.vendors,h=[],b=0,d=g.length;d>b;b++)f=g[b],h.push(a[""+f+c.charAt(0).toUpperCase()+c.substr(1)]=e);return h}.call(this));return d},e.prototype.vendorCSS=function(a,b){var c,e,f,g,h,i;for(h=d(a),g=h.getPropertyCSSValue(b),f=this.vendors,c=0,e=f.length;e>c;c++)i=f[c],g=g||h.getPropertyCSSValue("-"+i+"-"+b);return g},e.prototype.animationName=function(a){var b;try{b=this.vendorCSS(a,"animation-name").cssText}catch(c){b=d(a).getPropertyValue("animation-name")}return"none"===b?"":b},e.prototype.cacheAnimationName=function(a){return this.animationNameCache.set(a,this.animationName(a))},e.prototype.cachedAnimationName=function(a){return this.animationNameCache.get(a)},e.prototype.scrollHandler=function(){return this.scrolled=!0},e.prototype.scrollCallback=function(){var a;return!this.scrolled||(this.scrolled=!1,this.boxes=function(){var b,c,d,e;for(d=this.boxes,e=[],b=0,c=d.length;c>b;b++)a=d[b],a&&(this.isVisible(a)?this.show(a):e.push(a));return e}.call(this),this.boxes.length||this.config.live)?void 0:this.stop()},e.prototype.offsetTop=function(a){for(var b;void 0===a.offsetTop;)a=a.parentNode;for(b=a.offsetTop;a=a.offsetParent;)b+=a.offsetTop;return b},e.prototype.isVisible=function(a){var b,c,d,e,f;return c=a.getAttribute("data-wow-offset")||this.config.offset,f=this.config.scrollContainer&&this.config.scrollContainer.scrollTop||window.pageYOffset,e=f+Math.min(this.element.clientHeight,this.util().innerHeight())-c,d=this.offsetTop(a),b=d+a.clientHeight,e>=d&&b>=f},e.prototype.util=function(){return null!=this._util?this._util:this._util=new b},e.prototype.disabled=function(){return!this.config.mobile&&this.util().isMobile(navigator.userAgent)},e}()}).call(this);
\ No newline at end of file
diff --git a/ungleich_page/static/ungleich_page/js/ungleich.js b/ungleich_page/static/ungleich_page/js/ungleich.js
new file mode 100755
index 0000000..d2121bc
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/js/ungleich.js
@@ -0,0 +1,44 @@
+/* globals $, WOW */
+
+$(function(){
+ new WOW().init();
+ $('.img-toggle').one('mouseenter', toggleImage);
+});
+
+function toggleImage(e) {
+ var $this = $(this),
+ toggle_img = $this.attr('data-replaced'),
+ current_img = $this.attr('src');
+ $this.fadeOut(200, function() {
+ $this.attr('src', toggle_img);
+ $this.attr('data-replaced', current_img);
+ $this.fadeIn(300);
+ });
+};
+
+/*!
+ * Start Bootstrap - Agnecy Bootstrap Theme (http://startbootstrap.com)
+ * Code licensed under the Apache License v2.0.
+ * For details, see http://www.apache.org/licenses/LICENSE-2.0.
+ */
+
+// jQuery for page scrolling feature - requires jQuery Easing plugin
+$(function() {
+ $('a.page-scroll').bind('click', function(event) {
+ var $anchor = $(this);
+ $('html, body').stop().animate({
+ scrollTop: $($anchor.attr('href')).offset().top
+ }, 1500, 'easeInOutExpo');
+ event.preventDefault();
+ });
+});
+
+// Highlight the top nav as scrolling occurs
+$('body').scrollspy({
+ target: '.navbar-fixed-top'
+})
+
+// Closes the Responsive Menu on Menu Item Click
+$('.navbar-collapse ul li a').click(function() {
+ $('.navbar-toggle:visible').click();
+});
diff --git a/ungleich_page/static/ungleich_page/less/agency.less b/ungleich_page/static/ungleich_page/less/agency.less
new file mode 100755
index 0000000..f4610fa
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/less/agency.less
@@ -0,0 +1,724 @@
+@import "variables.less";
+@import "mixins.less";
+
+// Global Components
+
+body {
+ overflow-x: hidden;
+ .body-font;
+}
+
+.text-muted {
+ color: @gray;
+}
+
+.text-primary {
+ color: @brand-primary;
+}
+
+p {
+ font-size: 14px;
+ line-height: 1.75;
+}
+
+p.large {
+ font-size: 16px;
+}
+
+a,
+a:hover,
+a:focus,
+a:active,
+a.active {
+ outline: none;
+}
+
+a {
+ color: @brand-primary;
+}
+
+a:hover,
+a:focus,
+a:active,
+a.active {
+ color: darken(@brand-primary, 10%);
+}
+
+h1, h2, h3, h4, h5, h6 {
+ .heading-font;
+ font-weight: 700;
+}
+
+.img-centered {
+ margin: 0 auto;
+}
+
+.bg-light-gray {
+ background-color: @gray-lighter;
+}
+
+.bg-darkest-gray {
+ background-color: @gray-darkest;
+}
+
+// Restyled Primary Buttons
+
+.btn-primary {
+ .button-variant(white; @brand-primary; @brand-primary);
+ .heading-font;
+ font-weight: 700;
+}
+
+.btn-xl {
+ .button-variant(white; @brand-primary; @brand-primary);
+ .heading-font;
+ font-weight: 700;
+ border-radius: 3px;
+ font-size: 18px;
+ padding: 20px 40px;
+}
+
+// Custom Navigation Bar
+
+.navbar-default {
+ background-color: @gray-darkest;
+ border-color: transparent;
+ .navbar-brand {
+ color: @brand-primary;
+ .script-font;
+ &:hover,
+ &:focus,
+ &:active,
+ &.active {
+ color: darken(@brand-primary, 10%);
+ }
+ }
+ .navbar-collapse {
+ border-color: fade(white, 2%);
+ }
+ .navbar-toggle {
+ background-color: @brand-primary;
+ border-color: @brand-primary;
+ .icon-bar {
+ background-color: white;
+ }
+ &:hover,
+ &:focus {
+ background-color: @brand-primary;
+ }
+ }
+ .nav {
+ li {
+ a {
+ .heading-font;
+ font-weight: 400;
+ letter-spacing: 1px;
+ color: white;
+ &:hover,
+ &:focus {
+ color: @brand-primary;
+ outline: none;
+ }
+ }
+ }
+ }
+ .navbar-nav>.active>a {
+ border-radius: 0;
+ color: white;
+ background-color: @brand-primary;
+ }
+ .navbar-nav>.active>a:hover,
+ .navbar-nav>.active>a:focus {
+ color: white;
+ background-color: darken(@brand-primary, 10%);
+ }
+}
+
+@media(min-width:768px) {
+ .navbar-default {
+ background-color: transparent;
+ padding: 25px 0;
+ -webkit-transition: padding 0.3s;
+ -moz-transition: padding 0.3s;
+ transition: padding 0.3s;
+ border: none;
+ .navbar-brand {
+ font-size: 2em;
+ -webkit-transition: all 0.3s;
+ -moz-transition: all 0.3s;
+ transition: all 0.3s;
+ }
+ .navbar-nav>.active>a {
+ border-radius: 3px;
+ }
+ }
+ .navbar-default.navbar-shrink {
+ background-color: @gray-darkest;
+ padding: 10px 0;
+ .navbar-brand {
+ font-size: 1.5em;
+ }
+ }
+}
+
+header {
+ background-image: url('../img/header-bg.jpg');
+ background-repeat: none;
+ background-attachment: scroll;
+ background-position: center center;
+ .background-cover;
+ text-align: center;
+ color: white;
+ .intro-text {
+ padding-top: 100px;
+ padding-bottom: 50px;
+ .intro-lead-in {
+ .serif-font;
+ font-style: italic;
+ font-size: 22px;
+ line-height: 22px;
+ margin-bottom: 25px;
+ }
+ .intro-heading {
+ .heading-font;
+ font-weight: 700;
+ font-size: 50px;
+ line-height: 50px;
+ margin-bottom: 25px;
+ }
+ }
+}
+
+@media(min-width:768px) {
+ header {
+ .intro-text {
+ padding-top: 300px;
+ padding-bottom: 200px;
+ .intro-lead-in {
+ .serif-font;
+ font-style: italic;
+ font-size: 40px;
+ line-height: 40px;
+ margin-bottom: 25px;
+ }
+ .intro-heading {
+ .heading-font;
+ font-weight: 700;
+ font-size: 75px;
+ line-height: 75px;
+ margin-bottom: 50px;
+ }
+ }
+ }
+}
+
+// Global Section Styles
+
+section {
+ padding: 100px 0;
+ h2.section-heading {
+ font-size: 40px;
+ margin-top: 0;
+ margin-bottom: 15px;
+ }
+ h3.section-subheading {
+ font-size: 16px;
+ .serif-font;
+ text-transform: none;
+ font-style: italic;
+ font-weight: 400;
+ margin-bottom: 75px;
+ }
+}
+
+@media(min-width:768px) {
+ section {
+ padding: 150px 0;
+ }
+}
+
+// Services Section
+
+.service-heading {
+ margin: 15px 0;
+ text-transform: none;
+}
+
+// Portfolio Section
+
+#portfolio {
+ .portfolio-item {
+ margin: 0 0 15px;
+ right: 0;
+ .portfolio-link {
+ display: block;
+ position: relative;
+ max-width: 400px;
+ margin: 0 auto;
+ .portfolio-hover {
+ background: fade(@brand-primary, 90%);
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ opacity: 0;
+ transition: all ease 0.5s;
+ -webkit-transition: all ease 0.5s;
+ -moz-transition: all ease 0.5s;
+ &:hover {
+ opacity: 1;
+ }
+ .portfolio-hover-content {
+ position: absolute;
+ width: 100%;
+ height: 20px;
+ font-size: 20px;
+ text-align: center;
+ top: 50%;
+ margin-top: -12px;
+ color: white;
+ i {
+ margin-top: -12px;
+ }
+ h3,
+ h4 {
+ margin: 0;
+ }
+ }
+ }
+ }
+ .portfolio-caption {
+ max-width: 400px;
+ margin: 0 auto;
+ background-color: white;
+ text-align: center;
+ padding: 25px;
+ h4 {
+ text-transform: none;
+ margin: 0;
+ }
+ p {
+ .serif-font;
+ font-style: italic;
+ font-size: 16px;
+ margin: 0;
+ }
+ }
+ }
+ * {
+ z-index: 2;
+ }
+}
+
+@media(min-width:767px) {
+ #portfolio {
+ .portfolio-item {
+ margin: 0 0 30px;
+ }
+ }
+}
+
+// Timeline
+
+.timeline {
+ list-style: none;
+ padding: 0;
+ position: relative;
+ &:before {
+ top: 0;
+ bottom: 0;
+ position: absolute;
+ content: "";
+ width: 2px;
+ background-color: #f1f1f1;
+ left: 40px;
+ margin-left: -1.5px;
+ }
+ > li {
+ margin-bottom: 50px;
+ position: relative;
+ min-height: 50px;
+ &:before,
+ &:after {
+ content: " ";
+ display: table;
+ }
+ &:after {
+ clear: both;
+ }
+ .timeline-panel {
+ width: 100%;
+ float: right;
+ padding: 0 20px 0 100px;
+ position: relative;
+ text-align: left;
+ &:before {
+ border-left-width: 0;
+ border-right-width: 15px;
+ left: -15px;
+ right: auto;
+ }
+ &:after {
+ border-left-width: 0;
+ border-right-width: 14px;
+ left: -14px;
+ right: auto;
+ }
+ }
+ .timeline-image {
+ left: 0;
+ margin-left: 0;
+ width: 80px;
+ height: 80px;
+ position: absolute;
+ z-index: 100;
+ background-color: @brand-primary;
+ color: white;
+ border-radius: 100%;
+ border: 7px solid #f1f1f1;
+ text-align: center;
+ h4 {
+ font-size: 10px;
+ margin-top: 12px;
+ line-height: 14px;
+ }
+ }
+ &.timeline-inverted > .timeline-panel {
+ float: right;
+ text-align: left;
+ padding: 0 20px 0 100px;
+ &:before {
+ border-left-width: 0;
+ border-right-width: 15px;
+ left: -15px;
+ right: auto;
+ }
+ &:after {
+ border-left-width: 0;
+ border-right-width: 14px;
+ left: -14px;
+ right: auto;
+ }
+ }
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+ .timeline-heading {
+ h4 {
+ margin-top: 0;
+ color: inherit;
+ &.subheading {
+ text-transform: none;
+ }
+ }
+ }
+ .timeline-body {
+ > p,
+ > ul {
+ margin-bottom: 0;
+ }
+ }
+}
+
+@media(min-width:768px) {
+ .timeline {
+ &:before {
+ left: 50%;
+ }
+ > li {
+ margin-bottom: 100px;
+ min-height: 100px;
+ .timeline-panel {
+ width: 41%;
+ float: left;
+ padding: 0 20px 20px 30px;
+ text-align: right;
+ }
+ .timeline-image {
+ width: 100px;
+ height: 100px;
+ left: 50%;
+ margin-left: -50px;
+ h4 {
+ font-size: 13px;
+ margin-top: 16px;
+ line-height: 18px;
+ }
+ }
+ &.timeline-inverted > .timeline-panel {
+ float: right;
+ text-align: left;
+ padding: 0 30px 20px 20px;
+ }
+ }
+ }
+}
+
+@media(min-width:992px) {
+ .timeline {
+ > li {
+ min-height: 150px;
+ .timeline-panel {
+ padding: 0 20px 20px;
+ }
+ .timeline-image {
+ width: 150px;
+ height: 150px;
+ margin-left: -75px;
+ h4 {
+ font-size: 18px;
+ margin-top: 30px;
+ line-height: 26px;
+ }
+ }
+ &.timeline-inverted > .timeline-panel {
+ padding: 0 20px 20px;
+ }
+ }
+ }
+}
+
+@media(min-width:1200px) {
+ .timeline {
+ > li {
+ min-height: 170px;
+ .timeline-panel {
+ padding: 0 20px 20px 100px;
+ }
+ .timeline-image {
+ width: 170px;
+ height: 170px;
+ margin-left: -85px;
+ h4 {
+ margin-top: 40px;
+ }
+ }
+ &.timeline-inverted > .timeline-panel {
+ padding: 0 100px 20px 20px;
+ }
+ }
+ }
+}
+
+// Team Section
+
+.team-member {
+ text-align: center;
+ margin-bottom: 50px;
+ img {
+ margin: 0 auto;
+ border: 7px solid white;
+ }
+ h4 {
+ margin-top: 25px;
+ margin-bottom: 0;
+ text-transform: none;
+ }
+ p {
+ margin-top: 0;
+ }
+}
+
+// Clients Aside
+
+aside.clients {
+ img {
+ margin: 50px auto;
+ }
+}
+
+// Contact Section
+
+section#contact {
+ background-color: @gray-darkest;
+ background-image: url('../img/map-image.png');
+ background-position: center;
+ background-repeat: no-repeat;
+ .section-heading {
+ color: white;
+ }
+ .form-group {
+ margin-bottom: 25px;
+ input,
+ textarea {
+ padding: 20px;
+ }
+ input.form-control {
+ height: auto;
+ }
+ textarea.form-control {
+ height: 236px;
+ }
+ }
+ .form-control:focus {
+ border-color: @brand-primary;
+ box-shadow: none;
+ }
+ ::-webkit-input-placeholder {
+ .heading-font;
+ font-weight: 700;
+ color: @placeholder-text;
+ }
+ :-moz-placeholder { /* Firefox 18- */
+ .heading-font;
+ font-weight: 700;
+ color: @placeholder-text;
+ }
+ ::-moz-placeholder { /* Firefox 19+ */
+ .heading-font;
+ font-weight: 700;
+ color: @placeholder-text;
+ }
+ :-ms-input-placeholder {
+ .heading-font;
+ font-weight: 700;
+ color: @placeholder-text;
+ }
+ .text-danger {
+ color: @brand-danger;
+ }
+}
+
+// Footer
+
+footer {
+ padding: 25px 0;
+ text-align: center;
+ span.copyright {
+ line-height: 40px;
+ .heading-font;
+ text-transform: none;
+ }
+ ul.quicklinks {
+ margin-bottom: 0;
+ line-height: 40px;
+ .heading-font;
+ text-transform: none;
+ }
+}
+
+// Social Buttons
+
+ul.social-buttons {
+ margin-bottom: 0;
+ li {
+ a {
+ display: block;
+ background-color: @gray-darkest;
+ height: 40px;
+ width: 40px;
+ border-radius: 100%;
+ font-size: 20px;
+ line-height: 40px;
+ color: white;
+ outline: none;
+ -webkit-transition: all 0.3s;
+ -moz-transition: all 0.3s;
+ transition: all 0.3s;
+ &:hover,
+ &:focus,
+ &:active {
+ background-color: @brand-primary;
+ }
+ }
+ }
+}
+
+.btn:focus,
+.btn:active,
+.btn.active,
+.btn:active:focus {
+ outline: none;
+}
+
+.portfolio-modal {
+ .modal-content {
+ border-radius: 0;
+ background-clip: border-box;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ border: none;
+ min-height: 100%;
+ padding: 100px 0;
+ text-align: center;
+ h2 {
+ margin-bottom: 15px;
+ font-size: 3em;
+ }
+ p {
+ margin-bottom: 30px;
+ }
+ p.item-intro {
+ margin: 20px 0 30px;
+ .serif-font;
+ font-style: italic;
+ font-size: 16px;
+ }
+ ul.list-inline {
+ margin-bottom: 30px;
+ margin-top: 0;
+ }
+ img {
+ margin-bottom: 30px;
+ }
+ }
+ .close-modal {
+ position: absolute;
+ width:75px;
+ height:75px;
+ background-color:transparent;
+ top: 25px;
+ right: 25px;
+ cursor: pointer;
+ &:hover {
+ opacity: 0.3;
+ }
+ .lr {
+ height:75px;
+ width:1px;
+ margin-left:35px;
+ background-color:@gray-darkest;
+ transform: rotate(45deg);
+ -ms-transform: rotate(45deg);
+ /* IE 9 */
+ -webkit-transform: rotate(45deg);
+ /* Safari and Chrome */
+ z-index:1051;
+ .rl {
+ height:75px;
+ width:1px;
+ background-color:@gray-darkest;
+ transform: rotate(90deg);
+ -ms-transform: rotate(90deg);
+ /* IE 9 */
+ -webkit-transform: rotate(90deg);
+ /* Safari and Chrome */
+ z-index:1052;
+ }
+ }
+ }
+}
+
+// Highlight Color Customization
+
+::-moz-selection {
+ text-shadow: none;
+ background: @brand-primary;
+}
+
+::selection {
+ text-shadow: none;
+ background: @brand-primary;
+}
+
+img::selection {
+ background: transparent;
+}
+
+img::-moz-selection {
+ background: transparent;
+}
+
+body {
+ webkit-tap-highlight-color: @brand-primary;
+}
\ No newline at end of file
diff --git a/ungleich_page/static/ungleich_page/less/mixins.less b/ungleich_page/static/ungleich_page/less/mixins.less
new file mode 100755
index 0000000..8a28d48
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/less/mixins.less
@@ -0,0 +1,67 @@
+// Bootstrap Button Variant
+
+.button-variant(@color; @background; @border) {
+ color: @color;
+ background-color: @background;
+ border-color: @border;
+
+ &:hover,
+ &:focus,
+ &:active,
+ &.active,
+ .open .dropdown-toggle& {
+ color: @color;
+ background-color: darken(@background, 10%);
+ border-color: darken(@border, 12%);
+ }
+ &:active,
+ &.active,
+ .open .dropdown-toggle& {
+ background-image: none;
+ }
+ &.disabled,
+ &[disabled],
+ fieldset[disabled] & {
+ &,
+ &:hover,
+ &:focus,
+ &:active,
+ &.active {
+ background-color: @background;
+ border-color: @border;
+ }
+ }
+
+ .badge {
+ color: @background;
+ background-color: @color;
+ }
+}
+
+// Background Features
+
+.background-cover() {
+ -webkit-background-size: cover;
+ -moz-background-size: cover;
+ background-size: cover;
+ -o-background-size: cover;
+}
+
+// Font Selections
+
+.serif-font() {
+ font-family: "Droid Serif", "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+
+.script-font() {
+ font-family: "Kaushan Script", "Helvetica Neue", Helvetica, Arial, cursive;
+}
+
+.body-font() {
+ font-family: "Roboto Slab", "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+
+.heading-font() {
+ font-family: "Montserrat", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ text-transform: uppercase;
+}
diff --git a/ungleich_page/static/ungleich_page/less/variables.less b/ungleich_page/static/ungleich_page/less/variables.less
new file mode 100755
index 0000000..cff8406
--- /dev/null
+++ b/ungleich_page/static/ungleich_page/less/variables.less
@@ -0,0 +1,8 @@
+// Variables
+
+@brand-primary: #fed136;
+@brand-danger: #e74c3c;
+@gray-darkest: #222;
+@gray: #777;
+@gray-lighter: #f7f7f7;
+@placeholder-text: #bbbbbb;
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/404.html b/ungleich_page/templates/ungleich_page/404.html
new file mode 100755
index 0000000..ddcdaaa
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/404.html
@@ -0,0 +1,53 @@
+{% load static i18n %}
+
+
+
+
+
+
+
+
+
+
+
+ Page not found | ungleich
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
404
+
+ {% trans '"Sorry, we could not find the page you are looking for!"' %}
+
+
+
+
+
+
+
+
+
+
diff --git a/ungleich_page/templates/ungleich_page/_footer.html b/ungleich_page/templates/ungleich_page/_footer.html
new file mode 100755
index 0000000..f03fc2b
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/_footer.html
@@ -0,0 +1,40 @@
+{% load cms_tags %}
+
+
+
+
+
+
+
+
+ {% static_placeholder "footer_copyright" %}
+
+
+
+
+
diff --git a/ungleich_page/templates/ungleich_page/_header_base.html b/ungleich_page/templates/ungleich_page/_header_base.html
new file mode 100755
index 0000000..5674d5e
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/_header_base.html
@@ -0,0 +1,17 @@
+{% load cms_tags static %}
+
+
+
diff --git a/ungleich_page/templates/ungleich_page/_menu.html b/ungleich_page/templates/ungleich_page/_menu.html
new file mode 100755
index 0000000..3a6ae38
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/_menu.html
@@ -0,0 +1,36 @@
+{% load menu_tags static cms_tags %}
+
+
+
+
+
+
+
+
+
+ {% for child in children %}
+
+ {{ child.get_menu_title }}
+ {% if child.children %}
+
+ {% show_menu from_level to_level extra_inactive extra_active template "" "" child %}
+
+ {% endif %}
+
+ {% endfor %}
+
+
+
+
+
+
diff --git a/ungleich_page/templates/ungleich_page/glasfaser.html b/ungleich_page/templates/ungleich_page/glasfaser.html
new file mode 100755
index 0000000..a2e2c33
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/glasfaser.html
@@ -0,0 +1,322 @@
+{% load static bootstrap3 i18n %}
+{% get_current_language as LANGUAGE_CODE %}
+
+
+
+
+
+
+
+
+
+
+
+
ungleich GmbH
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% include "google_analytics.html" %}
+
+
+
+
+
+
+ {% include "gdpr_banner.html" %}
+
+
+
+
+
+
+
+
+
+
+
+
Unser Glasfaser-Angebot für Glarus Nord, Glarus und Glarus Süd
+
+
+
Surfen Sie mit 100 Mbit/s im Internet!
+
Mit dem neuen Glasfaser-Angebot der ungleich macht das Arbeiten im Internet richtig Spass. Das beste daran: die Geschwindigkeit ist symmetrisch in beide Richtungen verfügbar. Damit kann Ihr Firmennetzwerk auch Dienste bereitstellen.
+
Dieses Angebot ist im Moment ausschliesslich für Firmenkunden verfügbar. Die Aufschaltkosten der Glasfaserleitung sind von der Entfernung zum nächsten Anschlusspunkt abhängig. Fragen Sie noch heute nach einem individuellem Angebot. Gerne stellen wir Ihnen eine persönliche Offerte zusammen.
+
+
+
+
+
+
+
+
+
Was ist es?
+
+
+
Bei diesem Angebot handelt es sich um einen Internetzugang für Firmenkunden.
+
Sie erhalten in Zusammenarbeit mit unseren Partnern einen Glasfaseranschluss und eine Internetverbindung.
+
+
+
+
+
+
+
+
+
Technische Details
+ Im Angebot enthalten sind
+
+
+
+
+
+
+
Business-Internet
+
Symmetrische Internetleitung 100 Mbit/s upload und 100 Mbit/s download
+
Glasfaser-Installation bis ins Haus (keine Hausverkabelung)
+
+
+
+
+
+
+
+
Erreichbarkeit im Internet
+
1 öffentliches IPv6-Netzwerk (/64)
+
1 öffentliche IPv4-Adresse
+
+
+
+
+
+
+
+
Einfach zu nutzen
+
2 bereits für Sie konfigurierte Endgeräte (benötigt zwei Ihrer Steckdosen)
+
Einfach einstecken und los!
+
+
+
+
+
+
+
+
+
+
+
+
Wie funktioniert es?
+ So kommen Sie in wenigen einfachen Schritten zu Ihrem High-Speed-Internet
+
+
+
+
+
+
+
+
+
+
+
Senden Sie uns via E-Mail Ihren Firmennamen und Ihre Anschrift zu.
+
+
+
+
+
+
+
+
+
+
Wir prüfen dann die Entfernung zum nächsten Anschlusspunkt und schicken Ihnen eine Offerte zu.
+
+
+
+
+
+
+
+
+
+
Sollten Sie dem Angebot zustimmen, wird die Glasfaser zu Ihrem Standort verlegt und die Endgeräte installiert.
+
+
+
+
+
+
+
+
+
+
Sie müssen dann nur noch Ihre Geräte anschliessen und schon surfen Sie blitzschnell im Internet!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% include "ungleich_page/includes/_footer.html" %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ungleich_page/templates/ungleich_page/glasfaser/_about_item.html b/ungleich_page/templates/ungleich_page/glasfaser/_about_item.html
new file mode 100755
index 0000000..6b61957
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/glasfaser/_about_item.html
@@ -0,0 +1,12 @@
+
+ {% if instance.link_url %}{% endif %}
+
+
+
+ {% if instance.link_url %} {% endif %}
+
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/glasfaser/_services_item.html b/ungleich_page/templates/ungleich_page/glasfaser/_services_item.html
new file mode 100755
index 0000000..47bd4eb
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/glasfaser/_services_item.html
@@ -0,0 +1,7 @@
+
+
+
+
{{ instance.title }}
+
{{ instance.description }}
+
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/glasfaser/menus.html b/ungleich_page/templates/ungleich_page/glasfaser/menus.html
new file mode 100755
index 0000000..aa5d8ab
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/glasfaser/menus.html
@@ -0,0 +1,12 @@
+{% load menu_tags %}
+
+{% for child in children %}
+
+ {{ child.get_menu_title }}
+ {% if child.children %}
+
+ {% show_menu from_level to_level extra_inactive extra_active template "" "" child %}
+
+ {% endif %}
+
+{% endfor %}
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/glasfaser/section_about.html b/ungleich_page/templates/ungleich_page/glasfaser/section_about.html
new file mode 100755
index 0000000..f3fcffe
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/glasfaser/section_about.html
@@ -0,0 +1,18 @@
+{% load cms_tags %}
+
+
+
+
{{ about_instance.title }}
+ {{ about_instance.sub_title }}
+
+
+
+
+ {% for plugin in about_instance.child_plugin_instances %}
+ {% render_plugin plugin %}
+ {% endfor %}
+
+
+
+
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/glasfaser/section_contact.html b/ungleich_page/templates/ungleich_page/glasfaser/section_contact.html
new file mode 100755
index 0000000..4bf03d9
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/glasfaser/section_contact.html
@@ -0,0 +1,83 @@
+{% load i18n %}
+
+
+
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/glasfaser/section_services.html b/ungleich_page/templates/ungleich_page/glasfaser/section_services.html
new file mode 100755
index 0000000..c883cb1
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/glasfaser/section_services.html
@@ -0,0 +1,16 @@
+{% load static i18n cms_tags %}
+
+
+
+
{{ service_instance.title }}
+ {{ service_instance.sub_title }}
+
+
+ {% for plugin in service_instance.child_plugin_instances %}
+
+ {% render_plugin plugin %}
+
+ {% endfor %}
+
+
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/glasfaser/section_text_dcl.html b/ungleich_page/templates/ungleich_page/glasfaser/section_text_dcl.html
new file mode 100755
index 0000000..e45504f
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/glasfaser/section_text_dcl.html
@@ -0,0 +1,12 @@
+
+
+
+
+
{{instance.title}}
+
+
+
{{instance.description}}
+
+
+
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/glasfaser/section_text_glasfaser.html b/ungleich_page/templates/ungleich_page/glasfaser/section_text_glasfaser.html
new file mode 100755
index 0000000..06b0e26
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/glasfaser/section_text_glasfaser.html
@@ -0,0 +1,12 @@
+
+
+
+
+
{{instance.title}}
+
+
+
{{instance.description}}
+
+
+
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/glasfaser/section_with_image.html b/ungleich_page/templates/ungleich_page/glasfaser/section_with_image.html
new file mode 100755
index 0000000..20090fa
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/glasfaser/section_with_image.html
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/glasfaser_cms_page.html b/ungleich_page/templates/ungleich_page/glasfaser_cms_page.html
new file mode 100755
index 0000000..57d266c
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/glasfaser_cms_page.html
@@ -0,0 +1,108 @@
+{% load static bootstrap3 i18n cms_tags sekizai_tags menu_tags %}
+{% get_current_language as LANGUAGE_CODE %}
+
+
+
+
+
+
+
+
+
+
{% page_attribute "page_title" %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% addtoblock "css" %}
+
+ {% endaddtoblock %}
+ {% render_block "css" postprocessor "compressor.contrib.sekizai.compress" %}
+ {% render_block "js" postprocessor "compressor.contrib.sekizai.compress" %}
+
+
+ {% include "google_analytics.html" %}
+
+
+
+
+
+
+{% include "gdpr_banner.html" %}
+{% cms_toolbar %}
+
+
+
+
+
+
+
+ {% show_sub_menu 1 None 100 "ungleich_page/glasfaser/menus.html" %}
+
+
+
+
+
+
+ {% placeholder 'Top Section' %}
+
+ {% placeholder 'Middle Section' %}
+
+ {% placeholder 'Glasfaser Services' %}
+
+ {% placeholder 'Glasfaser About' %}
+
+ {% placeholder 'Contact Section' %}
+
+
+ {% include "ungleich_page/includes/_footer.html" %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ungleich_page/templates/ungleich_page/includes/_about.html b/ungleich_page/templates/ungleich_page/includes/_about.html
new file mode 100755
index 0000000..3333e7c
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/includes/_about.html
@@ -0,0 +1,122 @@
+{% load static i18n %}
+
+
+
+
+
{% trans "ABOUT" %}
+ {% trans "The timeline of ungleich" %}
+
+
+
+
+
+
+
+
+
2000
+
+
+
{% trans "The first incarnation of ungleich" %}
+
{% trans "in Germany." %}
+
+
+
+
+
+
+
+
+
+
2013
+
+
+
{% trans "ungleich founded" %}
+
{% trans "in Switzerland." %}
+
+
+
+
+
+
+
+
+
+
2014
+
+
+
{% trans "ungleich present at various conferences" %}: Linuxtag , UCMS , Linux Erfa, ETH Zurich .
+
+
+
+
+
+
+
+
+
+
+
2015
+
+
+
{% trans "ungleich introduces HA-Hosting" %}
+
{% trans "and introduces affordable 24X7 support." %}
+
+ {% trans "ungleich launches" %}
+ {% trans "Digital Glarus project" %} .
+
+
+
+
+
+
+
+
+
+
+
2016
+
+
+
{% blocktrans %}ungleich launches Alplora , an animal tracking service with LoraWAN technology.{% endblocktrans %}
+
+
+
+
+
+
+
+
+
+
2016
+
+
+
{% trans "ungleich starts to give basic computer courses for refugees." %}
+
+
+
+
+
+
+
+
+
+
2017
+
+
+
{% trans 'ungleich starts computer learning club for locals, "Digitale Building ungleich".' %}
+
{% blocktrans %}ungleich sells Alplora to an IoT startup in canton Zürich.{% endblocktrans %}
+
{% trans "ungleich showcases the most affordable Swiss VM hosting, Data Center Light." %}
+
+
+
+
+
+
+
+
+
{% trans "and" %} {% trans "the story continues!" %}
+
+
+
+
+
+
diff --git a/ungleich_page/templates/ungleich_page/includes/_contact_us.html b/ungleich_page/templates/ungleich_page/includes/_contact_us.html
new file mode 100755
index 0000000..55b8670
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/includes/_contact_us.html
@@ -0,0 +1,67 @@
+{% load static meta cms_tags %}
+{% load i18n %}
+
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/includes/_footer.html b/ungleich_page/templates/ungleich_page/includes/_footer.html
new file mode 100755
index 0000000..8937016
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/includes/_footer.html
@@ -0,0 +1,32 @@
+{% load static %}
+{% load i18n %}
+
+
+
+
+
+ {% trans "Copyright © ungleich GmbH " %} {% now "Y" %}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/includes/_header.html b/ungleich_page/templates/ungleich_page/includes/_header.html
new file mode 100755
index 0000000..04bbce5
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/includes/_header.html
@@ -0,0 +1,59 @@
+{% load static i18n %}
+
+
diff --git a/ungleich_page/templates/ungleich_page/includes/_portfolio.html b/ungleich_page/templates/ungleich_page/includes/_portfolio.html
new file mode 100755
index 0000000..75d35ef
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/includes/_portfolio.html
@@ -0,0 +1,34 @@
+{% load static %}
+{% load i18n %}
+
+
+
+
+
{% trans "Our Products" %}
+ {% blocktrans %}Our products include an innovative datacenter, affordable VM hosting, and high speed fiber internet for canton Glarus.{% endblocktrans %}
+
+
+
+
+
+
{% trans "Data Center Light" %}
+
{% trans "We offer the most affordable hosting in Switzerland. Data Center Light has full FOSS stack, 100% IPv6 and 100% SSD. Choose any configuration among CentOS, Debian, Ubuntu, Devuan, and FreeBSD." %}
+
+
+
+
+
+
{% trans "Rails Hosting" %}
+
{% trans "Ready to go live with your Ruby on Rails application? We offer you ready-to-deploy virtual machines or configure your existing infrastructure for Ruby on Rails." %}
+
+
+
+
+
+
{% trans "High Speed Internet" %}
+
{% trans "We offer high speed fiber internet in Glarus Süd, Glarus and Glarus Nord. Experience 100 Mbit/s and see how speed can change everything." %}
+
+
+
+
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/includes/_services.html b/ungleich_page/templates/ungleich_page/includes/_services.html
new file mode 100755
index 0000000..51202b9
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/includes/_services.html
@@ -0,0 +1,43 @@
+{% load static %}
+{% load i18n %}
+
+
+
+
+
{% trans "our services" %}
+
+ {% trans "We support our clients in all areas of Unix infrastructure." %}
+ {% trans "Our top notch configuration management is refreshingly simple and reliable." %}
+
+
+
+
+
+
+
+
{% trans "Hosting" %}
+
{% trans "Ruby on Rails. Java hosting, Django hosting, we make it everything run smooth and safe." %}
+
+
+
+
+
+
+
+
{% trans "Configuration as a Service" %}
+
{% trans "Ruby on Rails, Django, Java, Webserver, Mailserver, any infrastructure that needs to configured, we provide comprehensive solutions. Amazon, rackspace or bare metal servers, we configure for you." %}
+
+
+
+
+
+
+
+
{% trans "Linux System Engineering" %}
+
{% trans "Let your developers develop! We take care of your system administration. Gentoo, Archlinux, Debian, Ubuntu, and many more." %}
+
+
+
+
+
+
diff --git a/ungleich_page/templates/ungleich_page/includes/_softwares.html b/ungleich_page/templates/ungleich_page/includes/_softwares.html
new file mode 100755
index 0000000..669e5f3
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/includes/_softwares.html
@@ -0,0 +1,117 @@
+{% load static %}
+
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/includes/_team.html b/ungleich_page/templates/ungleich_page/includes/_team.html
new file mode 100755
index 0000000..b4e5b24
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/includes/_team.html
@@ -0,0 +1,95 @@
+{% load static %}
+{% load i18n %}
+
+
+
+
+
{% trans "Why ungleich?*" %}
+ {% trans "What our customers say" %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% blocktrans %}
+ "ungleich helped us getting started with our internal
+ infrastructure, hosted on physical servers in a
+ co-location data centre in Zurich. From planning the
+ network layout and virtualisation setup,
+ inviting offers and securing a great deal from a
+ hardware vendor, all the way to the installation of
+ basic services like DNS, VPN and firewalls using the
+ configuration management software cdist, we could
+ count on the support of ungleich. At the end, we got
+ a high availability infrastructure setup enabling our
+ engineers to work more efficiently and comfortable
+ than before."
+ {% endblocktrans %}
+
+
+ - Luciano Franceschina , CTO at Teralytics
+
+
+
+
+
+ {% blocktrans %}
+ "Thanks to ungleich team, who has designed and
+ configured our company's Linux infrastructure, our
+ systems are very easy to maintain. Their innovative
+ configuration management system cdist helped us
+ significantly not only in cost but also in time
+ saving, which is crucial for IT companies like ours."
+ {% endblocktrans %}
+
+
+ - Beat Seeliger , CTO at Panter AG
+
+
+
+
+
+ {% blocktrans %}
+ "ungleich provided an excellent service in designing
+ our system architecture and created secure and stable
+ appliance. For us it is important to have an enduring
+ stability in our system, and ungleich's configuration
+ management system cdist is easy to adapt for our
+ system administrators. We had a successful
+ collaboration with ungleich in the time of very
+ high workload, and their project leading was
+ high-skilled and very reliable. I would definitely
+ recommend them to any companies with high demand in
+ solid infrastructures."
+ {% endblocktrans %}
+
+
+ {% blocktrans %}
+ - Sebastian Plattner,
+ Teamleader Development Cyber Security Products at RUAG
+ {% endblocktrans %}
+
+
+
+
+
+
+
+
+
+
{% blocktrans %}*ungleich means not equal to (≠) U+2260.{% endblocktrans %}
+
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/landing.html b/ungleich_page/templates/ungleich_page/landing.html
new file mode 100755
index 0000000..2fd1bfd
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/landing.html
@@ -0,0 +1,142 @@
+{% load static i18n %}
+
+
+
+
+
+
+
+
+
+
+
+
ungleich GmbH
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% include "google_analytics.html" %}
+
+
+
+
+
+
+
+ {% include "gdpr_banner.html" %}
+
+
+
+
+
+
+
+ {% include "ungleich_page/includes/_header.html" %}
+
+
+ {% include "ungleich_page/includes/_services.html" %}
+
+
+ {% include "ungleich_page/includes/_portfolio.html" %}
+
+
+ {% include "ungleich_page/includes/_about.html" %}
+
+
+ {% include "ungleich_page/includes/_team.html" %}
+
+
+ {% include "ungleich_page/includes/_softwares.html" %}
+
+
+ {% include "ungleich_page/includes/_contact_us.html" %}
+
+
+ {% include "ungleich_page/includes/_footer.html" %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ungleich_page/templates/ungleich_page/ungleich/_customer_item.html b/ungleich_page/templates/ungleich_page/ungleich/_customer_item.html
new file mode 100755
index 0000000..d49183a
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/ungleich/_customer_item.html
@@ -0,0 +1,2 @@
+
+{{ instance.description }}
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/ungleich/_footer.html b/ungleich_page/templates/ungleich_page/ungleich/_footer.html
new file mode 100755
index 0000000..f8770e5
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/ungleich/_footer.html
@@ -0,0 +1,47 @@
+
+
+
+
+ Copyright © {{instance.copyright_label}} {% now "Y" %}
+
+
+
+ {% if instance.link_text %}
+
+ {% endif %}
+
+
+
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/ungleich/_header_with_background_video_slider_item.html b/ungleich_page/templates/ungleich_page/ungleich/_header_with_background_video_slider_item.html
new file mode 100755
index 0000000..4761cdc
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/ungleich/_header_with_background_video_slider_item.html
@@ -0,0 +1,27 @@
+{% load i18n %}
+{% if instance.image %}
+
+{% endif %}
+{% if instance.video %}
+
+ {% comment %}
+ use attribute poster="{{ instance.image.url }}" after cross browser testing
+ in place of .bg_img
+ {% endcomment %}
+
+
+
+
+{% endif %}
+
+ {% if instance.heading %}
+
{{ instance.heading }}
+ {% endif %}
+ {% if instance.description %}
+
{{ instance.description }}
+ {% endif %}
+ {% if instance.btn_link %}
+ {% trans "Learn More" as default_btn_text %}
+
{{ instance.btn_text|default:default_btn_text }}
+ {% endif %}
+
diff --git a/ungleich_page/templates/ungleich_page/ungleich/_products_item.html b/ungleich_page/templates/ungleich_page/ungleich/_products_item.html
new file mode 100755
index 0000000..0a09640
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/ungleich/_products_item.html
@@ -0,0 +1,6 @@
+
+
+
{{ instance.title }}
+
+
{{ instance.description }}
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/ungleich/_services_item.html b/ungleich_page/templates/ungleich_page/ungleich/_services_item.html
new file mode 100755
index 0000000..089adcd
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/ungleich/_services_item.html
@@ -0,0 +1,7 @@
+
+
+
+
{{ instance.title }}
+
{{ instance.description }}
+
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/ungleich/header_with_background_image_slider.html b/ungleich_page/templates/ungleich_page/ungleich/header_with_background_image_slider.html
new file mode 100755
index 0000000..a3ee0d3
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/ungleich/header_with_background_image_slider.html
@@ -0,0 +1,31 @@
+{% load cms_tags %}
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/ungleich/html_block.html b/ungleich_page/templates/ungleich_page/ungleich/html_block.html
new file mode 100755
index 0000000..65c7b79
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/ungleich/html_block.html
@@ -0,0 +1,5 @@
+{% load cms_tags static %}
+{{instance.HTML}}
+{% for plugin in instance.child_plugin_instances %}
+ {% render_plugin plugin %}
+{% endfor %}
diff --git a/ungleich_page/templates/ungleich_page/ungleich/section_customers.html b/ungleich_page/templates/ungleich_page/ungleich/section_customers.html
new file mode 100755
index 0000000..afe67b2
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/ungleich/section_customers.html
@@ -0,0 +1,35 @@
+{% load cms_tags custom_tags %}
+
+
+
+
{{ customer_instance.title }}
+ {{ customer_instance.sub_title }}
+
+
+
+
+
+
+
+ {% for plugin in customer_instance.child_plugin_instances %}
+
+ {% endfor %}
+
+
+
+
+ {% for plugin in customer_instance.child_plugin_instances %}
+
+ {% render_plugin plugin %}
+
+ {% endfor %}
+
+
+
+
+
+
+
+ {{customer_instance.bottom_text}}
+
+
\ No newline at end of file
diff --git a/ungleich_page/templates/ungleich_page/ungleich/section_products.html b/ungleich_page/templates/ungleich_page/ungleich/section_products.html
new file mode 100755
index 0000000..e3d0dc7
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/ungleich/section_products.html
@@ -0,0 +1,33 @@
+{% load cms_tags custom_tags %}
+
+
+
+
+
{{ product_instance.title }}
+ {{ product_instance.sub_title }}
+
+
+ {% for plugin in product_instance.child_plugin_instances %}
+
+ {% render_plugin plugin %}
+
+ {% endfor %}
+
+
+
+
+
+
+
diff --git a/ungleich_page/templates/ungleich_page/ungleich/section_services.html b/ungleich_page/templates/ungleich_page/ungleich/section_services.html
new file mode 100755
index 0000000..20be5ec
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/ungleich/section_services.html
@@ -0,0 +1,16 @@
+{% load cms_tags %}
+
+
+
+
{{ service_instance.title }}
+ {{ service_instance.sub_title }}
+
+
+ {% for plugin in service_instance.child_plugin_instances %}
+
+ {% render_plugin plugin %}
+
+ {% endfor %}
+
+
+
diff --git a/ungleich_page/templates/ungleich_page/ungleich_cms_page.html b/ungleich_page/templates/ungleich_page/ungleich_cms_page.html
new file mode 100755
index 0000000..f58b6f4
--- /dev/null
+++ b/ungleich_page/templates/ungleich_page/ungleich_cms_page.html
@@ -0,0 +1,84 @@
+{% load static i18n cms_tags sekizai_tags %}
+
+
+
+
+
+
+
+
+
+
+
+
+
{% page_attribute "page_title" %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% render_block "css" postprocessor "compressor.contrib.sekizai.compress" %}
+ {% render_block "js" postprocessor "compressor.contrib.sekizai.compress" %}
+
+ {% include "google_analytics.html" %}
+
+
+ {% if request.current_page.cmsfaviconextension %}
+
+ {% else %}
+
+ {% endif %}
+
+
+
+ {% include "gdpr_banner.html" %}
+
+ {% cms_toolbar %}
+ {% placeholder 'Ungleich Page Contents' %}
+
+
+ {% placeholder 'Footer' or %}
+ {% include "ungleich_page/includes/_footer.html" %}
+ {% endplaceholder %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ungleich_page/test_views.py b/ungleich_page/test_views.py
new file mode 100755
index 0000000..0fb238c
--- /dev/null
+++ b/ungleich_page/test_views.py
@@ -0,0 +1,23 @@
+from django.test import TestCase
+from django.urls import reverse
+from django.urls import resolve
+
+
+class ContactViewTest(TestCase):
+
+ def setUp(self):
+ self.url = reverse('ungleich_page:contact')
+ self.data = {
+ 'name': 'test',
+ 'email': 'test@gmail.com',
+ 'phone_number': '32123123123123',
+ 'message': 'This is a message',
+ }
+
+ def url_resolve_to_view_correctly(self):
+ found = resolve(self.url)
+ self.assertEqual(found.func.__name__, self.view.__name__)
+
+ def test_any_user_should_contact_us(self):
+ response = self.client.post(self.url, self.data, follow=True)
+ self.assertEqual(response.status_code, 200)
diff --git a/ungleich_page/tests.py b/ungleich_page/tests.py
new file mode 100755
index 0000000..a79ca8b
--- /dev/null
+++ b/ungleich_page/tests.py
@@ -0,0 +1,3 @@
+# from django.test import TestCase
+
+# Create your tests here.
diff --git a/ungleich_page/urls.py b/ungleich_page/urls.py
new file mode 100755
index 0000000..3c07ad7
--- /dev/null
+++ b/ungleich_page/urls.py
@@ -0,0 +1,9 @@
+from django.urls import re_path
+from .views import ContactView, LandingView
+from django.utils.translation import gettext_lazy as _
+
+urlpatterns = [
+ re_path(r'^$', LandingView.as_view(), name='landing'),
+ # url(r'^ungleich_page/?$', LandingView.as_view(), name='landing'),
+ re_path(_(r'contact/$'), ContactView.as_view(), name='contact'),
+]
diff --git a/ungleich_page/views.py b/ungleich_page/views.py
new file mode 100755
index 0000000..f54912b
--- /dev/null
+++ b/ungleich_page/views.py
@@ -0,0 +1,37 @@
+from django.contrib import messages
+
+from django.views.generic.edit import FormView
+from django.utils.translation import gettext_lazy as _
+from django.urls import reverse_lazy
+from django.views.generic import View
+from django.shortcuts import render
+
+from utils.forms import ContactUsForm
+
+
+class LandingView(View):
+ template_name = "ungleich_page/landing.html"
+ #form_class = ContactUsForm
+
+ def get(self, request, *args, **kwargs):
+ form = self.form_class()
+ return render(request, self.template_name, {'form': form})
+
+
+class ContactView(FormView):
+ template_name = 'ungleich_page/landing.html'
+ form_class = ContactUsForm
+ success_url = reverse_lazy('ungleich_page:landing')
+ success_message = _('Message Successfully Sent')
+
+ def form_valid(self, form):
+ #form.save()
+ #form.send_email()
+ #messages.add_message(self.request, messages.SUCCESS, self.success_message)
+ return super(ContactView, self).form_valid(form)
+
+ def get_context_data(self, **kwargs):
+ context = super(ContactView, self).get_context_data(**kwargs)
+ context['page_title'] = _('Contact Us')
+ context['page_subtitle'] = _('If you have any question, just send us an email.')
+ return context
diff --git a/utils/__init__.py b/utils/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/utils/admin.py b/utils/admin.py
new file mode 100755
index 0000000..f2039ee
--- /dev/null
+++ b/utils/admin.py
@@ -0,0 +1,7 @@
+from django.contrib import admin
+from .models import UserBillingAddress
+
+# Register your models here.
+
+
+admin.site.register(UserBillingAddress)
diff --git a/utils/apps.py b/utils/apps.py
new file mode 100755
index 0000000..7527884
--- /dev/null
+++ b/utils/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class UtilsConfig(AppConfig):
+ name = 'utils'
diff --git a/utils/backend.py b/utils/backend.py
new file mode 100755
index 0000000..2b5c86e
--- /dev/null
+++ b/utils/backend.py
@@ -0,0 +1,13 @@
+
+import logging
+
+from django.contrib.auth.backends import ModelBackend
+logger = logging.getLogger(__name__)
+
+
+class MyLDAPBackend(ModelBackend):
+ def authenticate(self, username=None, password=None, **kwargs):
+ user = super().authenticate(username, password, **kwargs)
+ if user:
+ user.create_ldap_account(password)
+ return user
diff --git a/utils/context_processor.py b/utils/context_processor.py
new file mode 100755
index 0000000..f18bf8f
--- /dev/null
+++ b/utils/context_processor.py
@@ -0,0 +1,31 @@
+from django.conf import settings
+
+
+def google_analytics(request):
+ """
+ Use the variables returned in this function to
+ render your Google Analytics tracking code template.
+
+ Also check whether the site is a tenant site and create a corresponding
+ variable to indicate this
+ """
+ host = request.get_host()
+ ga_prop_id = getattr(settings, 'GOOGLE_ANALYTICS_PROPERTY_IDS', False).get(
+ host)
+ which_urlspy = settings.MULTISITE_CMS_URLS.get(host)
+ if ga_prop_id is None:
+ # Try checking if we have a www in host, if yes we remove
+ # that and check in the dict again
+ if host.startswith('www.'):
+ ga_prop_id = getattr(settings, 'GOOGLE_ANALYTICS_PROPERTY_IDS',
+ False).get(host[4:])
+ which_urlspy = settings.MULTISITE_CMS_URLS.get(host[4:])
+ return_dict = {}
+ if not settings.DEBUG and ga_prop_id:
+ return_dict['GOOGLE_ANALYTICS_PROPERTY_ID'] = ga_prop_id
+
+ if which_urlspy:
+ if which_urlspy.endswith("multi"):
+ return_dict['IS_TENANT_SITE'] = True
+
+ return return_dict
diff --git a/hosting/fields.py b/utils/fields.py
old mode 100644
new mode 100755
similarity index 99%
rename from hosting/fields.py
rename to utils/fields.py
index 4f662d2..ba6b08c
--- a/hosting/fields.py
+++ b/utils/fields.py
@@ -253,4 +253,4 @@ class CountryField(models.CharField):
super(CountryField, self).__init__(*args, **kwargs)
def get_internal_type(self):
- return "CharField"
\ No newline at end of file
+ return "CharField"
diff --git a/utils/forms.py b/utils/forms.py
new file mode 100755
index 0000000..3413588
--- /dev/null
+++ b/utils/forms.py
@@ -0,0 +1,216 @@
+from django import forms
+from django.contrib.auth import authenticate
+from django.core.mail import EmailMultiAlternatives
+from django.template.loader import render_to_string
+from django.utils.translation import gettext_lazy as _
+
+from membership.models import CustomUser
+from .models import ContactMessage, BillingAddress, UserBillingAddress
+
+
+# from utils.fields import CountryField
+
+
+class SignupFormMixin(forms.ModelForm):
+ confirm_password = forms.CharField(widget=forms.PasswordInput())
+ password = forms.CharField(widget=forms.PasswordInput())
+
+ class Meta:
+ model = CustomUser
+ fields = ['name', 'email', 'password']
+ widgets = {
+ 'name': forms.TextInput(
+ attrs={'placeholder': _('Enter your name or company name')}),
+ }
+
+ def clean_confirm_password(self):
+ password = self.cleaned_data.get('password')
+ confirm_password = self.cleaned_data.get('confirm_password')
+ if not confirm_password == password:
+ raise forms.ValidationError("Passwords don't match")
+ return confirm_password
+
+
+class LoginFormMixin(forms.Form):
+ email = forms.CharField(widget=forms.EmailInput())
+ password = forms.CharField(widget=forms.PasswordInput())
+
+ class Meta:
+ fields = ['email', 'password']
+
+ def clean(self):
+ email = self.cleaned_data.get('email')
+ password = self.cleaned_data.get('password')
+ is_auth = authenticate(email=email, password=password)
+ if not is_auth:
+ raise forms.ValidationError(
+ _("Your username and/or password were incorrect."))
+ return self.cleaned_data
+
+ def clean_email(self):
+ email = self.cleaned_data.get('email')
+ try:
+ CustomUser.objects.get(email=email)
+ return email
+ except CustomUser.DoesNotExist:
+ raise forms.ValidationError(_("User does not exist"))
+
+
+class ResendActivationEmailForm(forms.Form):
+ email = forms.CharField(widget=forms.EmailInput())
+
+ class Meta:
+ fields = ['email']
+
+ def clean_email(self):
+ email = self.cleaned_data.get('email')
+ try:
+ c = CustomUser.objects.get(email=email)
+ if c.validated == 1:
+ raise forms.ValidationError(
+ _("The account is already active."))
+ return email
+ except CustomUser.DoesNotExist:
+ raise forms.ValidationError(_("User does not exist"))
+
+
+class PasswordResetRequestForm(forms.Form):
+ email = forms.CharField(widget=forms.EmailInput())
+
+ class Meta:
+ fields = ['email']
+
+ def clean_email(self):
+ email = self.cleaned_data.get('email')
+ try:
+ CustomUser.objects.get(email=email)
+ return email
+ except CustomUser.DoesNotExist:
+ raise forms.ValidationError(_("User does not exist"))
+
+
+class SetPasswordForm(forms.Form):
+ """
+ A form that lets a user change set their password without entering the old
+ password
+ """
+ error_messages = {
+ 'password_mismatch': _("The two password fields didn't match."),
+ }
+ new_password1 = forms.CharField(label=_("New password"),
+ widget=forms.PasswordInput)
+ new_password2 = forms.CharField(label=_("New password confirmation"),
+ widget=forms.PasswordInput)
+
+ def clean_new_password2(self):
+ password1 = self.cleaned_data.get('new_password1')
+ password2 = self.cleaned_data.get('new_password2')
+ if password1 and password2:
+ if password1 != password2:
+ raise forms.ValidationError(
+ self.error_messages['password_mismatch'],
+ code='password_mismatch', )
+ return password2
+
+
+class EditCreditCardForm(forms.Form):
+ token = forms.CharField(widget=forms.HiddenInput())
+
+
+class BillingAddressForm(forms.ModelForm):
+ token = forms.CharField(widget=forms.HiddenInput(), required=False)
+ card = forms.CharField(widget=forms.HiddenInput(), required=False)
+
+ class Meta:
+ model = BillingAddress
+ fields = ['cardholder_name', 'street_address',
+ 'city', 'postal_code', 'country', 'vat_number']
+ labels = {
+ 'cardholder_name': _('Cardholder Name'),
+ 'street_address': _('Street Address'),
+ 'city': _('City'),
+ 'postal_code': _('Postal Code'),
+ 'Country': _('Country'),
+ 'VAT Number': _('VAT Number')
+ }
+
+
+class BillingAddressFormSignup(BillingAddressForm):
+ name = forms.CharField(label=_('Name'))
+ email = forms.EmailField(label=_('Email Address'))
+ field_order = ['name', 'email']
+
+ class Meta:
+ model = BillingAddress
+ fields = ['name', 'email', 'cardholder_name', 'street_address',
+ 'city', 'postal_code', 'country', 'vat_number']
+ labels = {
+ 'name': 'Name',
+ 'email': _('Email'),
+ 'cardholder_name': _('Cardholder Name'),
+ 'street_address': _('Street Address'),
+ 'city': _('City'),
+ 'postal_code': _('Postal Code'),
+ 'Country': _('Country'),
+ 'vat_number': _('VAT Number')
+ }
+
+ def clean_email(self):
+ email = self.cleaned_data.get('email')
+ try:
+ CustomUser.objects.get(email=email)
+ raise forms.ValidationError(
+ _("The email %(email)s is already registered with us. "
+ "Please reset your password and access your account.") %
+ {'email': email}
+ )
+ except CustomUser.DoesNotExist:
+ return email
+
+
+class UserBillingAddressForm(forms.ModelForm):
+ user = forms.ModelChoiceField(queryset=CustomUser.objects.all(),
+ widget=forms.HiddenInput())
+
+ class Meta:
+ model = UserBillingAddress
+ fields = ['cardholder_name', 'street_address',
+ 'city', 'postal_code', 'country', 'user', 'vat_number']
+ labels = {
+ 'cardholder_name': _('Cardholder Name'),
+ 'street_address': _('Street Building'),
+ 'city': _('City'),
+ 'postal_code': _('Postal Code'),
+ 'Country': _('Country'),
+ 'vat_number': _('VAT Number'),
+ }
+
+
+class ContactUsForm(forms.ModelForm):
+ error_css_class = 'autofocus'
+
+ class Meta:
+ model = ContactMessage
+ fields = ['name', 'email', 'phone_number', 'message']
+ widgets = {
+ 'name': forms.TextInput(attrs={'class': u'form-control'}),
+ 'email': forms.TextInput(attrs={'class': u'form-control'}),
+ 'phone_number': forms.TextInput(attrs={'class': u'form-control'}),
+ 'message': forms.Textarea(attrs={'class': u'form-control'}),
+ }
+ labels = {
+ 'name': _('Name'),
+ 'email': _('Email'),
+ 'phone_number': _('Phone number'),
+ 'message': _('Message'),
+ }
+
+ def send_email(self, email_to='info@digitalglarus.ch'):
+ text_content = render_to_string(
+ 'emails/contact.txt', {'data': self.cleaned_data})
+ html_content = render_to_string(
+ 'emails/contact.html', {'data': self.cleaned_data})
+ email = EmailMultiAlternatives('Subject', text_content)
+ email.attach_alternative(html_content, "text/html")
+ email.to = [email_to]
+ email.send()
diff --git a/utils/hosting_utils.py b/utils/hosting_utils.py
new file mode 100755
index 0000000..0b31fed
--- /dev/null
+++ b/utils/hosting_utils.py
@@ -0,0 +1,241 @@
+import decimal
+import logging
+import subprocess
+
+from django.conf import settings
+
+from oca.pool import WrongIdError
+
+from datacenterlight.models import VMPricing
+from hosting.models import UserHostingKey, VMDetail, VATRates
+from opennebula_api.serializers import VirtualMachineSerializer
+
+logger = logging.getLogger(__name__)
+
+
+def get_all_public_keys(customer):
+ """
+ Returns all the public keys of the user
+ :param customer: The customer whose public keys are needed
+ :return: A list of public keys
+ """
+ return UserHostingKey.objects.filter(user_id=customer.id).values_list(
+ "public_key", flat=True).distinct()
+
+
+def get_or_create_vm_detail(user, manager, vm_id):
+ """
+ Returns VMDetail object related to given vm_id. Creates the object
+ if it does not exist
+
+ :param vm_id: The ID of the VM which should be greater than 0.
+ :param user: The CustomUser object that owns this VM
+ :param manager: The OpenNebulaManager object
+ :return: The VMDetail object. None if vm_id is less than or equal to 0.
+ Also, for the cases where the VMDetail does not exist and we can not
+ fetch data about the VM from OpenNebula, the function returns None
+ """
+ if vm_id <= 0:
+ return None
+ try:
+ vm_detail_obj = VMDetail.objects.get(vm_id=vm_id)
+ except VMDetail.DoesNotExist:
+ try:
+ vm_obj = manager.get_vm(vm_id)
+ except (WrongIdError, ConnectionRefusedError) as e:
+ logger.error(str(e))
+ return None
+ vm = VirtualMachineSerializer(vm_obj).data
+ vm_detail_obj = VMDetail.objects.create(
+ user=user, vm_id=vm_id, disk_size=vm['disk_size'],
+ cores=vm['cores'], memory=vm['memory'],
+ configuration=vm['configuration'], ipv4=vm['ipv4'],
+ ipv6=vm['ipv6']
+ )
+ return vm_detail_obj
+
+
+def get_vm_price(cpu, memory, disk_size, hdd_size=0, pricing_name='default'):
+ """
+ A helper function that computes price of a VM from given cpu, ram and
+ ssd parameters
+
+ :param cpu: Number of cores of the VM
+ :param memory: RAM of the VM
+ :param disk_size: Disk space of the VM (SSD)
+ :param hdd_size: The HDD size
+ :param pricing_name: The pricing name to be used
+ :return: The price of the VM
+ """
+ try:
+ pricing = VMPricing.objects.get(name=pricing_name)
+ except Exception as ex:
+ logger.error(
+ "Error getting VMPricing object for {pricing_name}."
+ "Details: {details}".format(
+ pricing_name=pricing_name, details=str(ex)
+ )
+ )
+ return None
+ price = ((decimal.Decimal(cpu) * pricing.cores_unit_price) +
+ (decimal.Decimal(memory) * pricing.ram_unit_price) +
+ (decimal.Decimal(disk_size) * pricing.ssd_unit_price) +
+ (decimal.Decimal(hdd_size) * pricing.hdd_unit_price) +
+ decimal.Decimal(settings.VM_BASE_PRICE))
+ cents = decimal.Decimal('.01')
+ price = price.quantize(cents, decimal.ROUND_HALF_UP)
+ return round(float(price), 2)
+
+
+def get_vm_price_for_given_vat(cpu, memory, ssd_size, hdd_size=0,
+ pricing_name='default', vat_rate=0):
+ try:
+ pricing = VMPricing.objects.get(name=pricing_name)
+ except Exception as ex:
+ logger.error(
+ "Error getting VMPricing object for {pricing_name}."
+ "Details: {details}".format(
+ pricing_name=pricing_name, details=str(ex)
+ )
+ )
+ return None
+
+ price = (
+ (decimal.Decimal(cpu) * pricing.cores_unit_price) +
+ (decimal.Decimal(memory) * pricing.ram_unit_price) +
+ (decimal.Decimal(ssd_size) * pricing.ssd_unit_price) +
+ (decimal.Decimal(hdd_size) * pricing.hdd_unit_price) +
+ decimal.Decimal(settings.VM_BASE_PRICE)
+ )
+
+ discount_name = pricing.discount_name
+ discount_amount = round(float(pricing.discount_amount), 2)
+ vat = price * decimal.Decimal(vat_rate) * decimal.Decimal(0.01)
+ vat_percent = vat_rate
+
+ cents = decimal.Decimal('.01')
+ price = price.quantize(cents, decimal.ROUND_HALF_UP)
+ vat = vat.quantize(cents, decimal.ROUND_HALF_UP)
+ discount_amount_with_vat = decimal.Decimal(discount_amount) * (1 + decimal.Decimal(vat_rate) * decimal.Decimal(0.01))
+ discount_amount_with_vat = discount_amount_with_vat.quantize(cents, decimal.ROUND_HALF_UP)
+ discount = {
+ 'name': discount_name,
+ 'amount': discount_amount,
+ 'amount_with_vat': round(float(discount_amount_with_vat), 2),
+ 'stripe_coupon_id': pricing.stripe_coupon_id
+ }
+ return (round(float(price), 2), round(float(vat), 2),
+ round(float(vat_percent), 2), discount)
+
+
+
+def get_vm_price_with_vat(cpu, memory, ssd_size, hdd_size=0,
+ pricing_name='default'):
+ """
+ A helper function that computes price of a VM from given cpu, ram and
+ ssd, hdd and the pricing parameters
+
+ :param cpu: Number of cores of the VM
+ :param memory: RAM of the VM
+ :param ssd_size: Disk space of the VM (SSD)
+ :param hdd_size: The HDD size
+ :param pricing_name: The pricing name to be used
+ :return: The a tuple containing the price of the VM, the VAT and the
+ VAT percentage
+ """
+ try:
+ pricing = VMPricing.objects.get(name=pricing_name)
+ except Exception as ex:
+ logger.error(
+ "Error getting VMPricing object for {pricing_name}."
+ "Details: {details}".format(
+ pricing_name=pricing_name, details=str(ex)
+ )
+ )
+ return None
+
+ price = (
+ (decimal.Decimal(cpu) * pricing.cores_unit_price) +
+ (decimal.Decimal(memory) * pricing.ram_unit_price) +
+ (decimal.Decimal(ssd_size) * pricing.ssd_unit_price) +
+ (decimal.Decimal(hdd_size) * pricing.hdd_unit_price) +
+ decimal.Decimal(settings.VM_BASE_PRICE)
+ )
+ if pricing.vat_inclusive:
+ vat = decimal.Decimal(0)
+ vat_percent = decimal.Decimal(0)
+ else:
+ vat = price * pricing.vat_percentage * decimal.Decimal(0.01)
+ vat_percent = pricing.vat_percentage
+
+ cents = decimal.Decimal('.01')
+ price = price.quantize(cents, decimal.ROUND_HALF_UP)
+ vat = vat.quantize(cents, decimal.ROUND_HALF_UP)
+ discount = {
+ 'name': pricing.discount_name,
+ 'amount': round(float(pricing.discount_amount), 2),
+ 'stripe_coupon_id': pricing.stripe_coupon_id
+ }
+ return (round(float(price), 2), round(float(vat), 2),
+ round(float(vat_percent), 2), discount)
+
+
+def ping_ok(host_ipv6):
+ """
+ A utility method to check if a host responds to ping requests. Note: the
+ function relies on `ping6` utility of debian to check.
+
+ :param host_ipv6 str type parameter that represets the ipv6 of the host to
+ checked
+ :return True if the host responds to ping else returns False
+ """
+ try:
+ subprocess.check_output("ping6 -c 1 " + host_ipv6, shell=True)
+ except Exception as ex:
+ logger.debug(host_ipv6 + " not reachable via ping. Error = " + str(ex))
+ return False
+ return True
+
+
+def get_vat_rate_for_country(country):
+ vat_rate = None
+ try:
+ vat_rate = VATRates.objects.get(
+ territory_codes=country, start_date__isnull=False, stop_date=None
+ )
+ logger.debug("VAT rate for %s is %s" % (country, vat_rate.rate))
+ return vat_rate.rate
+ except VATRates.DoesNotExist as dne:
+ logger.debug(str(dne))
+ logger.debug("Did not find VAT rate for %s, returning 0" % country)
+ return 0
+
+
+def get_ip_addresses(vm_id):
+ try:
+ vm_detail = VMDetail.objects.get(vm_id=vm_id)
+ return "%s
%s" % (vm_detail.ipv6, vm_detail.ipv4)
+ except VMDetail.DoesNotExist as dne:
+ logger.error(str(dne))
+ logger.error("VMDetail for %s does not exist" % vm_id)
+ return "--"
+
+
+class HostingUtils:
+ @staticmethod
+ def clear_items_from_list(from_list, items_list):
+ """
+ A utility function to clear items from a given list.
+ Useful when deleting items in bulk from session.
+ e.g.:
+ HostingUtils.clear_items_from_list(
+ request.session,
+ ['token', 'billing_address_data', 'card_id',]
+ )
+ :param from_list:
+ :param items_list:
+ :return:
+ """
+ for var in items_list:
+ if var in from_list:
+ del from_list[var]
diff --git a/utils/ldap_manager.py b/utils/ldap_manager.py
new file mode 100755
index 0000000..ff72b86
--- /dev/null
+++ b/utils/ldap_manager.py
@@ -0,0 +1,281 @@
+import base64
+import hashlib
+import random
+import ldap3
+import logging
+import unicodedata
+
+from django.conf import settings
+
+logger = logging.getLogger(__name__)
+
+
+class LdapManager:
+ __instance = None
+
+ def __new__(cls):
+ if LdapManager.__instance is None:
+ LdapManager.__instance = object.__new__(cls)
+ return LdapManager.__instance
+
+ def __init__(self):
+ """
+ Initialize the LDAP subsystem.
+ """
+ self.rng = random.SystemRandom()
+ self.server = ldap3.Server(settings.AUTH_LDAP_SERVER)
+
+ def get_admin_conn(self):
+ """
+ Return a bound :class:`ldap3.Connection` instance which has write
+ permissions on the dn in which the user accounts reside.
+ """
+ conn = self.get_conn(user=settings.LDAP_ADMIN_DN,
+ password=settings.LDAP_ADMIN_PASSWORD,
+ raise_exceptions=True)
+ conn.bind()
+ return conn
+
+ def get_conn(self, **kwargs):
+ """
+ Return an unbound :class:`ldap3.Connection` which talks to the configured
+ LDAP server.
+
+ The *kwargs* are passed to the constructor of :class:`ldap3.Connection` and
+ can be used to set *user*, *password* and other useful arguments.
+ """
+ return ldap3.Connection(self.server, **kwargs)
+
+ def _ssha_password(self, password):
+ """
+ Apply the SSHA password hashing scheme to the given *password*.
+ *password* must be a :class:`bytes` object, containing the utf-8
+ encoded password.
+
+ Return a :class:`bytes` object containing ``ascii``-compatible data
+ which can be used as LDAP value, e.g. after armoring it once more using
+ base64 or decoding it to unicode from ``ascii``.
+ """
+ SALT_BYTES = 15
+
+ sha1 = hashlib.sha1()
+ salt = self.rng.getrandbits(SALT_BYTES * 8).to_bytes(SALT_BYTES, "little")
+ sha1.update(password)
+ sha1.update(salt)
+
+ digest = sha1.digest()
+ passwd = b"{SSHA}" + base64.b64encode(digest + salt)
+ return passwd
+
+ def create_user(self, user, password, firstname, lastname, email):
+ conn = self.get_admin_conn()
+ uidNumber = self._get_max_uid() + 1
+ logger.debug("uidNumber={uidNumber}".format(uidNumber=uidNumber))
+ user_exists = True
+ while user_exists:
+ user_exists, _ = self.check_user_exists(
+ "",
+ '(&(objectClass=inetOrgPerson)(objectClass=posixAccount)'
+ '(objectClass=top)(uidNumber={uidNumber}))'.format(
+ uidNumber=uidNumber
+ )
+ )
+ if user_exists:
+ logger.debug(
+ "{uid} exists. Trying next.".format(uid=uidNumber)
+ )
+ uidNumber += 1
+ logger.debug("{uid} does not exist. Using it".format(uid=uidNumber))
+ self._set_max_uid(uidNumber)
+ try:
+ uid = user
+ conn.add("uid={uid},{customer_dn}".format(
+ uid=uid, customer_dn=settings.LDAP_CUSTOMER_DN
+ ),
+ ["inetOrgPerson", "posixAccount", "ldapPublickey"],
+ {
+ "uid": [uid],
+ "sn": [lastname.encode("utf-8")],
+ "givenName": [firstname.encode("utf-8")],
+ "cn": [uid],
+ "displayName": ["{} {}".format(firstname, lastname).encode("utf-8")],
+ "uidNumber": [str(uidNumber)],
+ "gidNumber": [str(settings.LDAP_CUSTOMER_GROUP_ID)],
+ "loginShell": ["/bin/bash"],
+ "homeDirectory": ["/home/{}".format(unicodedata.normalize('NFKD', user).encode('ascii','ignore'))],
+ "mail": email.encode("utf-8"),
+ "userPassword": [self._ssha_password(
+ password.encode("utf-8")
+ )]
+ }
+ )
+ logger.debug('Created user %s %s' % (user.encode('utf-8'), uidNumber))
+ except Exception as ex:
+ logger.debug('Could not create user %s' % user.encode('utf-8'))
+ logger.error("Exception: " + str(ex))
+ raise Exception(ex)
+ finally:
+ conn.unbind()
+
+ def change_password(self, uid, new_password):
+ """
+ Changes the password of the user identified by user_dn
+
+ :param uid: str The uid that identifies the user
+ :param new_password: str The new password string
+ :return: True if password was changed successfully False otherwise
+ """
+ conn = self.get_admin_conn()
+
+ # Make sure the user exists first to change his/her details
+ user_exists, entries = self.check_user_exists(
+ uid=uid,
+ search_base=settings.ENTIRE_SEARCH_BASE
+ )
+ return_val = False
+ if user_exists:
+ try:
+ return_val = conn.modify(
+ entries[0].entry_dn,
+ {
+ "userpassword": (
+ ldap3.MODIFY_REPLACE,
+ [self._ssha_password(new_password.encode("utf-8"))]
+ )
+ }
+ )
+ except Exception as ex:
+ logger.error("Exception: " + str(ex))
+ else:
+ logger.error("User {} not found".format(uid))
+
+ conn.unbind()
+ return return_val
+
+
+ def change_user_details(self, uid, details):
+ """
+ Updates the user details as per given values in kwargs of the user
+ identified by user_dn.
+
+ Assumes that all attributes passed in kwargs are valid.
+
+ :param uid: str The uid that identifies the user
+ :param details: dict A dictionary containing the new values
+ :return: True if user details were updated successfully False otherwise
+ """
+ conn = self.get_admin_conn()
+
+ # Make sure the user exists first to change his/her details
+ user_exists, entries = self.check_user_exists(
+ uid=uid,
+ search_base=settings.ENTIRE_SEARCH_BASE
+ )
+
+ return_val = False
+ if user_exists:
+ details_dict = {k: (ldap3.MODIFY_REPLACE, [v.encode("utf-8")]) for
+ k, v in details.items()}
+ try:
+ return_val = conn.modify(entries[0].entry_dn, details_dict)
+ msg = "success"
+ except Exception as ex:
+ msg = str(ex)
+ logger.error("Exception: " + msg)
+ finally:
+ conn.unbind()
+ else:
+ msg = "User {} not found".format(uid)
+ logger.error(msg)
+ conn.unbind()
+ return return_val, msg
+
+ def check_user_exists(self, uid, search_filter="", attributes=None,
+ search_base=settings.LDAP_CUSTOMER_DN, search_attr="uid"):
+ """
+ Check if the user with the given uid exists in the customer group.
+
+ :param uid: str representing the user
+ :param search_filter: str representing the filter condition to find
+ users. If its empty, the search finds the user with
+ the given uid.
+ :param attributes: list A list of str representing all the attributes
+ to be obtained in the result entries
+ :param search_base: str
+ :return: tuple (bool, [ldap3.abstract.entry.Entry ..])
+ A bool indicating if the user exists
+ A list of all entries obtained in the search
+ """
+ conn = self.get_admin_conn()
+ entries = []
+ try:
+ result = conn.search(
+ search_base=search_base,
+ search_filter=search_filter if len(search_filter) > 0 else
+ '(uid={uid})'.format(uid=uid),
+ attributes=attributes
+ )
+ entries = conn.entries
+ finally:
+ conn.unbind()
+ return result, entries
+
+ def delete_user(self, uid):
+ """
+ Deletes the user with the given uid from ldap
+
+ :param uid: str representing the user
+ :return: True if the delete was successful False otherwise
+ """
+ conn = self.get_admin_conn()
+ try:
+ return_val = conn.delete(
+ ("uid={uid}," + settings.LDAP_CUSTOMER_DN).format(uid=uid),
+ )
+ msg = "success"
+ except Exception as ex:
+ msg = str(ex)
+ logger.error("Exception: " + msg)
+ return_val = False
+ finally:
+ conn.unbind()
+ return return_val, msg
+
+ def _set_max_uid(self, max_uid):
+ """
+ a utility function to save max_uid value to a file
+
+ :param max_uid: an integer representing the max uid
+ :return:
+ """
+ with open(settings.LDAP_MAX_UID_FILE_PATH, 'w+') as handler:
+ handler.write(str(max_uid))
+
+ def _get_max_uid(self):
+ """
+ A utility function to read the max uid value that was previously set
+
+ :return: An integer representing the max uid value that was previously
+ set
+ """
+ try:
+ with open(settings.LDAP_MAX_UID_FILE_PATH, 'r+') as handler:
+ try:
+ return_value = int(handler.read())
+ except ValueError as ve:
+ logger.error(
+ "Error reading int value from {}. {}"
+ "Returning default value {} instead".format(
+ settings.LDAP_MAX_UID_FILE_PATH,
+ str(ve),
+ settings.LDAP_DEFAULT_START_UID
+ )
+ )
+ return_value = settings.LDAP_DEFAULT_START_UID
+ return return_value
+ except FileNotFoundError as fnfe:
+ logger.error("File not found : " + str(fnfe))
+ return_value = settings.LDAP_DEFAULT_START_UID
+ logger.error("So, returning UID={}".format(return_value))
+ return return_value
+
diff --git a/utils/locale/de/LC_MESSAGES/django.mo b/utils/locale/de/LC_MESSAGES/django.mo
new file mode 100755
index 0000000..c2a8797
Binary files /dev/null and b/utils/locale/de/LC_MESSAGES/django.mo differ
diff --git a/utils/locale/de/LC_MESSAGES/django.po b/utils/locale/de/LC_MESSAGES/django.po
new file mode 100755
index 0000000..152c63c
--- /dev/null
+++ b/utils/locale/de/LC_MESSAGES/django.po
@@ -0,0 +1,1085 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR
, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-12-03 10:44+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: LANGUAGE \n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: utils/fields.py:6
+msgid "Andorra"
+msgstr ""
+
+#: utils/fields.py:7
+msgid "United Arab Emirates"
+msgstr ""
+
+#: utils/fields.py:8
+msgid "Afghanistan"
+msgstr ""
+
+#: utils/fields.py:9
+msgid "Antigua & Barbuda"
+msgstr ""
+
+#: utils/fields.py:10
+msgid "Anguilla"
+msgstr ""
+
+#: utils/fields.py:11
+msgid "Albania"
+msgstr ""
+
+#: utils/fields.py:12
+msgid "Armenia"
+msgstr ""
+
+#: utils/fields.py:13
+msgid "Netherlands Antilles"
+msgstr ""
+
+#: utils/fields.py:14
+msgid "Angola"
+msgstr ""
+
+#: utils/fields.py:15
+msgid "Antarctica"
+msgstr ""
+
+#: utils/fields.py:16
+msgid "Argentina"
+msgstr ""
+
+#: utils/fields.py:17
+msgid "American Samoa"
+msgstr ""
+
+#: utils/fields.py:18
+msgid "Austria"
+msgstr ""
+
+#: utils/fields.py:19
+msgid "Australia"
+msgstr ""
+
+#: utils/fields.py:20
+msgid "Aruba"
+msgstr ""
+
+#: utils/fields.py:21
+msgid "Azerbaijan"
+msgstr ""
+
+#: utils/fields.py:22
+msgid "Bosnia and Herzegovina"
+msgstr ""
+
+#: utils/fields.py:23
+msgid "Barbados"
+msgstr ""
+
+#: utils/fields.py:24
+msgid "Bangladesh"
+msgstr ""
+
+#: utils/fields.py:25
+msgid "Belgium"
+msgstr ""
+
+#: utils/fields.py:26
+msgid "Burkina Faso"
+msgstr ""
+
+#: utils/fields.py:27
+msgid "Bulgaria"
+msgstr ""
+
+#: utils/fields.py:28
+msgid "Bahrain"
+msgstr ""
+
+#: utils/fields.py:29
+msgid "Burundi"
+msgstr ""
+
+#: utils/fields.py:30
+msgid "Benin"
+msgstr ""
+
+#: utils/fields.py:31
+msgid "Bermuda"
+msgstr ""
+
+#: utils/fields.py:32
+msgid "Brunei Darussalam"
+msgstr ""
+
+#: utils/fields.py:33
+msgid "Bolivia"
+msgstr ""
+
+#: utils/fields.py:34
+msgid "Brazil"
+msgstr ""
+
+#: utils/fields.py:35
+msgid "Bahama"
+msgstr ""
+
+#: utils/fields.py:36
+msgid "Bhutan"
+msgstr ""
+
+#: utils/fields.py:37
+msgid "Bouvet Island"
+msgstr ""
+
+#: utils/fields.py:38
+msgid "Botswana"
+msgstr ""
+
+#: utils/fields.py:39
+msgid "Belarus"
+msgstr ""
+
+#: utils/fields.py:40
+msgid "Belize"
+msgstr ""
+
+#: utils/fields.py:41
+msgid "Canada"
+msgstr ""
+
+#: utils/fields.py:42
+msgid "Cocos (Keeling) Islands"
+msgstr ""
+
+#: utils/fields.py:43
+msgid "Central African Republic"
+msgstr ""
+
+#: utils/fields.py:44
+msgid "Congo"
+msgstr ""
+
+#: utils/fields.py:45
+msgid "Switzerland"
+msgstr ""
+
+#: utils/fields.py:46
+msgid "Ivory Coast"
+msgstr ""
+
+#: utils/fields.py:47
+msgid "Cook Iislands"
+msgstr ""
+
+#: utils/fields.py:48
+msgid "Chile"
+msgstr ""
+
+#: utils/fields.py:49
+msgid "Cameroon"
+msgstr ""
+
+#: utils/fields.py:50
+msgid "China"
+msgstr ""
+
+#: utils/fields.py:51
+msgid "Colombia"
+msgstr ""
+
+#: utils/fields.py:52
+msgid "Costa Rica"
+msgstr ""
+
+#: utils/fields.py:53
+msgid "Cuba"
+msgstr ""
+
+#: utils/fields.py:54
+msgid "Cape Verde"
+msgstr ""
+
+#: utils/fields.py:55
+msgid "Christmas Island"
+msgstr ""
+
+#: utils/fields.py:56
+msgid "Cyprus"
+msgstr ""
+
+#: utils/fields.py:57
+msgid "Czech Republic"
+msgstr ""
+
+#: utils/fields.py:58
+msgid "Germany"
+msgstr ""
+
+#: utils/fields.py:59
+msgid "Djibouti"
+msgstr ""
+
+#: utils/fields.py:60
+msgid "Denmark"
+msgstr ""
+
+#: utils/fields.py:61
+msgid "Dominica"
+msgstr ""
+
+#: utils/fields.py:62
+msgid "Dominican Republic"
+msgstr ""
+
+#: utils/fields.py:63
+msgid "Algeria"
+msgstr ""
+
+#: utils/fields.py:64
+msgid "Ecuador"
+msgstr ""
+
+#: utils/fields.py:65
+msgid "Estonia"
+msgstr ""
+
+#: utils/fields.py:66
+msgid "Egypt"
+msgstr ""
+
+#: utils/fields.py:67
+msgid "Western Sahara"
+msgstr ""
+
+#: utils/fields.py:68
+msgid "Eritrea"
+msgstr ""
+
+#: utils/fields.py:69
+msgid "Spain"
+msgstr ""
+
+#: utils/fields.py:70
+msgid "Ethiopia"
+msgstr ""
+
+#: utils/fields.py:71
+msgid "Finland"
+msgstr ""
+
+#: utils/fields.py:72
+msgid "Fiji"
+msgstr ""
+
+#: utils/fields.py:73
+msgid "Falkland Islands (Malvinas)"
+msgstr ""
+
+#: utils/fields.py:74
+msgid "Micronesia"
+msgstr ""
+
+#: utils/fields.py:75
+msgid "Faroe Islands"
+msgstr ""
+
+#: utils/fields.py:76
+msgid "France"
+msgstr ""
+
+#: utils/fields.py:77
+msgid "France, Metropolitan"
+msgstr ""
+
+#: utils/fields.py:78
+msgid "Gabon"
+msgstr ""
+
+#: utils/fields.py:79
+msgid "United Kingdom (Great Britain)"
+msgstr ""
+
+#: utils/fields.py:80
+msgid "Grenada"
+msgstr ""
+
+#: utils/fields.py:81
+msgid "Georgia"
+msgstr ""
+
+#: utils/fields.py:82
+msgid "French Guiana"
+msgstr ""
+
+#: utils/fields.py:83
+msgid "Ghana"
+msgstr ""
+
+#: utils/fields.py:84
+msgid "Gibraltar"
+msgstr ""
+
+#: utils/fields.py:85
+msgid "Greenland"
+msgstr ""
+
+#: utils/fields.py:86
+msgid "Gambia"
+msgstr ""
+
+#: utils/fields.py:87
+msgid "Guinea"
+msgstr ""
+
+#: utils/fields.py:88
+msgid "Guadeloupe"
+msgstr ""
+
+#: utils/fields.py:89
+msgid "Equatorial Guinea"
+msgstr ""
+
+#: utils/fields.py:90
+msgid "Greece"
+msgstr ""
+
+#: utils/fields.py:91
+msgid "South Georgia and the South Sandwich Islands"
+msgstr ""
+
+#: utils/fields.py:92
+msgid "Guatemala"
+msgstr ""
+
+#: utils/fields.py:93
+msgid "Guam"
+msgstr ""
+
+#: utils/fields.py:94
+msgid "Guinea-Bissau"
+msgstr ""
+
+#: utils/fields.py:95
+msgid "Guyana"
+msgstr ""
+
+#: utils/fields.py:96
+msgid "Hong Kong"
+msgstr ""
+
+#: utils/fields.py:97
+msgid "Heard & McDonald Islands"
+msgstr ""
+
+#: utils/fields.py:98
+msgid "Honduras"
+msgstr ""
+
+#: utils/fields.py:99
+msgid "Croatia"
+msgstr ""
+
+#: utils/fields.py:100
+msgid "Haiti"
+msgstr ""
+
+#: utils/fields.py:101
+msgid "Hungary"
+msgstr ""
+
+#: utils/fields.py:102
+msgid "Indonesia"
+msgstr ""
+
+#: utils/fields.py:103
+msgid "Ireland"
+msgstr ""
+
+#: utils/fields.py:104
+msgid "Israel"
+msgstr ""
+
+#: utils/fields.py:105
+msgid "India"
+msgstr ""
+
+#: utils/fields.py:106
+msgid "British Indian Ocean Territory"
+msgstr ""
+
+#: utils/fields.py:107
+msgid "Iraq"
+msgstr ""
+
+#: utils/fields.py:108
+msgid "Islamic Republic of Iran"
+msgstr ""
+
+#: utils/fields.py:109
+msgid "Iceland"
+msgstr ""
+
+#: utils/fields.py:110
+msgid "Italy"
+msgstr ""
+
+#: utils/fields.py:111
+msgid "Jamaica"
+msgstr ""
+
+#: utils/fields.py:112
+msgid "Jordan"
+msgstr ""
+
+#: utils/fields.py:113
+msgid "Japan"
+msgstr ""
+
+#: utils/fields.py:114
+msgid "Kenya"
+msgstr ""
+
+#: utils/fields.py:115
+msgid "Kyrgyzstan"
+msgstr ""
+
+#: utils/fields.py:116
+msgid "Cambodia"
+msgstr ""
+
+#: utils/fields.py:117
+msgid "Kiribati"
+msgstr ""
+
+#: utils/fields.py:118
+msgid "Comoros"
+msgstr ""
+
+#: utils/fields.py:119
+msgid "St. Kitts and Nevis"
+msgstr ""
+
+#: utils/fields.py:120
+msgid "Korea, Democratic People's Republic of"
+msgstr ""
+
+#: utils/fields.py:121
+msgid "Korea, Republic of"
+msgstr ""
+
+#: utils/fields.py:122
+msgid "Kuwait"
+msgstr ""
+
+#: utils/fields.py:123
+msgid "Cayman Islands"
+msgstr ""
+
+#: utils/fields.py:124
+msgid "Kazakhstan"
+msgstr ""
+
+#: utils/fields.py:125
+msgid "Lao People's Democratic Republic"
+msgstr ""
+
+#: utils/fields.py:126
+msgid "Lebanon"
+msgstr ""
+
+#: utils/fields.py:127
+msgid "Saint Lucia"
+msgstr ""
+
+#: utils/fields.py:128
+msgid "Liechtenstein"
+msgstr ""
+
+#: utils/fields.py:129
+msgid "Sri Lanka"
+msgstr ""
+
+#: utils/fields.py:130
+msgid "Liberia"
+msgstr ""
+
+#: utils/fields.py:131
+msgid "Lesotho"
+msgstr ""
+
+#: utils/fields.py:132
+msgid "Lithuania"
+msgstr ""
+
+#: utils/fields.py:133
+msgid "Luxembourg"
+msgstr ""
+
+#: utils/fields.py:134
+msgid "Latvia"
+msgstr ""
+
+#: utils/fields.py:135
+msgid "Libyan Arab Jamahiriya"
+msgstr ""
+
+#: utils/fields.py:136
+msgid "Morocco"
+msgstr ""
+
+#: utils/fields.py:137
+msgid "Monaco"
+msgstr ""
+
+#: utils/fields.py:138
+msgid "Moldova, Republic of"
+msgstr ""
+
+#: utils/fields.py:139
+msgid "Madagascar"
+msgstr ""
+
+#: utils/fields.py:140
+msgid "Marshall Islands"
+msgstr ""
+
+#: utils/fields.py:141
+msgid "Mali"
+msgstr ""
+
+#: utils/fields.py:142
+msgid "Mongolia"
+msgstr ""
+
+#: utils/fields.py:143
+msgid "Myanmar"
+msgstr ""
+
+#: utils/fields.py:144
+msgid "Macau"
+msgstr ""
+
+#: utils/fields.py:145
+msgid "Northern Mariana Islands"
+msgstr ""
+
+#: utils/fields.py:146
+msgid "Martinique"
+msgstr ""
+
+#: utils/fields.py:147
+msgid "Mauritania"
+msgstr ""
+
+#: utils/fields.py:148
+msgid "Monserrat"
+msgstr ""
+
+#: utils/fields.py:149
+msgid "Malta"
+msgstr ""
+
+#: utils/fields.py:150
+msgid "Mauritius"
+msgstr ""
+
+#: utils/fields.py:151
+msgid "Maldives"
+msgstr ""
+
+#: utils/fields.py:152
+msgid "Malawi"
+msgstr ""
+
+#: utils/fields.py:153
+msgid "Mexico"
+msgstr ""
+
+#: utils/fields.py:154
+msgid "Malaysia"
+msgstr ""
+
+#: utils/fields.py:155
+msgid "Mozambique"
+msgstr ""
+
+#: utils/fields.py:156
+msgid "Namibia"
+msgstr ""
+
+#: utils/fields.py:157
+msgid "New Caledonia"
+msgstr ""
+
+#: utils/fields.py:158
+msgid "Niger"
+msgstr ""
+
+#: utils/fields.py:159
+msgid "Norfolk Island"
+msgstr ""
+
+#: utils/fields.py:160
+msgid "Nigeria"
+msgstr ""
+
+#: utils/fields.py:161
+msgid "Nicaragua"
+msgstr ""
+
+#: utils/fields.py:162
+msgid "Netherlands"
+msgstr ""
+
+#: utils/fields.py:163
+msgid "Norway"
+msgstr ""
+
+#: utils/fields.py:164
+msgid "Nepal"
+msgstr ""
+
+#: utils/fields.py:165
+msgid "Nauru"
+msgstr ""
+
+#: utils/fields.py:166
+msgid "Niue"
+msgstr ""
+
+#: utils/fields.py:167
+msgid "New Zealand"
+msgstr ""
+
+#: utils/fields.py:168
+msgid "Oman"
+msgstr ""
+
+#: utils/fields.py:169
+msgid "Panama"
+msgstr ""
+
+#: utils/fields.py:170
+msgid "Peru"
+msgstr ""
+
+#: utils/fields.py:171
+msgid "French Polynesia"
+msgstr ""
+
+#: utils/fields.py:172
+msgid "Papua New Guinea"
+msgstr ""
+
+#: utils/fields.py:173
+msgid "Philippines"
+msgstr ""
+
+#: utils/fields.py:174
+msgid "Pakistan"
+msgstr ""
+
+#: utils/fields.py:175
+msgid "Poland"
+msgstr ""
+
+#: utils/fields.py:176
+msgid "St. Pierre & Miquelon"
+msgstr ""
+
+#: utils/fields.py:177
+msgid "Pitcairn"
+msgstr ""
+
+#: utils/fields.py:178
+msgid "Puerto Rico"
+msgstr ""
+
+#: utils/fields.py:179
+msgid "Portugal"
+msgstr ""
+
+#: utils/fields.py:180
+msgid "Palau"
+msgstr ""
+
+#: utils/fields.py:181
+msgid "Paraguay"
+msgstr ""
+
+#: utils/fields.py:182
+msgid "Qatar"
+msgstr ""
+
+#: utils/fields.py:183
+msgid "Reunion"
+msgstr ""
+
+#: utils/fields.py:184
+msgid "Romania"
+msgstr ""
+
+#: utils/fields.py:185
+msgid "Russian Federation"
+msgstr ""
+
+#: utils/fields.py:186
+msgid "Rwanda"
+msgstr ""
+
+#: utils/fields.py:187
+msgid "Saudi Arabia"
+msgstr ""
+
+#: utils/fields.py:188
+msgid "Solomon Islands"
+msgstr ""
+
+#: utils/fields.py:189
+msgid "Seychelles"
+msgstr ""
+
+#: utils/fields.py:190
+msgid "Sudan"
+msgstr ""
+
+#: utils/fields.py:191
+msgid "Sweden"
+msgstr ""
+
+#: utils/fields.py:192
+msgid "Singapore"
+msgstr ""
+
+#: utils/fields.py:193
+msgid "St. Helena"
+msgstr ""
+
+#: utils/fields.py:194
+msgid "Slovenia"
+msgstr ""
+
+#: utils/fields.py:195
+msgid "Svalbard & Jan Mayen Islands"
+msgstr ""
+
+#: utils/fields.py:196
+msgid "Slovakia"
+msgstr ""
+
+#: utils/fields.py:197
+msgid "Sierra Leone"
+msgstr ""
+
+#: utils/fields.py:198
+msgid "San Marino"
+msgstr ""
+
+#: utils/fields.py:199
+msgid "Senegal"
+msgstr ""
+
+#: utils/fields.py:200
+msgid "Somalia"
+msgstr ""
+
+#: utils/fields.py:201
+msgid "Suriname"
+msgstr ""
+
+#: utils/fields.py:202
+msgid "Sao Tome & Principe"
+msgstr ""
+
+#: utils/fields.py:203
+msgid "El Salvador"
+msgstr ""
+
+#: utils/fields.py:204
+msgid "Syrian Arab Republic"
+msgstr ""
+
+#: utils/fields.py:205
+msgid "Swaziland"
+msgstr ""
+
+#: utils/fields.py:206
+msgid "Turks & Caicos Islands"
+msgstr ""
+
+#: utils/fields.py:207
+msgid "Chad"
+msgstr ""
+
+#: utils/fields.py:208
+msgid "French Southern Territories"
+msgstr ""
+
+#: utils/fields.py:209
+msgid "Togo"
+msgstr ""
+
+#: utils/fields.py:210
+msgid "Thailand"
+msgstr ""
+
+#: utils/fields.py:211
+msgid "Tajikistan"
+msgstr ""
+
+#: utils/fields.py:212
+msgid "Tokelau"
+msgstr ""
+
+#: utils/fields.py:213
+msgid "Turkmenistan"
+msgstr ""
+
+#: utils/fields.py:214
+msgid "Tunisia"
+msgstr ""
+
+#: utils/fields.py:215
+msgid "Tonga"
+msgstr ""
+
+#: utils/fields.py:216
+msgid "East Timor"
+msgstr ""
+
+#: utils/fields.py:217
+msgid "Turkey"
+msgstr ""
+
+#: utils/fields.py:218
+msgid "Trinidad & Tobago"
+msgstr ""
+
+#: utils/fields.py:219
+msgid "Tuvalu"
+msgstr ""
+
+#: utils/fields.py:220
+msgid "Taiwan, Province of China"
+msgstr ""
+
+#: utils/fields.py:221
+msgid "Tanzania, United Republic of"
+msgstr ""
+
+#: utils/fields.py:222
+msgid "Ukraine"
+msgstr ""
+
+#: utils/fields.py:223
+msgid "Uganda"
+msgstr ""
+
+#: utils/fields.py:224
+msgid "United States Minor Outlying Islands"
+msgstr ""
+
+#: utils/fields.py:225
+msgid "United States of America"
+msgstr ""
+
+#: utils/fields.py:226
+msgid "Uruguay"
+msgstr ""
+
+#: utils/fields.py:227
+msgid "Uzbekistan"
+msgstr ""
+
+#: utils/fields.py:228
+msgid "Vatican City State (Holy See)"
+msgstr ""
+
+#: utils/fields.py:229
+msgid "St. Vincent & the Grenadines"
+msgstr ""
+
+#: utils/fields.py:230
+msgid "Venezuela"
+msgstr ""
+
+#: utils/fields.py:231
+msgid "British Virgin Islands"
+msgstr ""
+
+#: utils/fields.py:232
+msgid "United States Virgin Islands"
+msgstr ""
+
+#: utils/fields.py:233
+msgid "Viet Nam"
+msgstr ""
+
+#: utils/fields.py:234
+msgid "Vanuatu"
+msgstr ""
+
+#: utils/fields.py:235
+msgid "Wallis & Futuna Islands"
+msgstr ""
+
+#: utils/fields.py:236
+msgid "Samoa"
+msgstr ""
+
+#: utils/fields.py:237
+msgid "Yemen"
+msgstr ""
+
+#: utils/fields.py:238
+msgid "Mayotte"
+msgstr ""
+
+#: utils/fields.py:239
+msgid "Yugoslavia"
+msgstr ""
+
+#: utils/fields.py:240
+msgid "South Africa"
+msgstr ""
+
+#: utils/fields.py:241
+msgid "Zambia"
+msgstr ""
+
+#: utils/fields.py:242
+msgid "Zaire"
+msgstr ""
+
+#: utils/fields.py:243
+msgid "Zimbabwe"
+msgstr ""
+
+#: utils/forms.py:23
+msgid "Enter your name or company name"
+msgstr "Gib Deinen Namen oder den Name Deines Unternehmens ein"
+
+#: utils/forms.py:47
+msgid "Your username and/or password were incorrect."
+msgstr "Dein Benutzername und/oder Dein Passwort ist falsch."
+
+#: utils/forms.py:56 utils/forms.py:74 utils/forms.py:89
+msgid "User does not exist"
+msgstr "Der Benutzer existiert nicht"
+
+#: utils/forms.py:71
+msgid "The account is already active."
+msgstr "Das Benutzerkonto ist bereits aktiv."
+
+#: utils/forms.py:98
+msgid "The two password fields didn't match."
+msgstr "Die beiden Passwörter stimmen nicht überein."
+
+#: utils/forms.py:100
+msgid "New password"
+msgstr "Neues Passwort"
+
+#: utils/forms.py:102
+msgid "New password confirmation"
+msgstr "Neues Passwort Bestätigung"
+
+#: utils/forms.py:129 utils/forms.py:150 utils/forms.py:180
+msgid "Cardholder Name"
+msgstr "Name des Kartenbesitzer"
+
+#: utils/forms.py:130 utils/forms.py:151
+msgid "Street Address"
+msgstr ""
+
+#: utils/forms.py:131 utils/forms.py:152 utils/forms.py:182
+msgid "City"
+msgstr ""
+
+#: utils/forms.py:132 utils/forms.py:153 utils/forms.py:183
+msgid "Postal Code"
+msgstr ""
+
+#: utils/forms.py:133 utils/forms.py:154 utils/forms.py:184
+msgid "Country"
+msgstr ""
+
+#: utils/forms.py:134 utils/forms.py:155 utils/forms.py:185
+msgid "VAT Number"
+msgstr ""
+
+#: utils/forms.py:139 utils/forms.py:202
+msgid "Name"
+msgstr ""
+
+#: utils/forms.py:140
+msgid "Email Address"
+msgstr ""
+
+#: utils/forms.py:149 utils/forms.py:203
+msgid "Email"
+msgstr "E-Mail"
+
+#: utils/forms.py:163
+#, python-format
+msgid ""
+"The email %(email)s is already registered with us. Please reset your "
+"password and access your account."
+msgstr ""
+"Diese E-Mail-Adresse %(email)s existiert bereits. Bitte setze dein Passwort "
+"zurück auf dein Konto zuzugreifen."
+
+#: utils/forms.py:181
+msgid "Street Building"
+msgstr "Gebäude"
+
+#: utils/forms.py:204
+msgid "Phone number"
+msgstr "Telefon"
+
+#: utils/forms.py:205
+msgid "Message"
+msgstr "Nachricht"
+
+#: utils/views.py:80
+msgid "An email with the activation link has been sent to you"
+msgstr "Es wurde eine E-Mail mit dem Aktivierungslink an Dich gesendet."
+
+#: utils/views.py:103
+msgid "Account Activation"
+msgstr "Accountaktivierung"
+
+#: utils/views.py:118
+msgid "The link to reset your password has been sent to your email"
+msgstr ""
+"Der Link zum Zurücksetzen deines Passwortes wurde an deine E-Mail gesendet"
+
+#: utils/views.py:139
+msgid "Password Reset"
+msgstr "Passwort zurücksetzen"
+
+#: utils/views.py:171
+msgid "Password has been reset."
+msgstr "Das Passwort wurde zurückgesetzt."
+
+#: utils/views.py:175 utils/views.py:177
+msgid "Password reset has not been successful."
+msgstr "Das Zurücksetzen war nicht erfolgreich."
+
+#: utils/views.py:182 utils/views.py:184
+msgid "The reset password link is no longer valid."
+msgstr "Der Link zum Zurücksetzen Deines Passwortes ist nicht länger gültig."
diff --git a/utils/mailer.py b/utils/mailer.py
new file mode 100755
index 0000000..3ca5f82
--- /dev/null
+++ b/utils/mailer.py
@@ -0,0 +1,67 @@
+import six
+from django.core.mail import send_mail
+from django.core.mail import EmailMultiAlternatives
+from django.template.loader import render_to_string
+
+
+class BaseEmail(object):
+
+ def __init__(self, *args, **kwargs):
+ self.to = kwargs.get('to')
+ self.template_name = kwargs.get('template_name')
+ self.template_path = kwargs.get('template_path')
+ self.subject = kwargs.get('subject')
+ self.context = kwargs.get('context', {})
+ self.template_full_path = '%s%s' % (self.template_path, self.template_name)
+ text_content = render_to_string('%s.txt' % self.template_full_path, self.context)
+ html_content = render_to_string('%s.html' % self.template_full_path, self.context)
+
+ self.email = EmailMultiAlternatives(self.subject, text_content)
+ self.email.attach_alternative(html_content, "text/html")
+ if 'from_address' in kwargs:
+ self.email.from_email = kwargs.get('from_address')
+ else:
+ self.email.from_email = '(ungleich) ungleich Support '
+ self.email.to = [kwargs.get('to', 'info@ungleich.ch')]
+
+ def send(self):
+ self.email.send()
+
+
+class BaseMailer(object):
+ def __init__(self):
+ self._slug = None
+ self.no_replay_mail = 'info@ungleich.ch'
+
+ if not hasattr(self, '_to'):
+ self._to = None
+
+ @property
+ def slug(self):
+ return self._slug
+
+ @slug.setter
+ def slug(self, val):
+ assert isinstance(val, six.string_types), "slug is not string: %r" % val
+ self._slug = val
+
+ @property
+ def registration(self):
+ return self.message
+
+ @registration.setter
+ def registration(self, val):
+ msg = "registration is not dict with fields subject,message"
+ assert type(val) is dict, msg
+ assert val.get('subject') and val.get('message'), msg
+ self._message, self._subject, self._from = (
+ val.get('message'), val.get('subject'), val.get('from'))
+ assert isinstance(self.slug, six.string_types), 'slug not set'
+
+ def send_mail(self, to=None):
+ if not to:
+ to = self._to
+ if not self.message:
+ raise NotImplementedError
+ send_mail(self._subject, self._message, self.no_replay_mail, [to])
+
diff --git a/utils/management/commands/optimize_frontend.py b/utils/management/commands/optimize_frontend.py
new file mode 100755
index 0000000..8544ba6
--- /dev/null
+++ b/utils/management/commands/optimize_frontend.py
@@ -0,0 +1,497 @@
+"""
+This command finds and creates a report for all the usage of css rules in
+an app. It aims to optimize existing codebase as well as assist the frontend
+developer when designing new components by avoiding unnecessary duplication and
+suggesting more/optimal alternatives.
+
+Features:
+ Currently the command can find out and display:
+ - Media Breakpoints used in a stylesheet
+ - Duplicate selectors in a stylesheet
+ - Unused selectors
+ Work in progress to enable these features:
+ - Duplicate style declaration for same selector
+ - DOM validation
+ - Finding out dead styles (those that are always cancelled)
+ - Optimize media declarations
+
+Example:
+ $ python manage.py optimize_frontend datacenterlight
+ above command produces a file ../optimize_frontend.html which contains a
+ report with the above mentioned features
+"""
+
+# import csv
+import json
+import logging
+import os
+import re
+from collections import Counter, OrderedDict
+# from itertools import zip_longest
+
+from django import template
+from django.conf import settings
+from django.contrib.staticfiles import finders
+from django.core.management.base import BaseCommand
+
+
+logger = logging.getLogger(__name__)
+
+RE_PATTERNS = {
+ 'view_html': '[\'\"](.*\.html)',
+ 'html_html': '{% (?:extends|include) [\'\"]?(.*\.html)',
+ 'html_style': '{% static [\'\"]?(.*\.css)',
+ 'css_media': (
+ '^\s*\@media([^{]+)\{\s*([\s\S]*?})\s*}'
+ ),
+ 'css_selector': (
+ '^\s*([.#\[:_A-Za-z][^{]*?)\s*'
+ '\s*{\s*([\s\S]*?)\s*}'
+ ),
+ 'html_class': 'class=[\'\"]([a-zA-Z0-9-_\s]*)',
+ 'html_id': 'id=[\'\"]([a-zA-Z0-9-_]*)'
+}
+
+
+class Command(BaseCommand):
+ help = (
+ 'Finds unused and duplicate style declarations from the stylesheets '
+ 'used in the templates of each app'
+ )
+ requires_system_checks = False
+
+ def add_arguments(self, parser):
+ # positional arguments
+ parser.add_argument(
+ 'apps', nargs='+', type=str,
+ help='name of the apps to be optimized'
+ )
+
+ # Named (optional) arguments
+ parser.add_argument(
+ '--together',
+ action='store_true',
+ help='optimize the apps together'
+ )
+ parser.add_argument(
+ '--css',
+ action='store_true',
+ help='optimize only the css rules declared in each stylesheet'
+ )
+
+ def handle(self, *args, **options):
+ apps_list = options['apps']
+ report = {}
+ for app in apps_list:
+ if options['css']:
+ report[app] = self.optimize_css(app)
+ # write report
+ write_report(report)
+
+ def optimize_css(self, app_name):
+ """Optimize declarations inside a css stylesheet
+
+ Args:
+ app_name (str): The application name
+ """
+ # get html and css files used in the app
+ files = get_files(app_name)
+ # get_selectors_from_css
+ css_selectors = get_selectors_css(files['style'])
+ # get_selectors_from_html
+ html_selectors = get_selectors_html(files['html'])
+ report = {
+ 'css_dup': get_css_duplication(css_selectors),
+ 'css_unused': get_css_unused(css_selectors, html_selectors)
+ }
+ return report
+
+
+def get_files(app_name):
+ """Get all the `html` and `css` files used in an app.
+
+ Args:
+ app_name (str): The application name
+
+ Returns:
+ dict: A dictonary containing Counter of occurence of each
+ html and css file in `html` and `style` fields respectively.
+ For example:
+ {
+ 'html': {'datacenterlight/success.html': 1},
+ 'style': {'datacenterlight/css/bootstrap.min.css': 2}
+ }
+ """
+ # the view file for the app
+ app_view = os.path.join(settings.PROJECT_DIR, app_name, 'views.py')
+ # get template files called from the view
+ all_html_list = file_match_pattern(app_view, 'view_html')
+ # list of unique template files
+ uniq_html_list = list(OrderedDict.fromkeys(all_html_list).keys())
+ # list of stylesheets
+ all_style_list = []
+ file_patterns = ['html_html', 'html_style']
+ # get html and css files called from within templates
+ i = 0
+ while i < len(uniq_html_list):
+ template_name = uniq_html_list[i]
+ try:
+ temp_files = templates_match_pattern(
+ template_name, file_patterns
+ )
+ except template.exceptions.TemplateDoesNotExist as e:
+ print("template file not found: ", str(e))
+ all_html_list = [
+ h for h in all_html_list if h != template_name
+ ]
+ del uniq_html_list[i]
+ else:
+ all_html_list.extend(temp_files[0])
+ uniq_html_list = list(
+ OrderedDict.fromkeys(all_html_list).keys()
+ )
+ all_style_list.extend(temp_files[1])
+ i += 1
+ # counter dict for the html files called from view
+ result = {
+ 'html': Counter(all_html_list),
+ 'style': Counter(all_style_list)
+ }
+ # print(result)
+ return result
+
+
+def get_selectors_css(files):
+ """Gets the selectors and declarations from a stylesheet.
+
+ Args:
+ files (list): A list of path of stylesheets.
+
+ Returns:
+ dict: A nested dictionary with the structre as
+ `{'file': {'media-selector': [('selectors',`declarations')]}}`
+ For example:
+ {
+ 'datacenterlight/css/landing-page.css':{
+ '(min-width: 768px)': [
+ ('.lead-right', 'text-align: right;'),
+ ]
+ }
+ }
+ """
+ selectors = {}
+ media_selectors = {}
+ # get media selectors and other simple declarations
+ for file in files:
+ if any(vendor in file for vendor in ['bootstrap', 'font-awesome']):
+ continue
+ result = finders.find(file)
+ if result:
+ with open(result) as f:
+ data = f.read()
+ media_selectors[file] = string_match_pattern(data, 'css_media')
+ new_data = string_remove_pattern(data, 'css_media')
+ default_match = string_match_pattern(new_data, 'css_selector')
+ selectors[file] = {
+ 'default': [
+ [' '.join(grp.split()) for grp in m] for m in default_match
+ ]
+ }
+ # get declarations from media queries
+ for file, match_list in media_selectors.items():
+ for match in match_list:
+ query = match[0]
+ block_text = ' '.join(match[1].split())
+ results = string_match_pattern(
+ block_text, 'css_selector'
+ )
+ f_query = ' '.join(query.replace(':', ': ').split())
+ if f_query in selectors[file]:
+ selectors[file][f_query].extend(results)
+ else:
+ selectors[file][f_query] = results
+ return selectors
+
+
+def get_selectors_html(files):
+ """Get `class` and `id` used in html files.
+
+ Args:
+ files (list): A list of html files path.
+
+ Returns:
+ dict: a dictonary of all the classes and ids found in the file, in
+ `class` and `id` field respectively.
+ """
+ selectors = {}
+ for file in files:
+ results = templates_match_pattern(file, ['html_class', 'html_id'])
+ class_dict = {c: 1 for match in results[0] for c in match.split()}
+ selectors[file] = {
+ 'classes': list(class_dict.keys()),
+ 'ids': results[1],
+ }
+ return selectors
+
+
+def file_match_pattern(file, patterns):
+ """Match a regex pattern in a file
+
+ Args:
+ file (str): Complete path of file
+ patterns (list or str): The pattern(s) to be searched in the file
+
+ Returns:
+ list: A list of all the matches in the file. Each item is a list of
+ all the captured groups in the pattern. If multiple patterns are given,
+ the returned list is a list of such lists.
+ For example:
+ [('.lead', 'font-size: 18px;'), ('.btn-lg', 'min-width: 180px;')]
+ """
+ with open(file) as f:
+ data = f.read()
+ results = string_match_pattern(data, patterns)
+ return results
+
+
+def string_match_pattern(data, patterns):
+ """Match a regex pattern in a string
+
+ Args:
+ data (str): the string to search for the pattern
+ patterns (list or str): The pattern(s) to be searched in the file
+
+ Returns:
+ list: A list of all the matches in the string. Each item is a list of
+ all the captured groups in the pattern. If multiple patterns are given,
+ the returned list is a list of such lists.
+ For example:
+ [('.lead', 'font-size: 18px;'), ('.btn-lg', 'min-width: 180px;')]
+ """
+ if not isinstance(patterns, str):
+ results = []
+ for p in patterns:
+ re_pattern = re.compile(RE_PATTERNS[p], re.MULTILINE)
+ results.append(re.findall(re_pattern, data))
+ else:
+ re_pattern = re.compile(RE_PATTERNS[patterns], re.MULTILINE)
+ results = re.findall(re_pattern, data)
+ return results
+
+
+def string_remove_pattern(data, patterns):
+ """Remove a pattern from a string
+
+ Args:
+ data (str): the string to search for the patter
+ patterns (list or str): The pattern(s) to be removed from the file
+
+ Returns:
+ str: The new string with all instance of matching pattern
+ removed from it
+ """
+ if not isinstance(patterns, str):
+ for p in patterns:
+ re_pattern = re.compile(RE_PATTERNS[p], re.MULTILINE)
+ data = re.sub(re_pattern, '', data)
+ else:
+ re_pattern = re.compile(RE_PATTERNS[patterns], re.MULTILINE)
+ data = re.sub(re_pattern, '', data)
+ return data
+
+
+def templates_match_pattern(template_name, patterns):
+ """Match a regex pattern in the first found template file
+
+ Args:
+ file (str): Path of template file
+ patterns (list or str): The pattern(s) to be searched in the file
+
+ Returns:
+ list: A list of all the matches in the file. Each item is a list of
+ all the captured groups in the pattern. If multiple patterns are given,
+ the returned list is a list of such lists.
+ For example:
+ [('.lead', 'font-size: 18px;'), ('.btn-lg', 'min-width: 180px;')]
+ """
+ t = template.loader.get_template(template_name)
+ data = t.template.source
+ results = string_match_pattern(data, patterns)
+ return results
+
+
+def get_css_duplication(css_selectors):
+ """Get duplicate selectors from the same stylesheet
+
+ Args:
+ css_selectors (dict): A dictonary containing css selectors from
+ all the files in the app in the below structure.
+ `{'file': {'media-selector': [('selectors',`declarations')]}}`
+
+ Returns:
+ dict: A dictonary containing the count of any duplicate selector in
+ each file.
+ `{'file': {'media-selector': {'selector': count}}}`
+ """
+ # duplicate css selectors in stylesheets
+ rule_count = {}
+ for file, media_selectors in css_selectors.items():
+ rule_count[file] = {}
+ for media, rules in media_selectors.items():
+ rules_dict = Counter([rule[0] for rule in rules])
+ dup_rules_dict = {k: v for k, v in rules_dict.items() if v > 1}
+ if dup_rules_dict:
+ rule_count[file][media] = dup_rules_dict
+ return rule_count
+
+
+def get_css_unused(css_selectors, html_selectors):
+ """Get selectors from stylesheets that are not used in any of the html
+ files in which the stylesheet is used.
+
+ Args:
+ css_selectors (dict): A dictonary containing css selectors from
+ all the files in the app in the below structure.
+ `{'file': {'media-selector': [('selectors',`declarations')]}}`
+ html_selectors (dict): A dictonary containing the 'class' and 'id'
+ declarations from all html files
+ """
+ with open('utils/optimize/test.json', 'w') as f:
+ json.dump([html_selectors, css_selectors], f, indent=4)
+ # print(html_selectors, css_selectors)
+
+
+def write_report(all_reports, filename='frontend'):
+ """Write the generated report to a file for re-use
+
+ Args;
+ all_reports (dict): A dictonary of report obtained from different tests
+ filename (str): An optional suffix for the output file
+ """
+ # full_filename = 'utils/optimize/optimize_' + filename + '.html'
+ # output_file = os.path.join(
+ # settings.PROJECT_DIR, full_filename
+ # )
+ with open('utils/optimize/op_frontend.json', 'w') as f:
+ json.dump(all_reports, f, indent=4)
+ # with open(output_file, 'w', newline='') as f:
+ # f.write(
+ # template.loader.render_to_string(
+ # 'utils/report.html', {'all_reports': all_reports}
+ # )
+ # )
+ # w = csv.writer(f)
+ # print(zip_longest(*results))
+ # for r in zip_longest(*results):
+ # w.writerow(r)
+
+
+# a list of all the html tags (to be moved in a json file)
+html_tags = [
+ "a",
+ "abbr",
+ "address",
+ "article",
+ "area",
+ "aside",
+ "audio",
+ "b",
+ "base",
+ "bdi",
+ "bdo",
+ "blockquote",
+ "body",
+ "br",
+ "button",
+ "canvas",
+ "caption",
+ "cite",
+ "code",
+ "col",
+ "colgroup",
+ "datalist",
+ "dd",
+ "del",
+ "details",
+ "dfn",
+ "div",
+ "dl",
+ "dt",
+ "em",
+ "embed",
+ "fieldset",
+ "figcaption",
+ "figure",
+ "footer",
+ "form",
+ "h1",
+ "h2",
+ "h3",
+ "h4",
+ "h5",
+ "h6",
+ "head",
+ "header",
+ "hgroup",
+ "hr",
+ "html",
+ "i",
+ "iframe",
+ "img",
+ "input",
+ "ins",
+ "kbd",
+ "keygen",
+ "label",
+ "legend",
+ "li",
+ "link",
+ "map",
+ "mark",
+ "menu",
+ "meta",
+ "meter",
+ "nav",
+ "noscript",
+ "object",
+ "ol",
+ "optgroup",
+ "option",
+ "output",
+ "p",
+ "param",
+ "pre",
+ "progress",
+ "q",
+ "rp",
+ "rt",
+ "ruby",
+ "s",
+ "samp",
+ "script",
+ "section",
+ "select",
+ "source",
+ "small",
+ "span",
+ "strong",
+ "style",
+ "sub",
+ "summary",
+ "sup",
+ "textarea",
+ "table",
+ "tbody",
+ "td",
+ "tfoot",
+ "thead",
+ "th",
+ "time",
+ "title",
+ "tr",
+ "u",
+ "ul",
+ "var",
+ "video",
+ "wbr"
+]
diff --git a/utils/middleware.py b/utils/middleware.py
new file mode 100755
index 0000000..56623bf
--- /dev/null
+++ b/utils/middleware.py
@@ -0,0 +1,17 @@
+#class MultipleProxyMiddleware(object):
+# FORWARDED_FOR_FIELDS = [
+# 'HTTP_X_FORWARDED_FOR',
+# 'HTTP_X_FORWARDED_HOST',
+# 'HTTP_X_FORWARDED_SERVER',
+# ]
+#
+# def process_request(self, request):
+# """
+# Rewrites the proxy headers so that only the most
+# recent proxy is used.
+# """
+# for field in self.FORWARDED_FOR_FIELDS:
+# if field in request.META:
+# if ',' in request.META[field]:
+# parts = request.META[field].split(',')
+# request.META[field] = parts[-1].strip()
diff --git a/utils/migrations/0001_initial.py b/utils/migrations/0001_initial.py
new file mode 100644
index 0000000..a8b63c0
--- /dev/null
+++ b/utils/migrations/0001_initial.py
@@ -0,0 +1,67 @@
+# Generated by Django 4.2.7 on 2023-12-07 10:48
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+import utils.fields
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='BillingAddress',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('cardholder_name', models.CharField(default='', max_length=100)),
+ ('street_address', models.CharField(max_length=100)),
+ ('city', models.CharField(max_length=50)),
+ ('postal_code', models.CharField(max_length=50)),
+ ('country', utils.fields.CountryField(choices=[('AD', 'Andorra'), ('AE', 'United Arab Emirates'), ('AF', 'Afghanistan'), ('AG', 'Antigua & Barbuda'), ('AI', 'Anguilla'), ('AL', 'Albania'), ('AM', 'Armenia'), ('AN', 'Netherlands Antilles'), ('AO', 'Angola'), ('AQ', 'Antarctica'), ('AR', 'Argentina'), ('AS', 'American Samoa'), ('AT', 'Austria'), ('AU', 'Australia'), ('AW', 'Aruba'), ('AZ', 'Azerbaijan'), ('BA', 'Bosnia and Herzegovina'), ('BB', 'Barbados'), ('BD', 'Bangladesh'), ('BE', 'Belgium'), ('BF', 'Burkina Faso'), ('BG', 'Bulgaria'), ('BH', 'Bahrain'), ('BI', 'Burundi'), ('BJ', 'Benin'), ('BM', 'Bermuda'), ('BN', 'Brunei Darussalam'), ('BO', 'Bolivia'), ('BR', 'Brazil'), ('BS', 'Bahama'), ('BT', 'Bhutan'), ('BV', 'Bouvet Island'), ('BW', 'Botswana'), ('BY', 'Belarus'), ('BZ', 'Belize'), ('CA', 'Canada'), ('CC', 'Cocos (Keeling) Islands'), ('CF', 'Central African Republic'), ('CG', 'Congo'), ('CH', 'Switzerland'), ('CI', 'Ivory Coast'), ('CK', 'Cook Iislands'), ('CL', 'Chile'), ('CM', 'Cameroon'), ('CN', 'China'), ('CO', 'Colombia'), ('CR', 'Costa Rica'), ('CU', 'Cuba'), ('CV', 'Cape Verde'), ('CX', 'Christmas Island'), ('CY', 'Cyprus'), ('CZ', 'Czech Republic'), ('DE', 'Germany'), ('DJ', 'Djibouti'), ('DK', 'Denmark'), ('DM', 'Dominica'), ('DO', 'Dominican Republic'), ('DZ', 'Algeria'), ('EC', 'Ecuador'), ('EE', 'Estonia'), ('EG', 'Egypt'), ('EH', 'Western Sahara'), ('ER', 'Eritrea'), ('ES', 'Spain'), ('ET', 'Ethiopia'), ('FI', 'Finland'), ('FJ', 'Fiji'), ('FK', 'Falkland Islands (Malvinas)'), ('FM', 'Micronesia'), ('FO', 'Faroe Islands'), ('FR', 'France'), ('FX', 'France, Metropolitan'), ('GA', 'Gabon'), ('GB', 'United Kingdom (Great Britain)'), ('GD', 'Grenada'), ('GE', 'Georgia'), ('GF', 'French Guiana'), ('GH', 'Ghana'), ('GI', 'Gibraltar'), ('GL', 'Greenland'), ('GM', 'Gambia'), ('GN', 'Guinea'), ('GP', 'Guadeloupe'), ('GQ', 'Equatorial Guinea'), ('GR', 'Greece'), ('GS', 'South Georgia and the South Sandwich Islands'), ('GT', 'Guatemala'), ('GU', 'Guam'), ('GW', 'Guinea-Bissau'), ('GY', 'Guyana'), ('HK', 'Hong Kong'), ('HM', 'Heard & McDonald Islands'), ('HN', 'Honduras'), ('HR', 'Croatia'), ('HT', 'Haiti'), ('HU', 'Hungary'), ('ID', 'Indonesia'), ('IE', 'Ireland'), ('IL', 'Israel'), ('IN', 'India'), ('IO', 'British Indian Ocean Territory'), ('IQ', 'Iraq'), ('IR', 'Islamic Republic of Iran'), ('IS', 'Iceland'), ('IT', 'Italy'), ('JM', 'Jamaica'), ('JO', 'Jordan'), ('JP', 'Japan'), ('KE', 'Kenya'), ('KG', 'Kyrgyzstan'), ('KH', 'Cambodia'), ('KI', 'Kiribati'), ('KM', 'Comoros'), ('KN', 'St. Kitts and Nevis'), ('KP', "Korea, Democratic People's Republic of"), ('KR', 'Korea, Republic of'), ('KW', 'Kuwait'), ('KY', 'Cayman Islands'), ('KZ', 'Kazakhstan'), ('LA', "Lao People's Democratic Republic"), ('LB', 'Lebanon'), ('LC', 'Saint Lucia'), ('LI', 'Liechtenstein'), ('LK', 'Sri Lanka'), ('LR', 'Liberia'), ('LS', 'Lesotho'), ('LT', 'Lithuania'), ('LU', 'Luxembourg'), ('LV', 'Latvia'), ('LY', 'Libyan Arab Jamahiriya'), ('MA', 'Morocco'), ('MC', 'Monaco'), ('MD', 'Moldova, Republic of'), ('MG', 'Madagascar'), ('MH', 'Marshall Islands'), ('ML', 'Mali'), ('MN', 'Mongolia'), ('MM', 'Myanmar'), ('MO', 'Macau'), ('MP', 'Northern Mariana Islands'), ('MQ', 'Martinique'), ('MR', 'Mauritania'), ('MS', 'Monserrat'), ('MT', 'Malta'), ('MU', 'Mauritius'), ('MV', 'Maldives'), ('MW', 'Malawi'), ('MX', 'Mexico'), ('MY', 'Malaysia'), ('MZ', 'Mozambique'), ('NA', 'Namibia'), ('NC', 'New Caledonia'), ('NE', 'Niger'), ('NF', 'Norfolk Island'), ('NG', 'Nigeria'), ('NI', 'Nicaragua'), ('NL', 'Netherlands'), ('NO', 'Norway'), ('NP', 'Nepal'), ('NR', 'Nauru'), ('NU', 'Niue'), ('NZ', 'New Zealand'), ('OM', 'Oman'), ('PA', 'Panama'), ('PE', 'Peru'), ('PF', 'French Polynesia'), ('PG', 'Papua New Guinea'), ('PH', 'Philippines'), ('PK', 'Pakistan'), ('PL', 'Poland'), ('PM', 'St. Pierre & Miquelon'), ('PN', 'Pitcairn'), ('PR', 'Puerto Rico'), ('PT', 'Portugal'), ('PW', 'Palau'), ('PY', 'Paraguay'), ('QA', 'Qatar'), ('RE', 'Reunion'), ('RO', 'Romania'), ('RU', 'Russian Federation'), ('RW', 'Rwanda'), ('SA', 'Saudi Arabia'), ('SB', 'Solomon Islands'), ('SC', 'Seychelles'), ('SD', 'Sudan'), ('SE', 'Sweden'), ('SG', 'Singapore'), ('SH', 'St. Helena'), ('SI', 'Slovenia'), ('SJ', 'Svalbard & Jan Mayen Islands'), ('SK', 'Slovakia'), ('SL', 'Sierra Leone'), ('SM', 'San Marino'), ('SN', 'Senegal'), ('SO', 'Somalia'), ('SR', 'Suriname'), ('ST', 'Sao Tome & Principe'), ('SV', 'El Salvador'), ('SY', 'Syrian Arab Republic'), ('SZ', 'Swaziland'), ('TC', 'Turks & Caicos Islands'), ('TD', 'Chad'), ('TF', 'French Southern Territories'), ('TG', 'Togo'), ('TH', 'Thailand'), ('TJ', 'Tajikistan'), ('TK', 'Tokelau'), ('TM', 'Turkmenistan'), ('TN', 'Tunisia'), ('TO', 'Tonga'), ('TP', 'East Timor'), ('TR', 'Turkey'), ('TT', 'Trinidad & Tobago'), ('TV', 'Tuvalu'), ('TW', 'Taiwan, Province of China'), ('TZ', 'Tanzania, United Republic of'), ('UA', 'Ukraine'), ('UG', 'Uganda'), ('UM', 'United States Minor Outlying Islands'), ('US', 'United States of America'), ('UY', 'Uruguay'), ('UZ', 'Uzbekistan'), ('VA', 'Vatican City State (Holy See)'), ('VC', 'St. Vincent & the Grenadines'), ('VE', 'Venezuela'), ('VG', 'British Virgin Islands'), ('VI', 'United States Virgin Islands'), ('VN', 'Viet Nam'), ('VU', 'Vanuatu'), ('WF', 'Wallis & Futuna Islands'), ('WS', 'Samoa'), ('YE', 'Yemen'), ('YT', 'Mayotte'), ('YU', 'Yugoslavia'), ('ZA', 'South Africa'), ('ZM', 'Zambia'), ('ZR', 'Zaire'), ('ZW', 'Zimbabwe')], default='CH', max_length=2)),
+ ('vat_number', models.CharField(blank=True, default='', max_length=100)),
+ ('stripe_tax_id', models.CharField(blank=True, default='', max_length=100)),
+ ('vat_number_validated_on', models.DateTimeField(blank=True, null=True)),
+ ('vat_validation_status', models.CharField(blank=True, default='', max_length=25)),
+ ],
+ options={
+ 'abstract': False,
+ },
+ ),
+ migrations.CreateModel(
+ name='ContactMessage',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=200)),
+ ('email', models.EmailField(max_length=254)),
+ ('phone_number', models.CharField(blank=True, max_length=200)),
+ ('message', models.TextField()),
+ ('received_date', models.DateTimeField(auto_now_add=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='UserBillingAddress',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('cardholder_name', models.CharField(default='', max_length=100)),
+ ('street_address', models.CharField(max_length=100)),
+ ('city', models.CharField(max_length=50)),
+ ('postal_code', models.CharField(max_length=50)),
+ ('country', utils.fields.CountryField(choices=[('AD', 'Andorra'), ('AE', 'United Arab Emirates'), ('AF', 'Afghanistan'), ('AG', 'Antigua & Barbuda'), ('AI', 'Anguilla'), ('AL', 'Albania'), ('AM', 'Armenia'), ('AN', 'Netherlands Antilles'), ('AO', 'Angola'), ('AQ', 'Antarctica'), ('AR', 'Argentina'), ('AS', 'American Samoa'), ('AT', 'Austria'), ('AU', 'Australia'), ('AW', 'Aruba'), ('AZ', 'Azerbaijan'), ('BA', 'Bosnia and Herzegovina'), ('BB', 'Barbados'), ('BD', 'Bangladesh'), ('BE', 'Belgium'), ('BF', 'Burkina Faso'), ('BG', 'Bulgaria'), ('BH', 'Bahrain'), ('BI', 'Burundi'), ('BJ', 'Benin'), ('BM', 'Bermuda'), ('BN', 'Brunei Darussalam'), ('BO', 'Bolivia'), ('BR', 'Brazil'), ('BS', 'Bahama'), ('BT', 'Bhutan'), ('BV', 'Bouvet Island'), ('BW', 'Botswana'), ('BY', 'Belarus'), ('BZ', 'Belize'), ('CA', 'Canada'), ('CC', 'Cocos (Keeling) Islands'), ('CF', 'Central African Republic'), ('CG', 'Congo'), ('CH', 'Switzerland'), ('CI', 'Ivory Coast'), ('CK', 'Cook Iislands'), ('CL', 'Chile'), ('CM', 'Cameroon'), ('CN', 'China'), ('CO', 'Colombia'), ('CR', 'Costa Rica'), ('CU', 'Cuba'), ('CV', 'Cape Verde'), ('CX', 'Christmas Island'), ('CY', 'Cyprus'), ('CZ', 'Czech Republic'), ('DE', 'Germany'), ('DJ', 'Djibouti'), ('DK', 'Denmark'), ('DM', 'Dominica'), ('DO', 'Dominican Republic'), ('DZ', 'Algeria'), ('EC', 'Ecuador'), ('EE', 'Estonia'), ('EG', 'Egypt'), ('EH', 'Western Sahara'), ('ER', 'Eritrea'), ('ES', 'Spain'), ('ET', 'Ethiopia'), ('FI', 'Finland'), ('FJ', 'Fiji'), ('FK', 'Falkland Islands (Malvinas)'), ('FM', 'Micronesia'), ('FO', 'Faroe Islands'), ('FR', 'France'), ('FX', 'France, Metropolitan'), ('GA', 'Gabon'), ('GB', 'United Kingdom (Great Britain)'), ('GD', 'Grenada'), ('GE', 'Georgia'), ('GF', 'French Guiana'), ('GH', 'Ghana'), ('GI', 'Gibraltar'), ('GL', 'Greenland'), ('GM', 'Gambia'), ('GN', 'Guinea'), ('GP', 'Guadeloupe'), ('GQ', 'Equatorial Guinea'), ('GR', 'Greece'), ('GS', 'South Georgia and the South Sandwich Islands'), ('GT', 'Guatemala'), ('GU', 'Guam'), ('GW', 'Guinea-Bissau'), ('GY', 'Guyana'), ('HK', 'Hong Kong'), ('HM', 'Heard & McDonald Islands'), ('HN', 'Honduras'), ('HR', 'Croatia'), ('HT', 'Haiti'), ('HU', 'Hungary'), ('ID', 'Indonesia'), ('IE', 'Ireland'), ('IL', 'Israel'), ('IN', 'India'), ('IO', 'British Indian Ocean Territory'), ('IQ', 'Iraq'), ('IR', 'Islamic Republic of Iran'), ('IS', 'Iceland'), ('IT', 'Italy'), ('JM', 'Jamaica'), ('JO', 'Jordan'), ('JP', 'Japan'), ('KE', 'Kenya'), ('KG', 'Kyrgyzstan'), ('KH', 'Cambodia'), ('KI', 'Kiribati'), ('KM', 'Comoros'), ('KN', 'St. Kitts and Nevis'), ('KP', "Korea, Democratic People's Republic of"), ('KR', 'Korea, Republic of'), ('KW', 'Kuwait'), ('KY', 'Cayman Islands'), ('KZ', 'Kazakhstan'), ('LA', "Lao People's Democratic Republic"), ('LB', 'Lebanon'), ('LC', 'Saint Lucia'), ('LI', 'Liechtenstein'), ('LK', 'Sri Lanka'), ('LR', 'Liberia'), ('LS', 'Lesotho'), ('LT', 'Lithuania'), ('LU', 'Luxembourg'), ('LV', 'Latvia'), ('LY', 'Libyan Arab Jamahiriya'), ('MA', 'Morocco'), ('MC', 'Monaco'), ('MD', 'Moldova, Republic of'), ('MG', 'Madagascar'), ('MH', 'Marshall Islands'), ('ML', 'Mali'), ('MN', 'Mongolia'), ('MM', 'Myanmar'), ('MO', 'Macau'), ('MP', 'Northern Mariana Islands'), ('MQ', 'Martinique'), ('MR', 'Mauritania'), ('MS', 'Monserrat'), ('MT', 'Malta'), ('MU', 'Mauritius'), ('MV', 'Maldives'), ('MW', 'Malawi'), ('MX', 'Mexico'), ('MY', 'Malaysia'), ('MZ', 'Mozambique'), ('NA', 'Namibia'), ('NC', 'New Caledonia'), ('NE', 'Niger'), ('NF', 'Norfolk Island'), ('NG', 'Nigeria'), ('NI', 'Nicaragua'), ('NL', 'Netherlands'), ('NO', 'Norway'), ('NP', 'Nepal'), ('NR', 'Nauru'), ('NU', 'Niue'), ('NZ', 'New Zealand'), ('OM', 'Oman'), ('PA', 'Panama'), ('PE', 'Peru'), ('PF', 'French Polynesia'), ('PG', 'Papua New Guinea'), ('PH', 'Philippines'), ('PK', 'Pakistan'), ('PL', 'Poland'), ('PM', 'St. Pierre & Miquelon'), ('PN', 'Pitcairn'), ('PR', 'Puerto Rico'), ('PT', 'Portugal'), ('PW', 'Palau'), ('PY', 'Paraguay'), ('QA', 'Qatar'), ('RE', 'Reunion'), ('RO', 'Romania'), ('RU', 'Russian Federation'), ('RW', 'Rwanda'), ('SA', 'Saudi Arabia'), ('SB', 'Solomon Islands'), ('SC', 'Seychelles'), ('SD', 'Sudan'), ('SE', 'Sweden'), ('SG', 'Singapore'), ('SH', 'St. Helena'), ('SI', 'Slovenia'), ('SJ', 'Svalbard & Jan Mayen Islands'), ('SK', 'Slovakia'), ('SL', 'Sierra Leone'), ('SM', 'San Marino'), ('SN', 'Senegal'), ('SO', 'Somalia'), ('SR', 'Suriname'), ('ST', 'Sao Tome & Principe'), ('SV', 'El Salvador'), ('SY', 'Syrian Arab Republic'), ('SZ', 'Swaziland'), ('TC', 'Turks & Caicos Islands'), ('TD', 'Chad'), ('TF', 'French Southern Territories'), ('TG', 'Togo'), ('TH', 'Thailand'), ('TJ', 'Tajikistan'), ('TK', 'Tokelau'), ('TM', 'Turkmenistan'), ('TN', 'Tunisia'), ('TO', 'Tonga'), ('TP', 'East Timor'), ('TR', 'Turkey'), ('TT', 'Trinidad & Tobago'), ('TV', 'Tuvalu'), ('TW', 'Taiwan, Province of China'), ('TZ', 'Tanzania, United Republic of'), ('UA', 'Ukraine'), ('UG', 'Uganda'), ('UM', 'United States Minor Outlying Islands'), ('US', 'United States of America'), ('UY', 'Uruguay'), ('UZ', 'Uzbekistan'), ('VA', 'Vatican City State (Holy See)'), ('VC', 'St. Vincent & the Grenadines'), ('VE', 'Venezuela'), ('VG', 'British Virgin Islands'), ('VI', 'United States Virgin Islands'), ('VN', 'Viet Nam'), ('VU', 'Vanuatu'), ('WF', 'Wallis & Futuna Islands'), ('WS', 'Samoa'), ('YE', 'Yemen'), ('YT', 'Mayotte'), ('YU', 'Yugoslavia'), ('ZA', 'South Africa'), ('ZM', 'Zambia'), ('ZR', 'Zaire'), ('ZW', 'Zimbabwe')], default='CH', max_length=2)),
+ ('vat_number', models.CharField(blank=True, default='', max_length=100)),
+ ('stripe_tax_id', models.CharField(blank=True, default='', max_length=100)),
+ ('vat_number_validated_on', models.DateTimeField(blank=True, null=True)),
+ ('vat_validation_status', models.CharField(blank=True, default='', max_length=25)),
+ ('current', models.BooleanField(default=True)),
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='billing_addresses', to=settings.AUTH_USER_MODEL)),
+ ],
+ options={
+ 'abstract': False,
+ },
+ ),
+ ]
diff --git a/utils/migrations/__init__.py b/utils/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/utils/mixins.py b/utils/mixins.py
new file mode 100755
index 0000000..ebcb221
--- /dev/null
+++ b/utils/mixins.py
@@ -0,0 +1,31 @@
+from guardian.shortcuts import assign_perm
+
+
+class AssignPermissionsMixin(object):
+ permissions = tuple()
+ user = None
+ obj = None
+ kwargs = dict()
+
+ def assign_permissions(self, user):
+ for permission in self.permissions:
+ assign_perm(permission, user, self)
+
+ # def save(self, *args, **kwargs):
+ # self.kwargs = kwargs
+ # self.get_objs()
+
+ # create = False
+ # if not self.pk:
+ # create = True
+
+ # super(AssignPermissionsMixin, self).save(*args, **kwargs)
+
+ # if create:
+ # self.assign_permissions()
+
+ # def get_objs(self):
+ # self.user = self.kwargs.pop('user', None)
+ # self.obj = self.kwargs.pop('obj', None)
+ # assert self.user, 'Se necesita el parámetro user para poder asignar los permisos'
+ # assert self.obj, 'Se necesita el parámetro obj para poder asignar los permisos'
diff --git a/utils/models.py b/utils/models.py
new file mode 100755
index 0000000..98882c5
--- /dev/null
+++ b/utils/models.py
@@ -0,0 +1,79 @@
+from django.db import models
+
+from membership.models import CustomUser
+
+from .fields import CountryField
+
+
+# Create your models here.
+
+class BaseBillingAddress(models.Model):
+ cardholder_name = models.CharField(max_length=100, default="")
+ street_address = models.CharField(max_length=100)
+ city = models.CharField(max_length=50)
+ postal_code = models.CharField(max_length=50)
+ country = CountryField()
+ vat_number = models.CharField(max_length=100, default="", blank=True)
+ stripe_tax_id = models.CharField(max_length=100, default="", blank=True)
+ vat_number_validated_on = models.DateTimeField(blank=True, null=True)
+ vat_validation_status = models.CharField(max_length=25, default="",
+ blank=True)
+
+ class Meta:
+ abstract = True
+
+
+class BillingAddress(BaseBillingAddress):
+ def __str__(self):
+ if self.vat_number:
+ return "%s, %s, %s, %s, %s, %s %s %s %s" % (
+ self.cardholder_name, self.street_address, self.city,
+ self.postal_code, self.country, self.vat_number,
+ self.stripe_tax_id, self.vat_number_validated_on,
+ self.vat_validation_status
+ )
+ else:
+ return "%s, %s, %s, %s, %s" % (
+ self.cardholder_name, self.street_address, self.city,
+ self.postal_code, self.country
+ )
+
+
+class UserBillingAddress(BaseBillingAddress):
+ user = models.ForeignKey(CustomUser, related_name='billing_addresses', on_delete=models.CASCADE)
+ current = models.BooleanField(default=True)
+
+ def __str__(self):
+ if self.vat_number:
+ return "%s, %s, %s, %s, %s, %s %s %s %s" % (
+ self.cardholder_name, self.street_address, self.city,
+ self.postal_code, self.country, self.vat_number,
+ self.stripe_tax_id, self.vat_number_validated_on,
+ self.vat_validation_status
+ )
+ else:
+ return "%s, %s, %s, %s, %s" % (
+ self.cardholder_name, self.street_address, self.city,
+ self.postal_code, self.country
+ )
+
+ def to_dict(self):
+ return {
+ 'Cardholder Name': self.cardholder_name,
+ 'Street Address': self.street_address,
+ 'City': self.city,
+ 'Postal Code': self.postal_code,
+ 'Country': self.country,
+ 'VAT Number': self.vat_number
+ }
+
+
+class ContactMessage(models.Model):
+ name = models.CharField(max_length=200)
+ email = models.EmailField()
+ phone_number = models.CharField(max_length=200, blank=True)
+ message = models.TextField()
+ received_date = models.DateTimeField(auto_now_add=True)
+
+ def __str__(self):
+ return "%s - %s - %s" % (self.name, self.email, self.received_date)
diff --git a/utils/optimize/.gitkeep b/utils/optimize/.gitkeep
new file mode 100755
index 0000000..e69de29
diff --git a/utils/stripe_utils.py b/utils/stripe_utils.py
new file mode 100644
index 0000000..d4b3e9e
--- /dev/null
+++ b/utils/stripe_utils.py
@@ -0,0 +1,573 @@
+import logging
+import re
+
+import stripe
+from django.conf import settings
+
+from datacenterlight.models import StripePlan
+
+stripe.api_key = settings.STRIPE_API_PRIVATE_KEY
+logger = logging.getLogger(__name__)
+
+
+def handleStripeError(f):
+ def handleProblems(*args, **kwargs):
+ response = {
+ 'paid': False,
+ 'response_object': None,
+ 'error': None
+ }
+
+ common_message = "Currently it's not possible to make payments."
+ try:
+ response_object = f(*args, **kwargs)
+ response = {
+ 'response_object': response_object,
+ 'error': None
+ }
+ return response
+ except stripe.error.CardError as e:
+ # Since it's a decline, stripe.error.CardError will be caught
+ body = e.json_body
+ err = body['error']
+ response.update({'error': err['message']})
+ logger.error(str(e))
+ return response
+ except stripe.error.RateLimitError as e:
+ logger.error(str(e))
+ response.update(
+ {'error': "Too many requests made to the API too quickly"})
+ return response
+ except stripe.error.InvalidRequestError as e:
+ logger.error(str(e))
+ response.update({'error': str(e._message)})
+ return response
+ except stripe.error.AuthenticationError as e:
+ # Authentication with Stripe's API failed
+ # (maybe you changed API keys recently)
+ logger.error(str(e))
+ response.update({'error': str(e)})
+ return response
+ except stripe.error.APIConnectionError as e:
+ logger.error(str(e))
+ response.update({'error': str(e)})
+ return response
+ except stripe.error.StripeError as e:
+ # maybe send email
+ logger.error(str(e))
+ response.update({'error': str(e)})
+ return response
+ except Exception as e:
+ # maybe send email
+ logger.error(str(e))
+ response.update({'error': str(e)})
+ return response
+
+ return handleProblems
+
+
+class StripeUtils(object):
+ CURRENCY = 'chf'
+ INTERVAL = 'month'
+ SUCCEEDED_STATUS = 'succeeded'
+ RESOURCE_ALREADY_EXISTS_ERROR_CODE = 'resource_already_exists'
+ STRIPE_NO_SUCH_PLAN = 'No such plan'
+ PLAN_EXISTS_ERROR_MSG = 'Plan {} exists already.\nCreating a local StripePlan now.'
+ PLAN_DOES_NOT_EXIST_ERROR_MSG = 'Plan {} does not exist.'
+
+ def __init__(self):
+ self.stripe = stripe
+
+ def update_customer_token(self, customer, token):
+ customer.source = token
+ customer.save()
+
+ @handleStripeError
+ def associate_customer_card(self, stripe_customer_id, id_payment_method,
+ set_as_default=False):
+ customer = stripe.Customer.retrieve(stripe_customer_id)
+ stripe.PaymentMethod.attach(
+ id_payment_method,
+ customer=stripe_customer_id,
+ )
+ if set_as_default:
+ customer.invoice_settings.default_payment_method = id_payment_method
+ customer.save()
+ return True
+
+ @handleStripeError
+ def dissociate_customer_card(self, stripe_customer_id, card_id):
+ customer = stripe.Customer.retrieve(stripe_customer_id)
+ if card_id.startswith("pm"):
+ logger.debug("PaymentMethod %s detached %s" % (card_id,
+ stripe_customer_id))
+ pm = stripe.PaymentMethod.retrieve(card_id)
+ stripe.PaymentMethod.detach(card_id)
+ pm.delete()
+ else:
+ logger.debug("card %s detached %s" % (card_id, stripe_customer_id))
+ card = customer.sources.retrieve(card_id)
+ card.delete()
+
+ @handleStripeError
+ def update_customer_card(self, customer_id, token):
+ customer = stripe.Customer.retrieve(customer_id)
+ current_card_token = customer.default_source
+ customer.sources.retrieve(current_card_token).delete()
+ customer.source = token
+ customer.save()
+ credit_card_raw_data = customer.sources.data.pop()
+ new_card_data = {
+ 'last4': credit_card_raw_data.last4,
+ 'brand': credit_card_raw_data.brand
+ }
+ return new_card_data
+
+ @handleStripeError
+ def get_card_details(self, customer_id):
+ customer = stripe.Customer.retrieve(customer_id)
+ credit_card_raw_data = customer.sources.data.pop()
+ card_details = {
+ 'last4': credit_card_raw_data.last4,
+ 'brand': credit_card_raw_data.brand,
+ 'exp_month': credit_card_raw_data.exp_month,
+ 'exp_year': credit_card_raw_data.exp_year,
+ 'fingerprint': credit_card_raw_data.fingerprint,
+ 'card_id': credit_card_raw_data.id
+ }
+ return card_details
+
+ @handleStripeError
+ def get_all_invoices(self, customer_id, created_gt):
+ return_list = []
+ has_more_invoices = True
+ starting_after = False
+ while has_more_invoices:
+ if starting_after:
+ invoices = stripe.Invoice.list(
+ limit=10, customer=customer_id, created={'gt': created_gt},
+ starting_after=starting_after
+ )
+ else:
+ invoices = stripe.Invoice.list(
+ limit=10, customer=customer_id, created={'gt': created_gt}
+ )
+ has_more_invoices = invoices.has_more
+ for invoice in invoices.data:
+ sub_ids = []
+ for line in invoice.lines.data:
+ if line.type == 'subscription':
+ sub_ids.append(line.id)
+ elif line.type == 'invoiceitem':
+ sub_ids.append(line.subscription)
+ else:
+ sub_ids.append('')
+ invoice_details = {
+ 'created': invoice.created,
+ 'receipt_number': invoice.receipt_number,
+ 'invoice_number': invoice.number,
+ 'paid_at': invoice.status_transitions.paid_at if invoice.paid else 0,
+ 'period_start': invoice.period_start,
+ 'period_end': invoice.period_end,
+ 'billing_reason': invoice.billing_reason,
+ 'discount': invoice.discount.coupon.amount_off if invoice.discount else 0,
+ 'total': invoice.total,
+ # to see how many line items we have in this invoice and
+ # then later check if we have more than 1
+ 'lines_data_count': len(invoice.lines.data) if invoice.lines.data is not None else 0,
+ 'invoice_id': invoice.id,
+ 'lines_meta_data_csv': ','.join(
+ [line.metadata.VM_ID if hasattr(line.metadata, 'VM_ID') else '' for line in invoice.lines.data]
+ ),
+ 'subscription_ids_csv': ','.join(sub_ids),
+ 'line_items': invoice.lines.data
+ }
+ starting_after = invoice.id
+ return_list.append(invoice_details)
+ return return_list
+
+ @handleStripeError
+ def get_cards_details_from_token(self, token):
+ stripe_token = stripe.Token.retrieve(token)
+ card_details = {
+ 'last4': stripe_token.card.last4,
+ 'brand': stripe_token.card.brand,
+ 'exp_month': stripe_token.card.exp_month,
+ 'exp_year': stripe_token.card.exp_year,
+ 'fingerprint': stripe_token.card.fingerprint,
+ 'card_id': stripe_token.card.id
+ }
+ return card_details
+
+ @handleStripeError
+ def get_cards_details_from_payment_method(self, payment_method_id):
+ payment_method = stripe.PaymentMethod.retrieve(payment_method_id)
+ # payment_method does not always seem to have a card with id
+ # if that is the case, fallback to payment_method_id for card_id
+ card_id = payment_method_id
+ if hasattr(payment_method.card, 'id'):
+ card_id = payment_method.card.id
+ card_details = {
+ 'last4': payment_method.card.last4,
+ 'brand': payment_method.card.brand,
+ 'exp_month': payment_method.card.exp_month,
+ 'exp_year': payment_method.card.exp_year,
+ 'fingerprint': payment_method.card.fingerprint,
+ 'card_id': card_id
+ }
+ return card_details
+
+ def check_customer(self, stripe_cus_api_id, user, token):
+ try:
+ customer = stripe.Customer.retrieve(stripe_cus_api_id)
+ except stripe.InvalidRequestError:
+ customer = self.create_customer(token, user.email, user.name)
+ user.stripecustomer.stripe_id = customer.get(
+ 'response_object').get('id')
+ user.stripecustomer.save()
+ if type(customer) is dict:
+ customer = customer['response_object']
+ return customer
+
+ @handleStripeError
+ def get_customer(self, stripe_api_cus_id):
+ customer = stripe.Customer.retrieve(stripe_api_cus_id)
+ # data = customer.get('response_object')
+ return customer
+
+ @handleStripeError
+ def create_customer(self, id_payment_method, email, name=None):
+ if name is None or name.strip() == "":
+ name = email
+ customer = self.stripe.Customer.create(
+ payment_method=id_payment_method,
+ description=name,
+ email=email
+ )
+ return customer
+
+ @handleStripeError
+ def make_charge(self, amount=None, customer=None):
+ _amount = float(amount)
+ amount = int(_amount * 100) # stripe amount unit, in cents
+ charge = self.stripe.Charge.create(
+ amount=amount, # in cents
+ currency=self.CURRENCY,
+ customer=customer
+ )
+ return charge
+
+ @handleStripeError
+ def get_or_create_stripe_plan(self, amount, name, stripe_plan_id,
+ interval=""):
+ """
+ This function checks if a StripePlan with the given
+ stripe_plan_id already exists. If it exists then the function
+ returns this object otherwise it creates a new StripePlan and
+ returns the new object.
+
+ :param amount: The amount in CHF
+ :param name: The name of the Stripe plan to be created.
+ :param stripe_plan_id: The id of the Stripe plan to be
+ created. Use get_stripe_plan_id_string function to
+ obtain the name of the plan to be created
+ :param interval: str representing the interval of the Plan
+ Specifies billing frequency. Either day, week, month or year.
+ Ref: https://stripe.com/docs/api/plans/create#create_plan-interval
+ The default is month
+ :return: The StripePlan object if it exists else creates a
+ Plan object in Stripe and a local StripePlan and
+ returns it. Returns None in case of Stripe error
+ """
+ _amount = float(amount)
+ amount = int(_amount * 100) # stripe amount unit, in cents
+ stripe_plan_db_obj = None
+ plan_interval = interval if interval != "" else self.INTERVAL
+ try:
+ stripe_plan_db_obj = StripePlan.objects.get(
+ stripe_plan_id=stripe_plan_id)
+ except StripePlan.DoesNotExist:
+ try:
+ self.stripe.Plan.create(
+ amount=amount,
+ interval=plan_interval,
+ name=name,
+ currency=self.CURRENCY,
+ id=stripe_plan_id)
+ stripe_plan_db_obj = StripePlan.objects.create(
+ stripe_plan_id=stripe_plan_id)
+ except stripe.error.InvalidRequestError as e:
+ logger.error(str(e))
+ logger.error("error_code = %s" % str(e.__dict__))
+ if self.RESOURCE_ALREADY_EXISTS_ERROR_CODE in e.error.code:
+ logger.debug(
+ self.PLAN_EXISTS_ERROR_MSG.format(stripe_plan_id))
+ stripe_plan_db_obj, c = StripePlan.objects.get_or_create(
+ stripe_plan_id=stripe_plan_id)
+ if c:
+ logger.debug("Created stripe plan %s" % stripe_plan_id)
+ else:
+ logger.debug("Plan %s exists already" % stripe_plan_id)
+ return stripe_plan_db_obj
+
+ @handleStripeError
+ def delete_stripe_plan(self, stripe_plan_id):
+ """
+ Deletes the Plan in Stripe and also deletes the local db copy
+ of the plan if it exists
+
+ :param stripe_plan_id: The stripe plan id that needs to be
+ deleted
+ :return: True if the plan was deleted successfully from
+ Stripe, False otherwise.
+ """
+ return_value = False
+ try:
+ plan = self.stripe.Plan.retrieve(stripe_plan_id)
+ plan.delete()
+ return_value = True
+ StripePlan.objects.filter(
+ stripe_plan_id=stripe_plan_id).all().delete()
+ except stripe.error.InvalidRequestError as e:
+ if self.STRIPE_NO_SUCH_PLAN in str(e):
+ logger.debug(
+ self.PLAN_DOES_NOT_EXIST_ERROR_MSG.format(stripe_plan_id))
+ return return_value
+
+ @handleStripeError
+ def subscribe_customer_to_plan(self, customer, plans, trial_end=None,
+ coupon="", tax_rates=list(),
+ default_payment_method=""):
+ """
+ Subscribes the given customer to the list of given plans
+
+ :param default_payment_method:
+ :param tax_rates:
+ :param coupon:
+ :param customer: The stripe customer identifier
+ :param plans: A list of stripe plans.
+ :param trial_end: An integer representing when the Stripe subscription
+ is supposed to end
+ Ref: https://stripe.com/docs/api/python#create_subscription-items
+ e.g.
+ plans = [
+ {
+ "plan": "dcl-v1-cpu-2-ram-5gb-ssd-10gb",
+ },
+ ]
+ :return: The subscription StripeObject
+ """
+ logger.debug("Subscribing %s to plan %s : coupon = %s" % (
+ customer, str(plans), str(coupon)
+ ))
+ subscription_result = self.stripe.Subscription.create(
+ customer=customer, items=plans, trial_end=trial_end,
+ coupon=coupon,
+ default_tax_rates=tax_rates,
+ payment_behavior='allow_incomplete',
+ default_payment_method=default_payment_method
+ )
+ logger.debug("Done subscribing")
+ return subscription_result
+
+ @handleStripeError
+ def set_subscription_metadata(self, subscription_id, metadata):
+ subscription = stripe.Subscription.retrieve(subscription_id)
+ subscription.metadata = metadata
+ subscription.save()
+
+ @handleStripeError
+ def unsubscribe_customer(self, subscription_id):
+ """
+ Cancels a given subscription
+
+ :param subscription_id: The Stripe subscription id string
+ :return:
+ """
+ sub = stripe.Subscription.retrieve(subscription_id)
+ return sub.delete()
+
+ @handleStripeError
+ def make_payment(self, customer, amount, token):
+ charge = self.stripe.Charge.create(
+ amount=amount, # in cents
+ currency=self.CURRENCY,
+ customer=customer
+ )
+ return charge
+
+ @staticmethod
+ def get_stripe_plan_id(cpu, ram, ssd, version, app='dcl', hdd=None,
+ price=None, excl_vat=True):
+ """
+ Returns the Stripe plan id string of the form
+ `dcl-v1-cpu-2-ram-5gb-ssd-10gb` based on the input parameters
+
+ :param cpu: The number of cores
+ :param ram: The size of the RAM in GB
+ :param ssd: The size of ssd storage in GB
+ :param hdd: The size of hdd storage in GB
+ :param version: The version of the Stripe plans
+ :param app: The application to which the stripe plan belongs
+ to. By default it is 'dcl'
+ :param price: The price for this plan
+ :return: A string of the form `dcl-v1-cpu-2-ram-5gb-ssd-10gb`
+ """
+ dcl_plan_string = 'cpu-{cpu}-ram-{ram}gb-ssd-{ssd}gb'.format(cpu=cpu,
+ ram=ram,
+ ssd=ssd)
+ if hdd is not None:
+ dcl_plan_string = '{dcl_plan_string}-hdd-{hdd}gb'.format(
+ dcl_plan_string=dcl_plan_string, hdd=hdd)
+ stripe_plan_id_string = '{app}-v{version}-{plan}'.format(
+ app=app,
+ version=version,
+ plan=dcl_plan_string
+ )
+ if price is not None:
+ stripe_plan_id_string = '{}-{}chf'.format(
+ stripe_plan_id_string,
+ round(price, 2)
+ )
+ if excl_vat:
+ stripe_plan_id_string = '{}-{}'.format(
+ stripe_plan_id_string,
+ "excl_vat"
+ )
+ return stripe_plan_id_string
+
+ @staticmethod
+ def get_vm_config_from_stripe_id(stripe_id):
+ """
+ Given a string like "dcl-v1-cpu-2-ram-5gb-ssd-10gb" return different
+ configuration params as a dict
+
+ :param stripe_id|str
+ :return: dict
+ """
+ pattern = re.compile(r'^dcl-v(\d+)-cpu-(\d+)-ram-(\d+\.?\d*)gb-ssd-(\d+)gb-?(\d*\.?\d*)(chf)?$')
+ match_res = pattern.match(stripe_id)
+ if match_res is not None:
+ price = None
+ try:
+ price=match_res.group(5)
+ except IndexError as ie:
+ logger.debug("Did not find price in {}".format(stripe_id))
+ return {
+ 'version': match_res.group(1),
+ 'cores': match_res.group(2),
+ 'ram': match_res.group(3),
+ 'ssd': match_res.group(4),
+ 'price': price
+ }
+
+
+ @staticmethod
+ def get_stripe_plan_name(cpu, memory, disk_size, price, excl_vat=True):
+ """
+ Returns the Stripe plan name
+ :return:
+ """
+ if excl_vat:
+ return "{cpu} Cores, {memory} GB RAM, {disk_size} GB SSD, " \
+ "{price} CHF Excl. VAT".format(
+ cpu=cpu,
+ memory=memory,
+ disk_size=disk_size,
+ price=round(price, 2)
+ )
+ else:
+ return "{cpu} Cores, {memory} GB RAM, {disk_size} GB SSD, " \
+ "{price} CHF".format(
+ cpu=cpu,
+ memory=memory,
+ disk_size=disk_size,
+ price=round(price, 2)
+ )
+
+ @handleStripeError
+ def set_subscription_meta_data(self, subscription_id, meta_data):
+ """
+ Adds VM metadata to a subscription
+ :param subscription_id: Stripe identifier for the subscription
+ :param meta_data: A dict of meta data to be added
+ :return:
+ """
+ subscription = stripe.Subscription.retrieve(subscription_id)
+ subscription.metadata = meta_data
+ subscription.save()
+
+ @handleStripeError
+ def get_or_create_tax_id_for_user(self, stripe_customer_id, vat_number,
+ type="eu_vat", country=""):
+ tax_ids_list = stripe.Customer.list_tax_ids(
+ stripe_customer_id,
+ limit=100,
+ )
+ for tax_id_obj in tax_ids_list.data:
+ if self.compare_vat_numbers(tax_id_obj.value, vat_number):
+ logger.debug("tax id obj exists already")
+ return tax_id_obj
+ else:
+ logger.debug(
+ "{val1} is not equal to {val2} or {con1} not same as "
+ "{con2}".format(val1=tax_id_obj.value, val2=vat_number,
+ con1=tax_id_obj.country.lower(),
+ con2=country.lower().strip()))
+ logger.debug(
+ "tax id obj does not exist for {val}. Creating a new one".format(
+ val=vat_number
+ ))
+ tax_id_obj = stripe.Customer.create_tax_id(
+ stripe_customer_id,
+ type=type,
+ value=vat_number,
+ )
+ return tax_id_obj
+
+ @handleStripeError
+ def get_payment_intent(self, amount, customer):
+ """ Create a stripe PaymentIntent of the given amount and return it
+ :param amount: the amount of payment_intent
+ :return:
+ """
+ payment_intent_obj = stripe.PaymentIntent.create(
+ amount=amount,
+ currency='chf',
+ customer=customer,
+ setup_future_usage='off_session'
+ )
+ return payment_intent_obj
+
+ @handleStripeError
+ def get_available_payment_methods(self, customer):
+ """ Retrieves all payment methods of the given customer
+ :param customer: StripeCustomer object
+ :return: a list of available payment methods
+ """
+ return_list = []
+ if customer is None:
+ return return_list
+ cu = stripe.Customer.retrieve(customer.stripe_id)
+ pms = stripe.PaymentMethod.list(
+ customer=customer.stripe_id,
+ type="card",
+ )
+ default_source = None
+ if cu.default_source:
+ default_source = cu.default_source
+ else:
+ default_source = cu.invoice_settings.default_payment_method
+ for pm in pms.data:
+ return_list.append({
+ 'last4': pm.card.last4, 'brand': pm.card.brand, 'id': pm.id,
+ 'exp_year': pm.card.exp_year,
+ 'exp_month': '{:02d}'.format(pm.card.exp_month),
+ 'preferred': pm.id == default_source
+ })
+ return return_list
+
+ def compare_vat_numbers(self, vat1, vat2):
+ _vat1 = vat1.replace(" ", "").replace(".", "").replace("-","")
+ _vat2 = vat2.replace(" ", "").replace(".", "").replace("-","")
+ return True if _vat1 == _vat2 else False
diff --git a/utils/tasks.py b/utils/tasks.py
new file mode 100644
index 0000000..06d1fb9
--- /dev/null
+++ b/utils/tasks.py
@@ -0,0 +1,98 @@
+import tempfile
+
+import cdist
+from cdist.integration import configure_hosts_simple
+from celery.result import AsyncResult
+from celery import current_task
+from celery.utils.log import get_task_logger
+from django.conf import settings
+from django.core.mail import EmailMessage
+
+from dynamicweb2.pr_celery import app
+
+logger = get_task_logger(__name__)
+
+
+@app.task(bind=True, max_retries=settings.CELERY_MAX_RETRIES)
+def send_plain_email_task(self, email_data):
+ """
+ This is a generic celery task to be used for sending emails.
+ A celery wrapper task for EmailMessage
+
+ :param self:
+ :param email_data: A dict of all needed email headers
+ :return:
+ """
+ email = EmailMessage(**email_data)
+ email.send()
+
+
+@app.task(bind=True, max_retries=settings.CELERY_MAX_RETRIES)
+def save_ssh_key(self, hosts, keys):
+ """
+ Saves ssh key into the VMs of a user using cdist
+
+ :param hosts: A list of hosts to be configured
+ :param keys: A list of keys to be added. A key should be dict of the
+ form {
+ 'value': 'sha-.....', # public key as string
+ 'state': True # whether key is to be added or
+ } # removed
+ """
+ logger.debug(
+ "Running save_ssh_key on {}".format(current_task.request.hostname))
+ logger.debug("""Running save_ssh_key task for
+ Hosts: {hosts_str}
+ Keys: {keys_str}""".format(hosts_str=", ".join(hosts),
+ keys_str=", ".join([
+ "{value}->{state}".format(
+ value=key.get('value'),
+ state=str(
+ key.get('state')))
+ for key in keys]))
+ )
+ return_value = True
+ with tempfile.NamedTemporaryFile(delete=True) as tmp_manifest:
+ # Generate manifest to be used for configuring the hosts
+ lines_list = [
+ ' --key "{key}" --state {state} \\\n'.format(
+ key=key['value'],
+ state='present' if key['state'] else 'absent'
+ ).encode('utf-8')
+ for key in keys]
+ lines_list.insert(0, b'__ssh_authorized_keys root \\\n')
+ tmp_manifest.writelines(lines_list)
+ tmp_manifest.flush()
+ try:
+ configure_hosts_simple(hosts,
+ tmp_manifest.name,
+ verbose=cdist.argparse.VERBOSE_TRACE)
+ except Exception as cdist_exception:
+ logger.error(cdist_exception)
+ return_value = False
+ email_data = {
+ 'subject': "celery save_ssh_key error - task id {0}".format(
+ self.request.id.__str__()),
+ 'from_email': current_task.request.hostname,
+ 'to': settings.DCL_ERROR_EMAILS_TO_LIST,
+ 'body': "Task Id: {0}\nResult: {1}\nTraceback: {2}".format(
+ self.request.id.__str__(), False, str(cdist_exception)),
+ }
+ send_plain_email_task(email_data)
+ return return_value
+
+
+@app.task
+def save_ssh_key_error_handler(uuid):
+ result = AsyncResult(uuid)
+ exc = result.get(propagate=False)
+ logger.error('Task {0} raised exception: {1!r}\n{2!r}'.format(
+ uuid, exc, result.traceback))
+ email_data = {
+ 'subject': "[celery error] Save SSH key error {0}".format(uuid),
+ 'from_email': current_task.request.hostname,
+ 'to': settings.DCL_ERROR_EMAILS_TO_LIST,
+ 'body': "Task Id: {0}\nResult: {1}\nTraceback: {2}".format(
+ uuid, exc, result.traceback),
+ }
+ send_plain_email_task(email_data)
diff --git a/utils/test_forms.py b/utils/test_forms.py
new file mode 100755
index 0000000..5bca7f3
--- /dev/null
+++ b/utils/test_forms.py
@@ -0,0 +1,96 @@
+from django.test import TestCase
+from .forms import ContactUsForm, BillingAddressForm, PasswordResetRequestForm,\
+ SetPasswordForm
+
+from model_mommy import mommy
+
+
+class PasswordResetRequestFormTest(TestCase):
+
+ def setUp(self):
+ self.user = mommy.make('CustomUser')
+ self.completed_data = {
+ 'email': self.user.email,
+ }
+
+ self.incorrect_data = {
+ 'email': 'test',
+ }
+
+ def test_valid_form(self):
+ form = PasswordResetRequestForm(data=self.completed_data)
+ self.assertTrue(form.is_valid())
+
+ def test_invalid_form(self):
+ form = PasswordResetRequestForm(data=self.incorrect_data)
+ self.assertFalse(form.is_valid())
+
+
+class SetPasswordFormTest(TestCase):
+
+ def setUp(self):
+ # self.user = mommy.make('CustomUser')
+ self.completed_data = {
+ 'new_password1': 'new_password',
+ 'new_password2': 'new_password',
+ }
+
+ self.incorrect_data = {
+ 'email': 'test',
+ }
+
+ def test_valid_form(self):
+ form = SetPasswordForm(data=self.completed_data)
+ self.assertTrue(form.is_valid())
+
+ def test_invalid_form(self):
+ form = SetPasswordForm(data=self.incorrect_data)
+ self.assertFalse(form.is_valid())
+
+
+class ContactUsFormTest(TestCase):
+
+ def setUp(self):
+ self.completed_data = {
+ 'name': 'test',
+ 'email': 'test@gmail.com',
+ 'phone_number': '32123123123123',
+ 'message': 'This is a message',
+ }
+
+ self.incompleted_data = {
+ 'name': 'test',
+ }
+
+ def test_valid_form(self):
+ form = ContactUsForm(data=self.completed_data)
+ self.assertTrue(form.is_valid())
+
+ def test_invalid_form(self):
+ form = ContactUsForm(data=self.incompleted_data)
+ self.assertFalse(form.is_valid())
+
+
+class BillingAddressFormTest(TestCase):
+
+ def setUp(self):
+ self.completed_data = {
+ 'cardholder_name': 'test',
+ 'street_address': 'street name',
+ 'city': 'MyCity',
+ 'postal_code': '32123123123123',
+ 'country': 'VE',
+ 'token': 'a23kfmslwxhkwis'
+ }
+
+ self.incompleted_data = {
+ 'street_address': 'test',
+ }
+
+ def test_valid_form(self):
+ form = BillingAddressForm(data=self.completed_data)
+ self.assertTrue(form.is_valid())
+
+ def test_invalid_form(self):
+ form = BillingAddressForm(data=self.incompleted_data)
+ self.assertFalse(form.is_valid())
diff --git a/utils/tests.py b/utils/tests.py
new file mode 100755
index 0000000..8abbbb1
--- /dev/null
+++ b/utils/tests.py
@@ -0,0 +1,306 @@
+import uuid
+from time import sleep
+from unittest.mock import patch
+
+import stripe
+from celery.result import AsyncResult
+from django.conf import settings
+from django.http.request import HttpRequest
+from django.test import Client
+from django.test import TestCase, override_settings
+from unittest import skipIf
+from model_mommy import mommy
+
+from datacenterlight.models import StripePlan
+from membership.models import StripeCustomer
+from utils.stripe_utils import StripeUtils
+from .tasks import save_ssh_key
+
+
+class BaseTestCase(TestCase):
+ """
+ Base class to initialize the test cases
+ """
+
+ def setUp(self):
+ # Password
+ self.dummy_password = 'test_password'
+
+ # Users
+ self.customer, self.another_customer = mommy.make(
+ 'membership.CustomUser', validated=1, _quantity=2
+ )
+ self.customer.set_password(self.dummy_password)
+ self.customer.save()
+ self.another_customer.set_password(self.dummy_password)
+ self.another_customer.save()
+
+ # Stripe mocked data
+ self.stripe_mocked_customer = self.customer_stripe_mocked_data()
+
+ # Clients
+ self.customer_client = self.get_client(self.customer)
+ self.another_customer_client = self.get_client(self.another_customer)
+
+ # Request Object
+ self.request = HttpRequest()
+ self.request.META['SERVER_NAME'] = 'ungleich.ch'
+ self.request.META['SERVER_PORT'] = '80'
+
+ def get_client(self, user):
+ """
+ Authenticate a user and return the client
+ """
+ client = Client()
+ client.login(email=user.email, password=self.dummy_password)
+ return client
+
+ def customer_stripe_mocked_data(self):
+ return {
+ "id": "cus_8R1y9UWaIIjZqr",
+ "object": "customer",
+ "currency": "usd",
+ "default_source": "card_18A9up2eZvKYlo2Cq2RJMGeF",
+ "email": "vmedixtodd+1@gmail.com",
+ "livemode": False,
+ "metadata": {
+ },
+ "shipping": None,
+ "sources": {
+ "object": "list",
+ "data": [{
+ "id": "card_18A9up2eZvKYlo2Cq2RJMGeF",
+ "object": "card",
+ "brand": "Visa",
+ "country": "US",
+ "customer": "cus_8R1y9UWaIIjZqr",
+ "cvc_check": "pass",
+ "dynamic_last4": None,
+ "exp_month": 12,
+ "exp_year": 2018,
+ "funding": "credit",
+ "last4": "4242",
+ }]
+ }
+ }
+
+ def setup_view(self, view, *args, **kwargs):
+ """Mimic as_view() returned callable, but returns view instance.
+
+ args and kwargs are the same you would pass to ``reverse()``
+
+ """
+ view.request = self.request
+ view.args = args
+ view.kwargs = kwargs
+ view.config = None
+ return view
+
+
+@skipIf(settings.STRIPE_API_PRIVATE_KEY_TEST is None or
+ settings.STRIPE_API_PRIVATE_KEY_TEST is "",
+ """Skip because STRIPE_API_PRIVATE_KEY_TEST is not set""")
+class TestStripeCustomerDescription(TestCase):
+ """
+ A class to test setting the description field of the stripe customer
+ https://stripe.com/docs/api#metadata
+ """
+
+ def setUp(self):
+ self.customer_password = 'test_password'
+ self.customer_email = 'test@ungleich.ch'
+ self.customer_name = "Monty Python"
+ self.customer = mommy.make('membership.CustomUser')
+ self.customer.set_password(self.customer_password)
+ self.customer.email = self.customer_email
+ self.customer.save()
+ self.stripe_utils = StripeUtils()
+ stripe.api_key = settings.STRIPE_API_PRIVATE_KEY_TEST
+ self.token = stripe.Token.create(
+ card={
+ "number": '4111111111111111',
+ "exp_month": 12,
+ "exp_year": 2022,
+ "cvc": '123'
+ },
+ )
+ self.failed_token = stripe.Token.create(
+ card={
+ "number": '4000000000000341',
+ "exp_month": 12,
+ "exp_year": 2022,
+ "cvc": '123'
+ },
+ )
+
+ def test_creating_stripe_customer(self):
+ stripe_data = self.stripe_utils.create_customer(self.token.id,
+ self.customer.email,
+ self.customer_name)
+ self.assertEqual(stripe_data.get('error'), None)
+ customer_data = stripe_data.get('response_object')
+ self.assertEqual(customer_data.description, self.customer_name)
+
+
+@skipIf(settings.STRIPE_API_PRIVATE_KEY_TEST == "" or
+ settings.TEST_MANAGE_SSH_KEY_HOST == "",
+ """Skipping test_save_ssh_key_add because either host
+ or public key were not specified or were empty""")
+class StripePlanTestCase(TestStripeCustomerDescription):
+ """
+ A class to test Stripe plans
+ """
+
+ def test_get_stripe_plan_id_string(self):
+ plan_id_string = StripeUtils.get_stripe_plan_id(cpu=2, ram=20, ssd=100,
+ version=1, app='dcl')
+ self.assertEqual(plan_id_string, 'dcl-v1-cpu-2-ram-20gb-ssd-100gb')
+ plan_id_string = StripeUtils.get_stripe_plan_id(cpu=2, ram=20, ssd=100,
+ version=1, app='dcl',
+ hdd=200)
+ self.assertEqual(plan_id_string,
+ 'dcl-v1-cpu-2-ram-20gb-ssd-100gb-hdd-200gb')
+
+ def test_get_or_create_plan(self):
+ stripe_plan = self.stripe_utils.get_or_create_stripe_plan(2000,
+ "test plan 1",
+ stripe_plan_id='test-plan-1')
+ self.assertIsNone(stripe_plan.get('error'))
+ self.assertIsInstance(stripe_plan.get('response_object'), StripePlan)
+
+ @skipIf(settings.TEST_MANAGE_SSH_KEY_PUBKEY == "" or
+ settings.TEST_MANAGE_SSH_KEY_HOST == "",
+ """Skipping test_save_ssh_key_add because either host
+ or public key were not specified or were empty""")
+ @patch('utils.stripe_utils.logger')
+ def test_create_duplicate_plans_error_handling(self, mock_logger):
+ """
+ Test details:
+ 1. Create a test plan in Stripe with a particular id
+ 2. Try to recreate the plan with the same id
+ 3. This creates a Stripe error, the code should be able to handle the error
+
+ :param mock_logger:
+ :return:
+ """
+ unique_id = str(uuid.uuid4().hex)
+ new_plan_id_str = 'test-plan-{}'.format(unique_id)
+ stripe_plan = self.stripe_utils.get_or_create_stripe_plan(2000,
+ "test plan {}".format(
+ unique_id),
+ stripe_plan_id=new_plan_id_str)
+ self.assertIsInstance(stripe_plan.get('response_object'), StripePlan)
+ self.assertEqual(stripe_plan.get('response_object').stripe_plan_id,
+ new_plan_id_str)
+
+ # Test creating the same plan again and expect the PLAN_EXISTS_ERROR_MSG
+ # We first delete the local Stripe Plan, so that the code tries to create a new plan in Stripe
+ StripePlan.objects.filter(
+ stripe_plan_id=new_plan_id_str).all().delete()
+ stripe_plan_1 = self.stripe_utils.get_or_create_stripe_plan(2000,
+ "test plan {}".format(
+ unique_id),
+ stripe_plan_id=new_plan_id_str)
+ mock_logger.debug.assert_called_with(
+ self.stripe_utils.PLAN_EXISTS_ERROR_MSG.format(new_plan_id_str))
+ self.assertIsInstance(stripe_plan_1.get('response_object'), StripePlan)
+ self.assertEqual(stripe_plan_1.get('response_object').stripe_plan_id,
+ new_plan_id_str)
+
+ # Delete the test stripe plan that we just created
+ delete_result = self.stripe_utils.delete_stripe_plan(new_plan_id_str)
+ self.assertIsInstance(delete_result, dict)
+ self.assertEqual(delete_result.get('response_object'), True)
+
+ @patch('utils.stripe_utils.logger')
+ def test_delete_unexisting_plan_should_fail(self, mock_logger):
+ plan_id = 'crazy-plan-id-that-does-not-exist'
+ result = self.stripe_utils.delete_stripe_plan(plan_id)
+ self.assertIsInstance(result, dict)
+ self.assertEqual(result.get('response_object'), False)
+ mock_logger.debug.assert_called_with(
+ self.stripe_utils.PLAN_DOES_NOT_EXIST_ERROR_MSG.format(plan_id))
+
+ def test_subscribe_customer_to_plan(self):
+ stripe_plan = self.stripe_utils.get_or_create_stripe_plan(2000,
+ "test plan 1",
+ stripe_plan_id='test-plan-1')
+ stripe_customer = StripeCustomer.get_or_create(
+ email=self.customer_email,
+ token=self.token)
+ result = self.stripe_utils.subscribe_customer_to_plan(
+ stripe_customer.stripe_id,
+ [{"plan": stripe_plan.get(
+ 'response_object').stripe_plan_id}])
+ self.assertIsInstance(result.get('response_object'),
+ stripe.Subscription)
+ self.assertIsNone(result.get('error'))
+ self.assertEqual(result.get('response_object').get('status'), 'active')
+
+ def test_subscribe_customer_to_plan_failed_payment(self):
+ stripe_plan = self.stripe_utils.get_or_create_stripe_plan(2000,
+ "test plan 1",
+ stripe_plan_id='test-plan-1')
+ stripe_customer = StripeCustomer.get_or_create(
+ email=self.customer_email,
+ token=self.failed_token)
+ result = self.stripe_utils.subscribe_customer_to_plan(
+ stripe_customer.stripe_id,
+ [{"plan": stripe_plan.get(
+ 'response_object').stripe_plan_id}])
+ self.assertIsNone(result.get('response_object'), None)
+ self.assertIsNotNone(result.get('error'))
+
+
+class SaveSSHKeyTestCase(TestCase):
+ """
+ A test case to test the celery save_ssh_key task
+ """
+
+ @override_settings(
+ task_eager_propagates=True,
+ task_always_eager=True,
+ )
+ def setUp(self):
+ self.public_key = settings.TEST_MANAGE_SSH_KEY_PUBKEY
+ self.hosts = settings.TEST_MANAGE_SSH_KEY_HOST
+
+ @skipIf(settings.TEST_MANAGE_SSH_KEY_PUBKEY is "" or
+ settings.TEST_MANAGE_SSH_KEY_PUBKEY is None or
+ settings.TEST_MANAGE_SSH_KEY_HOST is "" or
+ settings.TEST_MANAGE_SSH_KEY_HOST is None,
+ """Skipping test_save_ssh_key_add because either host
+ or public key were not specified or were empty""")
+ def test_save_ssh_key_add(self):
+ async_task = save_ssh_key.delay([self.hosts],
+ [{'value': self.public_key,
+ 'state': True}])
+ save_ssh_key_result = None
+ for i in range(0, 10):
+ sleep(5)
+ res = AsyncResult(async_task.task_id)
+ if type(res.result) is bool:
+ save_ssh_key_result = res.result
+ break
+ self.assertIsNotNone(save_ssh_key, "save_ssh_key_result is None")
+ self.assertTrue(save_ssh_key_result, "save_ssh_key_result is False")
+
+ @skipIf(settings.TEST_MANAGE_SSH_KEY_PUBKEY is None or
+ settings.TEST_MANAGE_SSH_KEY_PUBKEY == "" or
+ settings.TEST_MANAGE_SSH_KEY_HOST is None or
+ settings.TEST_MANAGE_SSH_KEY_HOST is "",
+ """Skipping test_save_ssh_key_add because either host
+ or public key were not specified or were empty""")
+ def test_save_ssh_key_remove(self):
+ async_task = save_ssh_key.delay([self.hosts],
+ [{'value': self.public_key,
+ 'state': False}])
+ save_ssh_key_result = None
+ for i in range(0, 10):
+ sleep(5)
+ res = AsyncResult(async_task.task_id)
+ if type(res.result) is bool:
+ save_ssh_key_result = res.result
+ break
+ self.assertIsNotNone(save_ssh_key, "save_ssh_key_result is None")
+ self.assertTrue(save_ssh_key_result, "save_ssh_key_result is False")
diff --git a/utils/views.py b/utils/views.py
new file mode 100755
index 0000000..838f861
--- /dev/null
+++ b/utils/views.py
@@ -0,0 +1,269 @@
+import uuid
+
+from django.conf import settings
+from django.contrib import messages
+from django.contrib.auth import authenticate, login
+from django.contrib.auth.tokens import default_token_generator
+from django.core.files.base import ContentFile
+from django.urls import reverse_lazy
+from django.http import HttpResponseRedirect
+from django.shortcuts import render
+from django.utils.encoding import force_bytes
+from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
+from django.utils.translation import gettext_lazy as _
+from django.views.decorators.cache import cache_control
+from django.views.generic import FormView, CreateView
+
+from datacenterlight.utils import get_cms_integration
+from hosting.forms import UserHostingKeyForm
+from hosting.models import UserHostingKey
+from membership.models import CustomUser
+from opennebula_api.opennebula_manager import OpenNebulaManager
+from utils.hosting_utils import get_all_public_keys
+from .forms import SetPasswordForm
+from .mailer import BaseEmail
+
+
+class SignupViewMixin(CreateView):
+ model = CustomUser
+ success_url = None
+
+ def get_success_url(self):
+ next_url = self.request.POST.get('next') if self.request.POST.get(
+ 'next') \
+ else self.success_url
+
+ return next_url
+
+ def form_valid(self, form):
+ name = form.cleaned_data.get('name')
+ email = form.cleaned_data.get('email')
+ password = form.cleaned_data.get('password')
+
+ CustomUser.register(name, password, email)
+ auth_user = authenticate(email=email, password=password)
+ login(self.request, auth_user)
+
+ return HttpResponseRedirect(self.get_success_url())
+
+
+class LoginViewMixin(FormView):
+ success_url = None
+
+ def get_success_url(self):
+ next_url = self.request.POST.get('next', self.success_url)
+ if not next_url:
+ return self.success_url
+ return next_url
+
+ def form_valid(self, form):
+ email = form.cleaned_data.get('email')
+ password = form.cleaned_data.get('password')
+ auth_user = authenticate(email=email, password=password)
+
+ if auth_user:
+ login(self.request, auth_user)
+ return HttpResponseRedirect(self.get_success_url())
+
+ return HttpResponseRedirect(self.get_success_url())
+
+ @cache_control(no_cache=True, must_revalidate=True, no_store=True)
+ def get(self, request, *args, **kwargs):
+ if self.request.user.is_authenticated:
+ return HttpResponseRedirect(self.get_success_url())
+
+ return super(LoginViewMixin, self).get(request, *args, **kwargs)
+
+
+class ResendActivationLinkViewMixin(FormView):
+ success_message = _(
+ "An email with the activation link has been sent to you")
+
+ def generate_email_context(self, user):
+ context = {
+ 'base_url': "{0}://{1}".format(self.request.scheme,
+ self.request.get_host()),
+ 'activation_link': reverse_lazy(
+ 'hosting:validate',
+ kwargs={'validate_slug': user.validation_slug}
+ ),
+ 'dcl_text': settings.DCL_TEXT,
+ }
+ return context
+
+ def form_valid(self, form):
+ email = form.cleaned_data.get('email')
+ user = CustomUser.objects.get(email=email)
+ messages.add_message(self.request, messages.SUCCESS,
+ self.success_message)
+ context = self.generate_email_context(user)
+ email_data = {
+ 'subject': '{dcl_text} {account_activation}'.format(
+ dcl_text=settings.DCL_TEXT,
+ account_activation=_('Account Activation')
+ ),
+ 'to': email,
+ 'context': context,
+ 'template_name': self.email_template_name,
+ 'template_path': self.email_template_path,
+ 'from_address': settings.DCL_SUPPORT_FROM_ADDRESS
+ }
+ email = BaseEmail(**email_data)
+ email.send()
+ return HttpResponseRedirect(self.get_success_url())
+
+
+class PasswordResetViewMixin(FormView):
+ success_message = _(
+ "The link to reset your password has been sent to your email")
+ site = ''
+
+ def test_generate_email_context(self, user):
+ context = {
+ 'user': user,
+ 'token': default_token_generator.make_token(user),
+ 'uid': urlsafe_base64_encode(force_bytes(user.pk)),
+ 'site_name': 'ungleich' if self.site != 'dcl' else settings.DCL_TEXT,
+ 'base_url': "{0}://{1}".format(self.request.scheme,
+ self.request.get_host())
+ }
+ return context
+
+ def form_valid(self, form):
+ email = form.cleaned_data.get('email')
+ user = CustomUser.objects.get(email=email)
+ messages.add_message(self.request, messages.SUCCESS,
+ self.success_message)
+ context = self.test_generate_email_context(user)
+ email_data = {
+ 'subject': _('Password Reset'),
+ 'to': email,
+ 'context': context,
+ 'template_name': 'password_reset_email',
+ 'template_path': self.template_email_path
+ }
+ if self.site == 'dcl':
+ email_data['from_address'] = settings.DCL_SUPPORT_FROM_ADDRESS
+ email = BaseEmail(**email_data)
+ email.send()
+
+ return HttpResponseRedirect(self.get_success_url())
+
+
+class PasswordResetConfirmViewMixin(FormView):
+ form_class = SetPasswordForm
+
+ def post(self, request, uidb64=None, token=None, *arg, **kwargs):
+ try:
+ uid = urlsafe_base64_decode(uidb64)
+ user = CustomUser.objects.get(pk=uid)
+ except (TypeError, ValueError, OverflowError, CustomUser.DoesNotExist):
+ user = None
+
+ form = self.form_class(request.POST)
+
+ if user is not None and default_token_generator.check_token(user,
+ token):
+ if form.is_valid():
+ new_password = form.cleaned_data['new_password2']
+ user.set_password(new_password)
+ user.save()
+ messages.success(request, _('Password has been reset.'))
+ return self.form_valid(form)
+ else:
+ messages.error(request,
+ _('Password reset has not been successful.'))
+ form.add_error(None,
+ _('Password reset has not been successful.'))
+ return self.form_invalid(form)
+
+ else:
+ messages.error(request,
+ _('The reset password link is no longer valid.'))
+ form.add_error(None,
+ _('The reset password link is no longer valid.'))
+ return self.form_invalid(form)
+
+
+class SSHKeyCreateView(FormView):
+ form_class = UserHostingKeyForm
+ model = UserHostingKey
+ template_name = 'hosting/user_key.html'
+ login_url = reverse_lazy('hosting:login')
+ context_object_name = "virtual_machine"
+ success_url = reverse_lazy('hosting:ssh_keys')
+
+ def get_form_kwargs(self):
+ kwargs = super(SSHKeyCreateView, self).get_form_kwargs()
+ kwargs.update({'request': self.request})
+ return kwargs
+
+ def form_valid(self, form):
+ form.save()
+ if settings.DCL_SSH_KEY_NAME_PREFIX in form.instance.name:
+ content = ContentFile(form.cleaned_data.get('private_key'))
+ filename = form.cleaned_data.get(
+ 'name') + '_' + str(uuid.uuid4())[:8] + '_private.pem'
+ form.instance.private_key.save(filename, content)
+ context = self.get_context_data()
+
+ next_url = self.request.session.get(
+ 'next',
+ reverse_lazy('hosting:create_virtual_machine')
+ )
+
+ if 'next' in self.request.session:
+ context.update({
+ 'next_url': next_url
+ })
+ del (self.request.session['next'])
+
+ if form.cleaned_data.get('private_key'):
+ context.update({
+ 'private_key': form.cleaned_data.get('private_key'),
+ 'key_name': form.cleaned_data.get('name'),
+ 'form': UserHostingKeyForm(request=self.request),
+ })
+
+ if self.request.user.is_authenticated:
+ owner = self.request.user
+ manager = OpenNebulaManager(
+ email=owner.username,
+ password=owner.password
+ )
+ keys_to_save = get_all_public_keys(self.request.user)
+ manager.save_key_in_opennebula_user('\n'.join(keys_to_save))
+ else:
+ self.request.session["new_user_hosting_key_id"] = form.instance.id
+ return HttpResponseRedirect(self.success_url)
+
+ def post(self, request, *args, **kwargs):
+ form = self.get_form()
+ required = 'add_ssh' in self.request.POST
+ form.fields['name'].required = required
+ form.fields['public_key'].required = required
+ if form.is_valid():
+ return self.form_valid(form)
+ else:
+ return self.form_invalid(form)
+
+
+class AskSSHKeyView(SSHKeyCreateView):
+ form_class = UserHostingKeyForm
+ template_name = "datacenterlight/add_ssh_key.html"
+ success_url = reverse_lazy('datacenterlight:order_confirmation')
+ context_object_name = "dcl_vm_buy_add_ssh_key"
+
+ @cache_control(no_cache=True, must_revalidate=True, no_store=True)
+ def get(self, request, *args, **kwargs):
+ context = {
+ 'site_url': reverse_lazy('datacenterlight:index'),
+ 'cms_integration': get_cms_integration('default'),
+ 'form': UserHostingKeyForm(request=self.request),
+ 'keys': get_all_public_keys(self.request.user)
+ }
+ return render(request, self.template_name, context)
+
+ def post(self, request, *args, **kwargs):
+ self.success_url = self.request.session.get("order_confirm_url")
+ return super(AskSSHKeyView, self).post(self, request, *args, **kwargs)
\ No newline at end of file
diff --git a/uwsgi.ini b/uwsgi.ini
new file mode 100644
index 0000000..656fce5
--- /dev/null
+++ b/uwsgi.ini
@@ -0,0 +1,8 @@
+[uwsgi]
+buffer-size = 65536
+socket = :8000
+chdir = /app
+module = dynamicweb2.wsgi:application
+master = true
+processes = 4
+threads = 2
diff --git a/webhook/__init__.py b/webhook/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/webhook/admin.py b/webhook/admin.py
new file mode 100755
index 0000000..8c38f3f
--- /dev/null
+++ b/webhook/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/webhook/apps.py b/webhook/apps.py
new file mode 100755
index 0000000..1473609
--- /dev/null
+++ b/webhook/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class WebhookConfig(AppConfig):
+ name = 'webhook'
diff --git a/webhook/management/commands/webhook.py b/webhook/management/commands/webhook.py
new file mode 100755
index 0000000..4ceb275
--- /dev/null
+++ b/webhook/management/commands/webhook.py
@@ -0,0 +1,81 @@
+import logging
+
+import stripe
+from django.core.management.base import BaseCommand
+
+logger = logging.getLogger(__name__)
+
+
+class Command(BaseCommand):
+ help = '''creates webhook with the supplied arguments and returns the
+ webhook secret
+ '''
+
+ def add_arguments(self, parser):
+ parser.add_argument(
+ '--webhook_endpoint',
+ help="The url of the webhook endpoint that accepts the events "
+ "from stripe",
+ dest="webhook_endpoint",
+ required=False
+ )
+ parser.add_argument('--events_csv', dest="events_csv", required=False)
+ parser.add_argument('--webhook_id', dest="webhook_id", required=False)
+ parser.add_argument('--create', dest='create', action='store_true')
+ parser.add_argument('--list', dest='list', action='store_true')
+ parser.add_argument('--delete', dest='delete', action='store_true')
+
+ def handle(self, *args, **options):
+ wep_exists = False
+ if options['list']:
+ logger.debug("Listing webhooks")
+ we_list = stripe.WebhookEndpoint.list(limit=100)
+ for wep in we_list.data:
+ msg = wep.id + " -- " + ",".join(wep.enabled_events)
+ logger.debug(msg)
+ self.stdout.write(
+ self.style.SUCCESS(msg)
+ )
+ elif options['delete']:
+ logger.debug("Deleting webhook")
+ if 'webhook_id' in options:
+ stripe.WebhookEndpoint.delete(options['webhook_id'])
+ msg = "Deleted " + options['webhook_id']
+ logger.debug(msg)
+ self.stdout.write(
+ self.style.SUCCESS(msg)
+ )
+ else:
+ msg = "Supply webhook_id to delete a webhook"
+ logger.debug(msg)
+ self.stdout.write(
+ self.style.SUCCESS(msg)
+ )
+ exit(0)
+ elif options['create']:
+ logger.debug("Creating webhook")
+ try:
+ we_list = stripe.WebhookEndpoint.list(limit=100)
+ for wep in we_list.data:
+ if set(wep.enabled_events) == set(options['events_csv'].split(",")):
+ if wep.url == options['webhook_endpoint']:
+ logger.debug("We have this webhook already")
+ wep_exists = True
+ break
+ if wep_exists is False:
+ logger.debug(
+ "No webhook exists for {} at {}. Creatting a new endpoint "
+ "now".format(
+ options['webhook_endpoint'], options['events_csv']
+ )
+ )
+ wep = stripe.WebhookEndpoint.create(
+ url=options['webhook_endpoint'],
+ enabled_events=options['events_csv'].split(",")
+ )
+ self.stdout.write(
+ self.style.SUCCESS('Creation successful. '
+ 'webhook_secret = %s' % wep.secret)
+ )
+ except Exception as e:
+ print(" *** Error occurred. Details {}".format(str(e)))
diff --git a/webhook/models.py b/webhook/models.py
new file mode 100755
index 0000000..d49766e
--- /dev/null
+++ b/webhook/models.py
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
\ No newline at end of file
diff --git a/webhook/tests.py b/webhook/tests.py
new file mode 100755
index 0000000..7ce503c
--- /dev/null
+++ b/webhook/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/webhook/views.py b/webhook/views.py
new file mode 100755
index 0000000..0a96d0b
--- /dev/null
+++ b/webhook/views.py
@@ -0,0 +1,318 @@
+import datetime
+import logging
+import json
+import stripe
+
+# Create your views here.
+from django.conf import settings
+from django.http import HttpResponse
+from django.views.decorators.csrf import csrf_exempt
+from django.views.decorators.http import require_POST
+
+from datacenterlight.views import do_provisioning, do_provisioning_generic
+from membership.models import StripeCustomer
+from hosting.models import IncompleteSubscriptions, IncompletePaymentIntents
+
+from utils.models import BillingAddress, UserBillingAddress
+from utils.tasks import send_plain_email_task
+
+logger = logging.getLogger(__name__)
+
+
+# Things to do for webhooks feature
+# 1. Uninstall old version and install a more recent version of stripe
+# ```
+# source venv/bin/activate
+# ./manage.py shell
+# pip uninstall stripe
+# pip install stripe==2.24.1
+# ```
+# 2. Create tax id updated webhook
+# ```
+# ./manage.py webhook --create \
+# --webhook_endpoint https://datacenterlight.ch/en-us/webhooks/ \
+# --events_csv customer.tax_id.updated
+# ```
+#
+# 3. From the secret obtained in 2, setup an environment variable
+# ```
+# WEBHOOK_SECRET='whsec......'
+# ```
+
+
+@require_POST
+@csrf_exempt
+def handle_webhook(request):
+ payload = request.body
+ event = None
+
+ try:
+ if 'HTTP_STRIPE_SIGNATURE' in request.META:
+ sig_header = request.META['HTTP_STRIPE_SIGNATURE']
+ else:
+ logger.error("No HTTP_STRIPE_SIGNATURE header")
+ # Invalid payload
+ return HttpResponse(status=400)
+ event = stripe.Webhook.construct_event(
+ payload, sig_header, settings.WEBHOOK_SECRET
+ )
+ except ValueError as e:
+ # Invalid payload
+ err_msg = "FAILURE handle_invoice_webhook: Invalid payload details"
+ err_body = "Details %s" % str(e)
+ return handle_error(err_msg, err_body)
+ except stripe.error.SignatureVerificationError as e:
+ # Invalid signature
+ err_msg = "FAILURE handle_invoice_webhook: SignatureVerificationError"
+ err_body = "Details %s" % str(e)
+ return handle_error(err_msg, err_body)
+
+ # Do something with event
+ logger.debug("Passed signature verification")
+
+ if event.type == "customer.tax_id.updated":
+ logger.debug("Webhook Event: customer.tax_id.updated")
+ tax_id_obj = event.data.object
+ logger.debug("Tax_id %s is %s" % (tax_id_obj.id,
+ tax_id_obj.verification.status))
+ stripe_customer = None
+ try:
+ stripe_customer = StripeCustomer.objects.get(stripe_id=tax_id_obj.customer)
+ except StripeCustomer.DoesNotExist as dne:
+ logger.debug(
+ "StripeCustomer %s does not exist" % tax_id_obj.customer)
+ if tax_id_obj.verification.status == "verified":
+ b_addresses = BillingAddress.objects.filter(stripe_tax_id=tax_id_obj.id)
+ for b_address in b_addresses:
+ b_address.vat_validation_status = tax_id_obj.verification.status
+ b_address.vat_number_validated_on = datetime.datetime.now()
+ b_address.save()
+
+ ub_addresses = UserBillingAddress.objects.filter(stripe_tax_id=tax_id_obj.id)
+ for ub_address in ub_addresses:
+ ub_address.vat_validation_status = tax_id_obj.verification.status
+ ub_address.vat_number_validated_on = datetime.datetime.now()
+ ub_address.save()
+ email_data = {
+ 'subject': "The VAT %s associated with %s was verified" %
+ (tax_id_obj.value, stripe_customer.user.email if stripe_customer else "unknown"),
+ 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
+ 'to': settings.DCL_ERROR_EMAILS_TO_LIST,
+ 'body': "The following objects were modified:\n".join(
+ '\n'.join([str(b_address) for b_address in b_addresses])
+ ).join(
+ '\n'.join([str(ub_address) for ub_address in ub_addresses])
+ ),
+ }
+ else:
+ logger.debug("Tax_id %s is %s" % (tax_id_obj.id,
+ tax_id_obj.verification.status))
+ email_data = {
+ 'subject': "The VAT %s associated with %s was %s" %
+ (tax_id_obj.value, stripe_customer.user.email if stripe_customer else "unknown", tax_id_obj.verification.status),
+ 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
+ 'to': settings.DCL_ERROR_EMAILS_TO_LIST,
+ 'body': "Response = %s" % str(tax_id_obj),
+ }
+ send_plain_email_task.delay(email_data)
+ elif event.type == 'invoice.paid':
+ #More info: https://stripe.com/docs/billing/migration/strong-customer-authentication#scenario-1-handling-fulfillment
+ invoice_obj = event.data.object
+ logger.debug("Webhook Event: invoice.paid")
+ logger.debug("invoice_obj %s " % str(invoice_obj))
+ logger.debug("invoice_obj.paid = %s %s" % (invoice_obj.paid, type(invoice_obj.paid)))
+ logger.debug("invoice_obj.billing_reason = %s %s" % (invoice_obj.billing_reason, type(invoice_obj.billing_reason)))
+ # We should check for billing_reason == "subscription_create" but we
+ # check for "subscription_update"
+ # because we are using older api.
+ # See https://stripe.com/docs/upgrades?since=2015-07-13
+
+ # The billing_reason attribute of the invoice object now can take the
+ # value of subscription_create, indicating that it is the first
+ # invoice of a subscription. For older API versions,
+ # billing_reason=subscription_create is represented as
+ # subscription_update.
+
+ if (invoice_obj.paid and
+ invoice_obj.billing_reason == "subscription_update"):
+ logger.debug("""invoice_obj.paid and
+ invoice_obj.billing_reason == subscription_update""")
+ logger.debug("Start provisioning")
+ try:
+ logger.debug("Looking for subscription %s" %
+ invoice_obj.subscription)
+ stripe_subscription_obj = stripe.Subscription.retrieve(
+ invoice_obj.subscription)
+ try:
+ incomplete_sub = IncompleteSubscriptions.objects.get(
+ subscription_id=invoice_obj.subscription)
+ request = ""
+ soc = ""
+ card_details_response = ""
+ gp_details = ""
+ template = ""
+ specs = ""
+ billing_address_data = ""
+ if incomplete_sub.request:
+ request = json.loads(incomplete_sub.request)
+ if incomplete_sub.specs:
+ specs = json.loads(incomplete_sub.specs)
+ if incomplete_sub.stripe_onetime_charge:
+ soc = json.loads(incomplete_sub.stripe_onetime_charge)
+ if incomplete_sub.gp_details:
+ gp_details = json.loads(incomplete_sub.gp_details)
+ if incomplete_sub.card_details_response:
+ card_details_response = json.loads(
+ incomplete_sub.card_details_response)
+ if incomplete_sub.template:
+ template = json.loads(
+ incomplete_sub.template)
+ if incomplete_sub.billing_address_data:
+ billing_address_data = json.loads(
+ incomplete_sub.billing_address_data)
+ logger.debug("*******")
+ logger.debug(str(incomplete_sub))
+ logger.debug("*******")
+ logger.debug("1*******")
+ logger.debug(request)
+ logger.debug("2*******")
+ logger.debug(card_details_response)
+ logger.debug("3*******")
+ logger.debug(soc)
+ logger.debug("4*******")
+ logger.debug(gp_details)
+ logger.debug("5*******")
+ logger.debug(template)
+ logger.debug("6*******")
+ do_provisioning(
+ request=request,
+ stripe_api_cus_id=incomplete_sub.stripe_api_cus_id,
+ card_details_response=card_details_response,
+ stripe_subscription_obj=stripe_subscription_obj,
+ stripe_onetime_charge=soc,
+ gp_details=gp_details,
+ specs=specs,
+ vm_template_id=incomplete_sub.vm_template_id,
+ template=template,
+ billing_address_data=billing_address_data,
+ real_request=None
+ )
+ except IncompleteSubscriptions.DoesNotExist as ex:
+ logger.error(str(ex))
+ except IncompleteSubscriptions.MultipleObjectsReturned as ex:
+ logger.error(str(ex))
+ email_data = {
+ 'subject': "IncompleteSubscriptions error",
+ 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
+ 'to': settings.DCL_ERROR_EMAILS_TO_LIST,
+ 'body': "Response = %s" % str(ex),
+ }
+ send_plain_email_task.delay(email_data)
+ except Exception as ex:
+ logger.error(str(ex))
+ email_data = {
+ 'subject': "invoice.paid Webhook error",
+ 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
+ 'to': settings.DCL_ERROR_EMAILS_TO_LIST,
+ 'body': "Response = %s" % str(ex),
+ }
+ send_plain_email_task.delay(email_data)
+ elif event.type == 'invoice.payment_failed':
+ invoice_obj = event.data.object
+ logger.debug("Webhook Event: invoice.payment_failed")
+ logger.debug("invoice_obj %s " % str(invoice_obj))
+ if (invoice_obj.payment_failed and
+ invoice_obj.billing_reason == "subscription_update"):
+ logger.debug("Payment failed, inform the users")
+ elif event.type == 'payment_intent.succeeded':
+ payment_intent_obj = event.data.object
+ logger.debug("Webhook Event: payment_intent.succeeded")
+ logger.debug("payment_intent_obj %s " % str(payment_intent_obj))
+ try:
+ logger.debug("Looking for IncompletePaymentIntents %s " %
+ payment_intent_obj.id)
+ incomplete_pm = IncompletePaymentIntents.objects.get(
+ payment_intent_id=payment_intent_obj.id)
+ logger.debug("incomplete_pm = %s" % str(incomplete_pm.__dict__))
+ request = ""
+ soc = ""
+ card_details_response = ""
+ gp_details = ""
+ template = ""
+ billing_address_data = ""
+ if incomplete_pm.request:
+ request = json.loads(incomplete_pm.request)
+ logger.debug("request = %s" % str(request))
+ if incomplete_pm.stripe_charge_id:
+ soc = incomplete_pm.stripe_charge_id
+ logger.debug("stripe_onetime_charge = %s" % str(soc))
+ if incomplete_pm.gp_details:
+ gp_details = json.loads(incomplete_pm.gp_details)
+ logger.debug("gp_details = %s" % str(gp_details))
+ if incomplete_pm.card_details_response:
+ card_details_response = json.loads(
+ incomplete_pm.card_details_response)
+ logger.debug("card_details_response = %s" % str(card_details_response))
+ if incomplete_pm.billing_address_data:
+ billing_address_data = json.loads(
+ incomplete_pm.billing_address_data)
+ logger.debug("billing_address_data = %s" % str(billing_address_data))
+ logger.debug("1*******")
+ logger.debug(request)
+ logger.debug("2*******")
+ logger.debug(card_details_response)
+ logger.debug("3*******")
+ logger.debug(soc)
+ logger.debug("4*******")
+ logger.debug(gp_details)
+ logger.debug("5*******")
+ logger.debug(template)
+ logger.debug("6*******")
+ logger.debug(billing_address_data)
+ incomplete_pm.completed_at = datetime.datetime.now()
+ charges = ""
+ if len(payment_intent_obj.charges.data) > 0:
+ for d in payment_intent_obj.charges.data:
+ if charges == "":
+ charges = "%s" % d.id
+ else:
+ charges = "%s,%s" % (charges, d.id)
+ logger.debug("Charge ids = %s" % charges)
+ incomplete_pm.stripe_charge_id=charges
+ do_provisioning_generic(
+ request=request,
+ stripe_api_cus_id=incomplete_pm.stripe_api_cus_id,
+ card_details_response=card_details_response,
+ stripe_subscription_id=None,
+ stripe_charge_id=charges,
+ gp_details=gp_details,
+ billing_address_data=billing_address_data
+ )
+ incomplete_pm.save()
+ except IncompletePaymentIntents.DoesNotExist as ex:
+ logger.error(str(ex))
+ except (IncompletePaymentIntents.MultipleObjectsReturned,
+ Exception) as ex:
+ logger.error(str(ex))
+ email_data = {
+ 'subject': "IncompletePaymentIntents error",
+ 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
+ 'to': settings.DCL_ERROR_EMAILS_TO_LIST,
+ 'body': "Response = %s" % str(ex),
+ }
+ send_plain_email_task.delay(email_data)
+ else:
+ logger.error("Unhandled event : " + event.type)
+ return HttpResponse(status=200)
+
+
+def handle_error(error_msg, error_body):
+ logger.error("%s -- %s" % (error_msg, error_body))
+ email_to_admin_data = {
+ 'subject': error_msg,
+ 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
+ 'to': [settings.ADMIN_EMAIL],
+ 'body': error_body,
+ }
+ send_plain_email_task.delay(email_to_admin_data)
+ return HttpResponse(status=400)
\ No newline at end of file