Downloadspeed calculator

Errechnet dir die Downloadzeit bei Angaben von Größe der Datei und Internet geschwindigkeit

Der hier verwendete Code

<html data-lt-installed="true"><head> <meta charset="UTF-8"> <title>Download time calculator</title> <style> window,body{ width: 100%; height: 100%; } body{ font-family: Helvetica, Arial, sans-serif; background-color: #f8f8f8; } .content{ display:block; margin-left:auto; margin-right:auto; width: 600px; } h1,h2,h3,h4{ color: #444; } .content #speed, .content #file, .content #results, .content #downloadSimulatorWindow_{ margin-bottom: 20px; border: 1px solid red; border: 1px solid gray; border-radius: 3px; background-color: #EEE; box-shadow: 0px 2px 3px rgba(0,0,0,0.5); } input, button{ font-size: 16pt; } #speed { text-align: center; } #speed input{ font-size: 16pt; text-align: right; } #speed .idkSpeed{ font-size: 8pt; } #speed .idkSpeed.mobile{ font-size: 11pt; } .overhead-p{ font-size: 8pt; } #file{ text-align: center; } #file input{ font-size: 16pt; text-align: right; } .examples-p{ font-size: 8pt; } #results{ background-color: #FFF !important; text-align: center; visibility: hidden; } #results .time{ font-style:normal; font-size:24px; } #results .time em{ font-style:normal; font-size:32px; } #downloadSimulatorWindow { position: relative; width: 600px; height: 99px; color: gray; opacity: 0.5; border: 1px solid gray; border-radius: 5px; visibility: hidden; box-shadow: 0px 1px 16px rgba(0,0,0,0.5); } #downloadSimulatorWindow .filename { position: absolute; left: 85px; top: 18px; width: 355px; height: 15px; } #downloadSimulatorWindow .progresrbar { position: absolute; left: 85px; top: 38px; width: 398px; height: 22px; } #downloadSimulatorWindow progress{ width: 100%; } #downloadSimulatorWindow .percent { position: absolute; left: 435px; top: 15px; width: 49px; height: 17px; text-align: right; } #downloadSimulatorWindow .details { position: absolute; left: 85px; top: 63px; width: 401px; height: 19px; padding-left: 0.5em; font-size: 14px; } #downloadSimulatorWindow .icon { position: absolute; left: 10px; top: 18px; width: 64px; height: 64px; } #downloadSimulatorWindow .ps { position: absolute; right: 0px; bottom: -20px; width: 514px; height: 18px; font-size: 10px; text-align: right; } .footer{ text-align: center; font-size: 9pt; padding: 1em; } #calculateButton{ padding-left: 1em; padding-right: 1em; } #speedtest_mobile{ display: none; margin: 30px; background: #333; color: #FFF; } #speedtest_mobile a{ color: #FFF; margin:20px; } .mobile-iphone-btn, .mobile-windows-btn, .mobile-android-btn, .mobile-amazon-btn{ width: 230px; height: 74px; background: url(http://www.speedtest.net/mobile/../images/app-store-sprite.png); background-position: 0px -2px; display: block; float: left; display: inline-block; } .mobile-iphone-btn{ background-position: 0px -2px; } .mobile-windows-btn{ background-position: 245px -2px; } .mobile-android-btn{ background-position: 483px -2px; } .mobile-amazon-btn{ background-position: 0 -2px; background: url(http://www.speedtest.net/mobile/../images/app-store-amazon.png); } .speedtest-mobile-ico{ width: 124px; height: 124px; background-image: url(http://www.speedtest.net/mobile/../images/placeholder-mobile-header.png); -webkit-background-size: 124px 124px; -moz-background-size: 124px 124px; background-size: 124px 124px; background-repeat: no-repeat; width: 70px; height: 70px; -webkit-background-size: 70px 70px; -moz-background-size: 70px 70px; background-size: 70px 70px; float: left; margin-left: 8px; margin-right: 15px; margin-left: 50px; margin-top: 35px; display: inline-block; } /******/ .collapse{ font-size: 8pt; display: block; line-height: 44px; color: gray; } .collapse:hover{ color: white; -background-color: #FCFCFC; } .collapse + input{ display:none; } .collapse + input + div{ display:none; } .collapse+ input:checked + div{ display:block; } </style> <script> (function(a) { function b() { return { empty: !1, unusedTokens: [], unusedInput: [], overflow: -2, charsLeftOver: 0, nullInput: !1, invalidMonth: null, invalidFormat: !1, userInvalidated: !1, iso: !1 } } function c(a, b) { return function(c) { return k(a.call(this, c), b) } } function d(a, b) { return function(c) { return this.lang().ordinal(a.call(this, c), b) } } function e() {} function f(a) { w(a), h(this, a) } function g(a) { var b = q(a) , c = b.year || 0 , d = b.month || 0 , e = b.week || 0 , f = b.day || 0 , g = b.hour || 0 , h = b.minute || 0 , i = b.second || 0 , j = b.millisecond || 0; this._milliseconds = +j + 1e3 * i + 6e4 * h + 36e5 * g, this._days = +f + 7 * e, this._months = +d + 12 * c, this._data = {}, this._bubble() } function h(a, b) { for (var c in b) b.hasOwnProperty(c) && (a[c] = b[c]); return b.hasOwnProperty("toString") && (a.toString = b.toString), b.hasOwnProperty("valueOf") && (a.valueOf = b.valueOf), a } function i(a) { var b, c = {}; for (b in a) a.hasOwnProperty(b) && qb.hasOwnProperty(b) && (c[b] = a[b]); return c } function j(a) { return 0 > a ? Math.ceil(a) : Math.floor(a) } function k(a, b, c) { for (var d = "" + Math.abs(a), e = a >= 0; d.length < b; ) d = "0" + d; return (e ? c ? "+" : "" : "-") + d } function l(a, b, c, d) { var e, f, g = b._milliseconds, h = b._days, i = b._months; g && a._d.setTime(+a._d + g * c), (h || i) && (e = a.minute(), f = a.hour()), h && a.date(a.date() + h * c), i && a.month(a.month() + i * c), g && !d && db.updateOffset(a), (h || i) && (a.minute(e), a.hour(f)) } function m(a) { return "[object Array]" === Object.prototype.toString.call(a) } function n(a) { return "[object Date]" === Object.prototype.toString.call(a) || a instanceof Date } function o(a, b, c) { var d, e = Math.min(a.length, b.length), f = Math.abs(a.length - b.length), g = 0; for (d = 0; e > d; d++) (c && a[d] !== b[d] || !c && s(a[d]) !== s(b[d])) && g++; return g + f } function p(a) { if (a) { var b = a.toLowerCase().replace(/(.)s$/, "$1"); a = Tb[a] || Ub[b] || b } return a } function q(a) { var b, c, d = {}; for (c in a) a.hasOwnProperty(c) && (b = p(c), b && (d[b] = a[c])); return d } function r(b) { var c, d; if (0 === b.indexOf("week")) c = 7, d = "day"; else { if (0 !== b.indexOf("month")) return; c = 12, d = "month" } db[b] = function(e, f) { var g, h, i = db.fn._lang[b], j = []; if ("number" == typeof e && (f = e, e = a), h = function(a) { var b = db().utc().set(d, a); return i.call(db.fn._lang, b, e || "") } , null != f) return h(f); for (g = 0; c > g; g++) j.push(h(g)); return j } } function s(a) { var b = +a , c = 0; return 0 !== b && isFinite(b) && (c = b >= 0 ? Math.floor(b) : Math.ceil(b)), c } function t(a, b) { return new Date(Date.UTC(a, b + 1, 0)).getUTCDate() } function u(a) { return v(a) ? 366 : 365 } function v(a) { return a % 4 === 0 && a % 100 !== 0 || a % 400 === 0 } function w(a) { var b; a._a && -2 === a._pf.overflow && (b = a._a[jb] < 0 || a._a[jb] > 11 ? jb : a._a[kb] < 1 || a._a[kb] > t(a._a[ib], a._a[jb]) ? kb : a._a[lb] < 0 || a._a[lb] > 23 ? lb : a._a[mb] < 0 || a._a[mb] > 59 ? mb : a._a[nb] < 0 || a._a[nb] > 59 ? nb : a._a[ob] < 0 || a._a[ob] > 999 ? ob : -1, a._pf._overflowDayOfYear && (ib > b || b > kb) && (b = kb), a._pf.overflow = b) } function x(a) { return null == a._isValid && (a._isValid = !isNaN(a._d.getTime()) && a._pf.overflow < 0 && !a._pf.empty && !a._pf.invalidMonth && !a._pf.nullInput && !a._pf.invalidFormat && !a._pf.userInvalidated, a._strict && (a._isValid = a._isValid && 0 === a._pf.charsLeftOver && 0 === a._pf.unusedTokens.length)), a._isValid } function y(a) { return a ? a.toLowerCase().replace("_", "-") : a } function z(a, b) { return b._isUTC ? db(a).zone(b._offset || 0) : db(a).local() } function A(a, b) { return b.abbr = a, pb[a] || (pb[a] = new e), pb[a].set(b), pb[a] } function B(a) { delete pb[a] } function C(a) { var b, c, d, e, f = 0, g = function(a) { if (!pb[a] && rb) try { require("./lang/" + a) } catch (b) {} return pb[a] }; if (!a) return db.fn._lang; if (!m(a)) { if (c = g(a)) return c; a = [a] } for (; f < a.length; ) { for (e = y(a[f]).split("-"), b = e.length, d = y(a[f + 1]), d = d ? d.split("-") : null; b > 0; ) { if (c = g(e.slice(0, b).join("-"))) return c; if (d && d.length >= b && o(e, d, !0) >= b - 1) break; b-- } f++ } return db.fn._lang } function D(a) { return a.match(/\[[\s\S]/) ? a.replace(/^\[|\]$/g, "") : a.replace(/\\/g, "") } function E(a) { var b, c, d = a.match(vb); for (b = 0, c = d.length; c > b; b++) d[b] = Yb[d[b]] ? Yb[d[b]] : D(d[b]); return function(e) { var f = ""; for (b = 0; c > b; b++) f += d[b]instanceof Function ? d[b].call(e, a) : d[b]; return f } } function F(a, b) { return a.isValid() ? (b = G(b, a.lang()), Vb[b] || (Vb[b] = E(b)), Vb[b](a)) : a.lang().invalidDate() } function G(a, b) { function c(a) { return b.longDateFormat(a) || a } var d = 5; for (wb.lastIndex = 0; d >= 0 && wb.test(a); ) a = a.replace(wb, c), wb.lastIndex = 0, d -= 1; return a } function H(a, b) { var c, d = b._strict; switch (a) { case "DDDD": return Ib; case "YYYY": case "GGGG": case "gggg": return d ? Jb : zb; case "Y": case "G": case "g": return Lb; case "YYYYYY": case "YYYYY": case "GGGGG": case "ggggg": return d ? Kb : Ab; case "S": if (d) return Gb; case "SS": if (d) return Hb; case "SSS": if (d) return Ib; case "DDD": return yb; case "MMM": case "MMMM": case "dd": case "ddd": case "dddd": return Cb; case "a": case "A": return C(b._l)._meridiemParse; case "X": return Fb; case "Z": case "ZZ": return Db; case "T": return Eb; case "SSSS": return Bb; case "MM": case "DD": case "YY": case "GG": case "gg": case "HH": case "hh": case "mm": case "ss": case "ww": case "WW": return d ? Hb : xb; case "M": case "D": case "d": case "H": case "h": case "m": case "s": case "w": case "W": case "e": case "E": return xb; default: return c = new RegExp(P(O(a.replace("\\", "")), "i")) } } function I(a) { a = a || ""; var b = a.match(Db) || [] , c = b[b.length - 1] || [] , d = (c + "").match(Qb) || ["-", 0, 0] , e = +(60 * d[1]) + s(d[2]); return "+" === d[0] ? -e : e } function J(a, b, c) { var d, e = c._a; switch (a) { case "M": case "MM": null != b && (e[jb] = s(b) - 1); break; case "MMM": case "MMMM": d = C(c._l).monthsParse(b), null != d ? e[jb] = d : c._pf.invalidMonth = b; break; case "D": case "DD": null != b && (e[kb] = s(b)); break; case "DDD": case "DDDD": null != b && (c._dayOfYear = s(b)); break; case "YY": e[ib] = s(b) + (s(b) > 68 ? 1900 : 2e3); break; case "YYYY": case "YYYYY": case "YYYYYY": e[ib] = s(b); break; case "a": case "A": c._isPm = C(c._l).isPM(b); break; case "H": case "HH": case "h": case "hh": e[lb] = s(b); break; case "m": case "mm": e[mb] = s(b); break; case "s": case "ss": e[nb] = s(b); break; case "S": case "SS": case "SSS": case "SSSS": e[ob] = s(1e3 * ("0." + b)); break; case "X": c._d = new Date(1e3 * parseFloat(b)); break; case "Z": case "ZZ": c._useUTC = !0, c._tzm = I(b); break; case "w": case "ww": case "W": case "WW": case "d": case "dd": case "ddd": case "dddd": case "e": case "E": a = a.substr(0, 1); case "gg": case "gggg": case "GG": case "GGGG": case "GGGGG": a = a.substr(0, 2), b && (c._w = c._w || {}, c._w[a] = b) } } function K(a) { var b, c, d, e, f, g, h, i, j, k, l = []; if (!a._d) { for (d = M(a), a._w && null == a._a[kb] && null == a._a[jb] && (f = function(b) { var c = parseInt(b, 10); return b ? b.length < 3 ? c > 68 ? 1900 + c : 2e3 + c : c : null == a._a[ib] ? db().weekYear() : a._a[ib] } , g = a._w, null != g.GG || null != g.W || null != g.E ? h = Z(f(g.GG), g.W || 1, g.E, 4, 1) : (i = C(a._l), j = null != g.d ? V(g.d, i) : null != g.e ? parseInt(g.e, 10) + i._week.dow : 0, k = parseInt(g.w, 10) || 1, null != g.d && j < i._week.dow && k++, h = Z(f(g.gg), k, j, i._week.doy, i._week.dow)), a._a[ib] = h.year, a._dayOfYear = h.dayOfYear), a._dayOfYear && (e = null == a._a[ib] ? d[ib] : a._a[ib], a._dayOfYear > u(e) && (a._pf._overflowDayOfYear = !0), c = U(e, 0, a._dayOfYear), a._a[jb] = c.getUTCMonth(), a._a[kb] = c.getUTCDate()), b = 0; 3 > b && null == a._a[b]; ++b) a._a[b] = l[b] = d[b]; for (; 7 > b; b++) a._a[b] = l[b] = null == a._a[b] ? 2 === b ? 1 : 0 : a._a[b]; l[lb] += s((a._tzm || 0) / 60), l[mb] += s((a._tzm || 0) % 60), a._d = (a._useUTC ? U : T).apply(null, l) } } function L(a) { var b; a._d || (b = q(a._i), a._a = [b.year, b.month, b.day, b.hour, b.minute, b.second, b.millisecond], K(a)) } function M(a) { var b = new Date; return a._useUTC ? [b.getUTCFullYear(), b.getUTCMonth(), b.getUTCDate()] : [b.getFullYear(), b.getMonth(), b.getDate()] } function N(a) { a._a = [], a._pf.empty = !0; var b, c, d, e, f, g = C(a._l), h = "" + a._i, i = h.length, j = 0; for (d = G(a._f, g).match(vb) || [], b = 0; b < d.length; b++) e = d[b], c = (h.match(H(e, a)) || [])[0], c && (f = h.substr(0, h.indexOf(c)), f.length > 0 && a._pf.unusedInput.push(f), h = h.slice(h.indexOf(c) + c.length), j += c.length), Yb[e] ? (c ? a._pf.empty = !1 : a._pf.unusedTokens.push(e), J(e, c, a)) : a._strict && !c && a._pf.unusedTokens.push(e); a._pf.charsLeftOver = i - j, h.length > 0 && a._pf.unusedInput.push(h), a._isPm && a._a[lb] < 12 && (a._a[lb] += 12), a._isPm === !1 && 12 === a._a[lb] && (a._a[lb] = 0), K(a), w(a) } function O(a) { return a.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function(a, b, c, d, e) { return b || c || d || e }) } function P(a) { return a.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&") } function Q(a) { var c, d, e, f, g; if (0 === a._f.length) return a._pf.invalidFormat = !0, a._d = new Date(0 / 0), void 0; for (f = 0; f < a._f.length; f++) g = 0, c = h({}, a), c._pf = b(), c._f = a._f[f], N(c), x(c) && (g += c._pf.charsLeftOver, g += 10 * c._pf.unusedTokens.length, c._pf.score = g, (null == e || e > g) && (e = g, d = c)); h(a, d || c) } function R(a) { var b, c, d = a._i, e = Mb.exec(d); if (e) { for (a._pf.iso = !0, b = 0, c = Ob.length; c > b; b++) if (Ob[b][1].exec(d)) { a._f = Ob[b][0] + (e[6] || " "); break } for (b = 0, c = Pb.length; c > b; b++) if (Pb[b][1].exec(d)) { a._f += Pb[b][0]; break } d.match(Db) && (a._f += "Z"), N(a) } else a._d = new Date(d) } function S(b) { var c = b._i , d = sb.exec(c); c === a ? b._d = new Date : d ? b._d = new Date(+d[1]) : "string" == typeof c ? R(b) : m(c) ? (b._a = c.slice(0), K(b)) : n(c) ? b._d = new Date(+c) : "object" == typeof c ? L(b) : b._d = new Date(c) } function T(a, b, c, d, e, f, g) { var h = new Date(a,b,c,d,e,f,g); return 1970 > a && h.setFullYear(a), h } function U(a) { var b = new Date(Date.UTC.apply(null, arguments)); return 1970 > a && b.setUTCFullYear(a), b } function V(a, b) { if ("string" == typeof a) if (isNaN(a)) { if (a = b.weekdaysParse(a), "number" != typeof a) return null } else a = parseInt(a, 10); return a } function W(a, b, c, d, e) { return e.relativeTime(b || 1, !!c, a, d) } function X(a, b, c) { var d = hb(Math.abs(a) / 1e3) , e = hb(d / 60) , f = hb(e / 60) , g = hb(f / 24) , h = hb(g / 365) , i = 45 > d && ["s", d] || 1 === e && ["m"] || 45 > e && ["mm", e] || 1 === f && ["h"] || 22 > f && ["hh", f] || 1 === g && ["d"] || 25 >= g && ["dd", g] || 45 >= g && ["M"] || 345 > g && ["MM", hb(g / 30)] || 1 === h && ["y"] || ["yy", h]; return i[2] = b, i[3] = a > 0, i[4] = c, W.apply({}, i) } function Y(a, b, c) { var d, e = c - b, f = c - a.day(); return f > e && (f -= 7), e - 7 > f && (f += 7), d = db(a).add("d", f), { week: Math.ceil(d.dayOfYear() / 7), year: d.year() } } function Z(a, b, c, d, e) { var f, g, h = U(a, 0, 1).getUTCDay(); return c = null != c ? c : e, f = e - h + (h > d ? 7 : 0) - (e > h ? 7 : 0), g = 7 * (b - 1) + (c - e) + f + 1, { year: g > 0 ? a : a - 1, dayOfYear: g > 0 ? g : u(a - 1) + g } } function $(a) { var b = a._i , c = a._f; return null === b ? db.invalid({ nullInput: !0 }) : ("string" == typeof b && (a._i = b = C().preparse(b)), db.isMoment(b) ? (a = i(b), a._d = new Date(+b._d)) : c ? m(c) ? Q(a) : N(a) : S(a), new f(a)) } function _(a, b) { db.fn[a] = db.fn[a + "s"] = function(a) { var c = this._isUTC ? "UTC" : ""; return null != a ? (this._d["set" + c + b](a), db.updateOffset(this), this) : this._d["get" + c + b]() } } function ab(a) { db.duration.fn[a] = function() { return this._data[a] } } function bb(a, b) { db.duration.fn["as" + a] = function() { return +this / b } } function cb(a) { var b = !1 , c = db; "undefined" == typeof ender && (a ? (gb.moment = function() { return !b && console && console.warn && (b = !0, console.warn("Accessing Moment through the global scope is deprecated, and will be removed in an upcoming release.")), c.apply(null, arguments) } , h(gb.moment, c)) : gb.moment = db) } for (var db, eb, fb = "2.5.1", gb = this, hb = Math.round, ib = 0, jb = 1, kb = 2, lb = 3, mb = 4, nb = 5, ob = 6, pb = {}, qb = { _isAMomentObject: null, _i: null, _f: null, _l: null, _strict: null, _isUTC: null, _offset: null, _pf: null, _lang: null }, rb = "undefined" != typeof module && module.exports && "undefined" != typeof require, sb = /^\/?Date\((\-?\d+)/i, tb = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/, ub = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/, vb = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g, wb = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g, xb = /\d\d?/, yb = /\d{1,3}/, zb = /\d{1,4}/, Ab = /[+\-]?\d{1,6}/, Bb = /\d+/, Cb = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, Db = /Z|[\+\-]\d\d:?\d\d/gi, Eb = /T/i, Fb = /[\+\-]?\d+(\.\d{1,3})?/, Gb = /\d/, Hb = /\d\d/, Ib = /\d{3}/, Jb = /\d{4}/, Kb = /[+-]?\d{6}/, Lb = /[+-]?\d+/, Mb = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/, Nb = "YYYY-MM-DDTHH:mm:ssZ", Ob = [["YYYYYY-MM-DD", /[+-]\d{6}-\d{2}-\d{2}/], ["YYYY-MM-DD", /\d{4}-\d{2}-\d{2}/], ["GGGG-[W]WW-E", /\d{4}-W\d{2}-\d/], ["GGGG-[W]WW", /\d{4}-W\d{2}/], ["YYYY-DDD", /\d{4}-\d{3}/]], Pb = [["HH:mm:ss.SSSS", /(T| )\d\d:\d\d:\d\d\.\d{1,3}/], ["HH:mm:ss", /(T| )\d\d:\d\d:\d\d/], ["HH:mm", /(T| )\d\d:\d\d/], ["HH", /(T| )\d\d/]], Qb = /([\+\-]|\d\d)/gi, Rb = "Date|Hours|Minutes|Seconds|Milliseconds".split("|"), Sb = { Milliseconds: 1, Seconds: 1e3, Minutes: 6e4, Hours: 36e5, Days: 864e5, Months: 2592e6, Years: 31536e6 }, Tb = { ms: "millisecond", s: "second", m: "minute", h: "hour", d: "day", D: "date", w: "week", W: "isoWeek", M: "month", y: "year", DDD: "dayOfYear", e: "weekday", E: "isoWeekday", gg: "weekYear", GG: "isoWeekYear" }, Ub = { dayofyear: "dayOfYear", isoweekday: "isoWeekday", isoweek: "isoWeek", weekyear: "weekYear", isoweekyear: "isoWeekYear" }, Vb = {}, Wb = "DDD w W M D d".split(" "), Xb = "M D H h m s w W".split(" "), Yb = { M: function() { return this.month() + 1 }, MMM: function(a) { return this.lang().monthsShort(this, a) }, MMMM: function(a) { return this.lang().months(this, a) }, D: function() { return this.date() }, DDD: function() { return this.dayOfYear() }, d: function() { return this.day() }, dd: function(a) { return this.lang().weekdaysMin(this, a) }, ddd: function(a) { return this.lang().weekdaysShort(this, a) }, dddd: function(a) { return this.lang().weekdays(this, a) }, w: function() { return this.week() }, W: function() { return this.isoWeek() }, YY: function() { return k(this.year() % 100, 2) }, YYYY: function() { return k(this.year(), 4) }, YYYYY: function() { return k(this.year(), 5) }, YYYYYY: function() { var a = this.year() , b = a >= 0 ? "+" : "-"; return b + k(Math.abs(a), 6) }, gg: function() { return k(this.weekYear() % 100, 2) }, gggg: function() { return k(this.weekYear(), 4) }, ggggg: function() { return k(this.weekYear(), 5) }, GG: function() { return k(this.isoWeekYear() % 100, 2) }, GGGG: function() { return k(this.isoWeekYear(), 4) }, GGGGG: function() { return k(this.isoWeekYear(), 5) }, e: function() { return this.weekday() }, E: function() { return this.isoWeekday() }, a: function() { return this.lang().meridiem(this.hours(), this.minutes(), !0) }, A: function() { return this.lang().meridiem(this.hours(), this.minutes(), !1) }, H: function() { return this.hours() }, h: function() { return this.hours() % 12 || 12 }, m: function() { return this.minutes() }, s: function() { return this.seconds() }, S: function() { return s(this.milliseconds() / 100) }, SS: function() { return k(s(this.milliseconds() / 10), 2) }, SSS: function() { return k(this.milliseconds(), 3) }, SSSS: function() { return k(this.milliseconds(), 3) }, Z: function() { var a = -this.zone() , b = "+"; return 0 > a && (a = -a, b = "-"), b + k(s(a / 60), 2) + ":" + k(s(a) % 60, 2) }, ZZ: function() { var a = -this.zone() , b = "+"; return 0 > a && (a = -a, b = "-"), b + k(s(a / 60), 2) + k(s(a) % 60, 2) }, z: function() { return this.zoneAbbr() }, zz: function() { return this.zoneName() }, X: function() { return this.unix() }, Q: function() { return this.quarter() } }, Zb = ["months", "monthsShort", "weekdays", "weekdaysShort", "weekdaysMin"]; Wb.length; ) eb = Wb.pop(), Yb[eb + "o"] = d(Yb[eb], eb); for (; Xb.length; ) eb = Xb.pop(), Yb[eb + eb] = c(Yb[eb], 2); for (Yb.DDDD = c(Yb.DDD, 3), h(e.prototype, { set: function(a) { var b, c; for (c in a) b = a[c], "function" == typeof b ? this[c] = b : this["_" + c] = b }, _months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), months: function(a) { return this._months[a.month()] }, _monthsShort: "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), monthsShort: function(a) { return this._monthsShort[a.month()] }, monthsParse: function(a) { var b, c, d; for (this._monthsParse || (this._monthsParse = []), b = 0; 12 > b; b++) if (this._monthsParse[b] || (c = db.utc([2e3, b]), d = "^" + this.months(c, "") + "|^" + this.monthsShort(c, ""), this._monthsParse[b] = new RegExp(d.replace(".", ""),"i")), this._monthsParse[b].test(a)) return b }, _weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), weekdays: function(a) { return this._weekdays[a.day()] }, _weekdaysShort: "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), weekdaysShort: function(a) { return this._weekdaysShort[a.day()] }, _weekdaysMin: "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), weekdaysMin: function(a) { return this._weekdaysMin[a.day()] }, weekdaysParse: function(a) { var b, c, d; for (this._weekdaysParse || (this._weekdaysParse = []), b = 0; 7 > b; b++) if (this._weekdaysParse[b] || (c = db([2e3, 1]).day(b), d = "^" + this.weekdays(c, "") + "|^" + this.weekdaysShort(c, "") + "|^" + this.weekdaysMin(c, ""), this._weekdaysParse[b] = new RegExp(d.replace(".", ""),"i")), this._weekdaysParse[b].test(a)) return b }, _longDateFormat: { LT: "h:mm A", L: "MM/DD/YYYY", LL: "MMMM D YYYY", LLL: "MMMM D YYYY LT", LLLL: "dddd, MMMM D YYYY LT" }, longDateFormat: function(a) { var b = this._longDateFormat[a]; return !b && this._longDateFormat[a.toUpperCase()] && (b = this._longDateFormat[a.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function(a) { return a.slice(1) }), this._longDateFormat[a] = b), b }, isPM: function(a) { return "p" === (a + "").toLowerCase().charAt(0) }, _meridiemParse: /[ap]\.?m?\.?/i, meridiem: function(a, b, c) { return a > 11 ? c ? "pm" : "PM" : c ? "am" : "AM" }, _calendar: { sameDay: "[Today at] LT", nextDay: "[Tomorrow at] LT", nextWeek: "dddd [at] LT", lastDay: "[Yesterday at] LT", lastWeek: "[Last] dddd [at] LT", sameElse: "L" }, calendar: function(a, b) { var c = this._calendar[a]; return "function" == typeof c ? c.apply(b) : c }, _relativeTime: { future: "in %s", past: "%s ago", s: "a few seconds", m: "a minute", mm: "%d minutes", h: "an hour", hh: "%d hours", d: "a day", dd: "%d days", M: "a month", MM: "%d months", y: "a year", yy: "%d years" }, relativeTime: function(a, b, c, d) { var e = this._relativeTime[c]; return "function" == typeof e ? e(a, b, c, d) : e.replace(/%d/i, a) }, pastFuture: function(a, b) { var c = this._relativeTime[a > 0 ? "future" : "past"]; return "function" == typeof c ? c(b) : c.replace(/%s/i, b) }, ordinal: function(a) { return this._ordinal.replace("%d", a) }, _ordinal: "%d", preparse: function(a) { return a }, postformat: function(a) { return a }, week: function(a) { return Y(a, this._week.dow, this._week.doy).week }, _week: { dow: 0, doy: 6 }, _invalidDate: "Invalid date", invalidDate: function() { return this._invalidDate } }), db = function(c, d, e, f) { var g; return "boolean" == typeof e && (f = e, e = a), g = {}, g._isAMomentObject = !0, g._i = c, g._f = d, g._l = e, g._strict = f, g._isUTC = !1, g._pf = b(), $(g) } , db.utc = function(c, d, e, f) { var g; return "boolean" == typeof e && (f = e, e = a), g = {}, g._isAMomentObject = !0, g._useUTC = !0, g._isUTC = !0, g._l = e, g._i = c, g._f = d, g._strict = f, g._pf = b(), $(g).utc() } , db.unix = function(a) { return db(1e3 * a) } , db.duration = function(a, b) { var c, d, e, f = a, h = null; return db.isDuration(a) ? f = { ms: a._milliseconds, d: a._days, M: a._months } : "number" == typeof a ? (f = {}, b ? f[b] = a : f.milliseconds = a) : (h = tb.exec(a)) ? (c = "-" === h[1] ? -1 : 1, f = { y: 0, d: s(h[kb]) * c, h: s(h[lb]) * c, m: s(h[mb]) * c, s: s(h[nb]) * c, ms: s(h[ob]) * c }) : (h = ub.exec(a)) && (c = "-" === h[1] ? -1 : 1, e = function(a) { var b = a && parseFloat(a.replace(",", ".")); return (isNaN(b) ? 0 : b) * c } , f = { y: e(h[2]), M: e(h[3]), d: e(h[4]), h: e(h[5]), m: e(h[6]), s: e(h[7]), w: e(h[8]) }), d = new g(f), db.isDuration(a) && a.hasOwnProperty("_lang") && (d._lang = a._lang), d } , db.version = fb, db.defaultFormat = Nb, db.updateOffset = function() {} , db.lang = function(a, b) { var c; return a ? (b ? A(y(a), b) : null === b ? (B(a), a = "en") : pb[a] || C(a), c = db.duration.fn._lang = db.fn._lang = C(a), c._abbr) : db.fn._lang._abbr } , db.langData = function(a) { return a && a._lang && a._lang._abbr && (a = a._lang._abbr), C(a) } , db.isMoment = function(a) { return a instanceof f || null != a && a.hasOwnProperty("_isAMomentObject") } , db.isDuration = function(a) { return a instanceof g } , eb = Zb.length - 1; eb >= 0; --eb) r(Zb[eb]); for (db.normalizeUnits = function(a) { return p(a) } , db.invalid = function(a) { var b = db.utc(0 / 0); return null != a ? h(b._pf, a) : b._pf.userInvalidated = !0, b } , db.parseZone = function(a) { return db(a).parseZone() } , h(db.fn = f.prototype, { clone: function() { return db(this) }, valueOf: function() { return +this._d + 6e4 * (this._offset || 0) }, unix: function() { return Math.floor(+this / 1e3) }, toString: function() { return this.clone().lang("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ") }, toDate: function() { return this._offset ? new Date(+this) : this._d }, toISOString: function() { var a = db(this).utc(); return 0 < a.year() && a.year() <= 9999 ? F(a, "YYYY-MM-DD[T]HH:mm:ss.SSS[Z]") : F(a, "YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]") }, toArray: function() { var a = this; return [a.year(), a.month(), a.date(), a.hours(), a.minutes(), a.seconds(), a.milliseconds()] }, isValid: function() { return x(this) }, isDSTShifted: function() { return this._a ? this.isValid() && o(this._a, (this._isUTC ? db.utc(this._a) : db(this._a)).toArray()) > 0 : !1 }, parsingFlags: function() { return h({}, this._pf) }, invalidAt: function() { return this._pf.overflow }, utc: function() { return this.zone(0) }, local: function() { return this.zone(0), this._isUTC = !1, this }, format: function(a) { var b = F(this, a || db.defaultFormat); return this.lang().postformat(b) }, add: function(a, b) { var c; return c = "string" == typeof a ? db.duration(+b, a) : db.duration(a, b), l(this, c, 1), this }, subtract: function(a, b) { var c; return c = "string" == typeof a ? db.duration(+b, a) : db.duration(a, b), l(this, c, -1), this }, diff: function(a, b, c) { var d, e, f = z(a, this), g = 6e4 * (this.zone() - f.zone()); return b = p(b), "year" === b || "month" === b ? (d = 432e5 * (this.daysInMonth() + f.daysInMonth()), e = 12 * (this.year() - f.year()) + (this.month() - f.month()), e += (this - db(this).startOf("month") - (f - db(f).startOf("month"))) / d, e -= 6e4 * (this.zone() - db(this).startOf("month").zone() - (f.zone() - db(f).startOf("month").zone())) / d, "year" === b && (e /= 12)) : (d = this - f, e = "second" === b ? d / 1e3 : "minute" === b ? d / 6e4 : "hour" === b ? d / 36e5 : "day" === b ? (d - g) / 864e5 : "week" === b ? (d - g) / 6048e5 : d), c ? e : j(e) }, from: function(a, b) { return db.duration(this.diff(a)).lang(this.lang()._abbr).humanize(!b) }, fromNow: function(a) { return this.from(db(), a) }, calendar: function() { var a = z(db(), this).startOf("day") , b = this.diff(a, "days", !0) , c = -6 > b ? "sameElse" : -1 > b ? "lastWeek" : 0 > b ? "lastDay" : 1 > b ? "sameDay" : 2 > b ? "nextDay" : 7 > b ? "nextWeek" : "sameElse"; return this.format(this.lang().calendar(c, this)) }, isLeapYear: function() { return v(this.year()) }, isDST: function() { return this.zone() < this.clone().month(0).zone() || this.zone() < this.clone().month(5).zone() }, day: function(a) { var b = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); return null != a ? (a = V(a, this.lang()), this.add({ d: a - b })) : b }, month: function(a) { var b, c = this._isUTC ? "UTC" : ""; return null != a ? "string" == typeof a && (a = this.lang().monthsParse(a), "number" != typeof a) ? this : (b = this.date(), this.date(1), this._d["set" + c + "Month"](a), this.date(Math.min(b, this.daysInMonth())), db.updateOffset(this), this) : this._d["get" + c + "Month"]() }, startOf: function(a) { switch (a = p(a)) { case "year": this.month(0); case "month": this.date(1); case "week": case "isoWeek": case "day": this.hours(0); case "hour": this.minutes(0); case "minute": this.seconds(0); case "second": this.milliseconds(0) } return "week" === a ? this.weekday(0) : "isoWeek" === a && this.isoWeekday(1), this }, endOf: function(a) { return a = p(a), this.startOf(a).add("isoWeek" === a ? "week" : a, 1).subtract("ms", 1) }, isAfter: function(a, b) { return b = "undefined" != typeof b ? b : "millisecond", +this.clone().startOf(b) > +db(a).startOf(b) }, isBefore: function(a, b) { return b = "undefined" != typeof b ? b : "millisecond", +this.clone().startOf(b) < +db(a).startOf(b) }, isSame: function(a, b) { return b = b || "ms", +this.clone().startOf(b) === +z(a, this).startOf(b) }, min: function(a) { return a = db.apply(null, arguments), this > a ? this : a }, max: function(a) { return a = db.apply(null, arguments), a > this ? this : a }, zone: function(a) { var b = this._offset || 0; return null == a ? this._isUTC ? b : this._d.getTimezoneOffset() : ("string" == typeof a && (a = I(a)), Math.abs(a) < 16 && (a = 60 * a), this._offset = a, this._isUTC = !0, b !== a && l(this, db.duration(b - a, "m"), 1, !0), this) }, zoneAbbr: function() { return this._isUTC ? "UTC" : "" }, zoneName: function() { return this._isUTC ? "Coordinated Universal Time" : "" }, parseZone: function() { return this._tzm ? this.zone(this._tzm) : "string" == typeof this._i && this.zone(this._i), this }, hasAlignedHourOffset: function(a) { return a = a ? db(a).zone() : 0, (this.zone() - a) % 60 === 0 }, daysInMonth: function() { return t(this.year(), this.month()) }, dayOfYear: function(a) { var b = hb((db(this).startOf("day") - db(this).startOf("year")) / 864e5) + 1; return null == a ? b : this.add("d", a - b) }, quarter: function() { return Math.ceil((this.month() + 1) / 3) }, weekYear: function(a) { var b = Y(this, this.lang()._week.dow, this.lang()._week.doy).year; return null == a ? b : this.add("y", a - b) }, isoWeekYear: function(a) { var b = Y(this, 1, 4).year; return null == a ? b : this.add("y", a - b) }, week: function(a) { var b = this.lang().week(this); return null == a ? b : this.add("d", 7 * (a - b)) }, isoWeek: function(a) { var b = Y(this, 1, 4).week; return null == a ? b : this.add("d", 7 * (a - b)) }, weekday: function(a) { var b = (this.day() + 7 - this.lang()._week.dow) % 7; return null == a ? b : this.add("d", a - b) }, isoWeekday: function(a) { return null == a ? this.day() || 7 : this.day(this.day() % 7 ? a : a - 7) }, get: function(a) { return a = p(a), this[a]() }, set: function(a, b) { return a = p(a), "function" == typeof this[a] && this[a](b), this }, lang: function(b) { return b === a ? this._lang : (this._lang = C(b), this) } }), eb = 0; eb < Rb.length; eb++) _(Rb[eb].toLowerCase().replace(/s$/, ""), Rb[eb]); _("year", "FullYear"), db.fn.days = db.fn.day, db.fn.months = db.fn.month, db.fn.weeks = db.fn.week, db.fn.isoWeeks = db.fn.isoWeek, db.fn.toJSON = db.fn.toISOString, h(db.duration.fn = g.prototype, { _bubble: function() { var a, b, c, d, e = this._milliseconds, f = this._days, g = this._months, h = this._data; h.milliseconds = e % 1e3, a = j(e / 1e3), h.seconds = a % 60, b = j(a / 60), h.minutes = b % 60, c = j(b / 60), h.hours = c % 24, f += j(c / 24), h.days = f % 30, g += j(f / 30), h.months = g % 12, d = j(g / 12), h.years = d }, weeks: function() { return j(this.days() / 7) }, valueOf: function() { return this._milliseconds + 864e5 * this._days + this._months % 12 * 2592e6 + 31536e6 * s(this._months / 12) }, humanize: function(a) { var b = +this , c = X(b, !a, this.lang()); return a && (c = this.lang().pastFuture(b, c)), this.lang().postformat(c) }, add: function(a, b) { var c = db.duration(a, b); return this._milliseconds += c._milliseconds, this._days += c._days, this._months += c._months, this._bubble(), this }, subtract: function(a, b) { var c = db.duration(a, b); return this._milliseconds -= c._milliseconds, this._days -= c._days, this._months -= c._months, this._bubble(), this }, get: function(a) { return a = p(a), this[a.toLowerCase() + "s"]() }, as: function(a) { return a = p(a), this["as" + a.charAt(0).toUpperCase() + a.slice(1) + "s"]() }, lang: db.fn.lang, toIsoString: function() { var a = Math.abs(this.years()) , b = Math.abs(this.months()) , c = Math.abs(this.days()) , d = Math.abs(this.hours()) , e = Math.abs(this.minutes()) , f = Math.abs(this.seconds() + this.milliseconds() / 1e3); return this.asSeconds() ? (this.asSeconds() < 0 ? "-" : "") + "P" + (a ? a + "Y" : "") + (b ? b + "M" : "") + (c ? c + "D" : "") + (d || e || f ? "T" : "") + (d ? d + "H" : "") + (e ? e + "M" : "") + (f ? f + "S" : "") : "P0D" } }); for (eb in Sb) Sb.hasOwnProperty(eb) && (bb(eb, Sb[eb]), ab(eb.toLowerCase())); bb("Weeks", 6048e5), db.duration.fn.asMonths = function() { return (+this - 31536e6 * this.years()) / 2592e6 + 12 * this.years() } , db.lang("en", { ordinal: function(a) { var b = a % 10 , c = 1 === s(a % 100 / 10) ? "th" : 1 === b ? "st" : 2 === b ? "nd" : 3 === b ? "rd" : "th"; return a + c } }), rb ? (module.exports = db, cb(!0)) : "function" == typeof define && define.amd ? define("moment", function(b, c, d) { return d.config && d.config() && d.config().noGlobal !== !0 && cb(d.config().noGlobal === a), db }) : cb() } ).call(this); </script> </head> <body> <div class="content"> <h1>Download time calculator</h1> <h3>How long will take to download this?</h3> <form onsubmit="return false"> <div id="speed"> <h3>How fast is your connection speed?</h3> <p> <label for="internetSpeed">Download Speed</label> <input id="internetSpeed" type="number" min="0" step="0.01" value="10" placeholder="Download speed" autofocus=""> <input id="internetSpeed_p" type="button" value="+" onclick="internetSpeed.value = (parseInt(internetSpeed.value)+1).toFixed(2)"> <input id="internetSpeed_p" type="button" value="-" onclick="internetSpeed.value = (parseInt(internetSpeed.value)-1).toFixed(2)"> <select id="internetSpeedBase"> <option value="10^3">Kbps</option> <option value="10^6" selected="">Mbps</option> </select> </p> <p class="idkSpeed"><a id="speedtestLink" href="http://speedtest.net" target="new">I don't know my internet speed</a></p> <div> <label class="collapse" for="_1">▼</label> <input id="_1" type="checkbox"> <div> <p class="overhead-p"><label for="internetOverhead">Overhead</label> <select id="internetOverhead"> <option value="1" selected="">None</option> <option value="0.99">1%</option> <option value="0.95">5%</option> <option value="0.9">10% (Tipical TCP overhead)</option> <option value="0.85">15%</option> <option value="0.8">20%</option> <option value="0.75">25%</option> <option value="0.7">30%</option> <option value="0.6">40%</option> <option value="0.5">50%</option> <option value="0.4">60%</option> <option value="0.3">70%</option> <option value="0.2">80%</option> <option value="0.1">90%</option> <option value="0.05">95%</option> <option value="0.01">99%</option> </select> <a href="#" onclick="alert('If you just measured your internet speed, you don\'t need to change this.\n\nBut if enter your contracted speed e.g. 10Mbps, keep in mind this value is a teorical maximum, there will always be overhead.\nFor a conservative value use 10% (tipical TCP overhead) or for more realistic results use 20%.')">Help</a> </p> </div> </div> </div> <div id="file"> <h3>What is the size of what you want to download?</h3> <p> <label for="fileSize">Size</label> <input type="number" id="fileSize" value="1" step="0.01" min="0"> <input id="internetSpeed_p" type="button" value="+" onclick="fileSize.value = (parseInt(fileSize.value)+1).toFixed(2)"> <input id="internetSpeed_p" type="button" value="-" onclick="fileSize.value = (parseInt(fileSize.value)-1).toFixed(2)"> <select id="fileSizeBase"> <option value="2^10">KB (KiloBytes)</option> <option value="2^20" selected="">MB (MegaBytes)</option> <option value="2^30">GB (GigaBytes)</option> <option value="2^40">TB (TeraBytes)</option> </select> </p> <p class="examples-p" style="display:none"> <label for="fileSizeEx">Examples</label> <select id="fileSizeEx"> <option></option> <optgroup label="iTunes Store"> <option value="4">4-minute song</option> <option value="30">5-minute video</option> <option value="110">9-hour audiobook</option> <option value="200">45-minute TV show</option> <option value="600">45-minute HDTV show</option> <option value="1.5">2-hour SD movie</option> <option value="4">2-hour HD movie</option> <option value="40">iPod Game</option> </optgroup> <optgroup label="Playstation Network"> <option value="9">PS3 Game</option> <option value="24">PS4 Game</option> </optgroup> <option value=""></option> <option value=""></option> <option value=""></option> </select> </p> <p> <button id="calculateButton">Calculate</button> </p> </div> </form> <div id="results" style="visibility: visible;"> <div id="results_inner"> <p class="time"></p> <p class=""> <span class="size"></span> </p> <p class=""> <span class="speed"></span></p> </div> <hr> <div id="downloadSimulatorWindow" style="visibility: visible;"> <div class="filename">Simulation</div> <div class="icon"></div> <div class="percent"></div> <div class="progresrbar"><progress max="100" value="0"></progress></div> <div class="details"> <span class="downloaded"></span> of <span class="size"></span> (<span class="speed"></span>/sec) <span> - </span> <span class="remaining"></span> remaining </div> <div class="ps">* this is not an actual transfer, this is just a simulation of how much time it would take</div> </div> </div> <div class="footer"> <a href="#">Download-Calculator</a> </div> </div> <script> var downloadSimulator = null; window.onload=function(){ calculateButton.onclick = calc; var hasFlash = function() { if(typeof navigator.plugins == "undefined" || navigator.plugins.length == 0){ try{ return !!(new ActiveXObject("ShockwaveFlash.ShockwaveFlash")); }catch(e){ return undefined; } }else{ return navigator.plugins["Shockwave Flash"]; } }; if(!hasFlash()){ speedtest.style.display = 'none'; speedtestLink.innerHTML = "Test my internet speed"; document.querySelector('.idkSpeed').classList.add("mobile"); } downloadSimulator = new Downloader(document.getElementById('downloadSimulatorWindow')); if(window.location.hash){ var uri = window.location.hash; internetSpeed.value = uri.match(/speed=([\d.]+)x(\d+\^\d+)/)[1]; internetSpeedBase.value = uri.match(/speed=([\d.]+)x(\d+\^\d+)/)[2]; internetOverhead.value = uri.match(/overhead=([\d.]+)/)[1]; fileSize.value = uri.match(/file=([\d.]+)x(\d+\^\d+)/)[1]; fileSizeBase.value = uri.match(/file=([\d.]+)x(\d+\^\d+)/)[2]; calc(); }else if(window.localStorage){ if(window.localStorage.getItem('downloadtime.speed')){ internetSpeed.value = window.localStorage.getItem('downloadtime.speed'); internetSpeedBase.value = window.localStorage.getItem('downloadtime.speedBase'); internetOverhead.value = window.localStorage.getItem('downloadtime.overhead'); fileSize.value = window.localStorage.getItem('downloadtime.file'); fileSizeBase.value = window.localStorage.getItem('downloadtime.fileBase'); }else defaults(); }else defaults(); document.getElementsByTagName("form")[0].onsubmit = function(e){ if (e.stopPropagation) e.stopPropagation(); else e.cancelBubble = true; if (e.preventDefault) e.preventDefault(); else e.returnValue = false; this.returnValue = false; calc(); return false; } }; function defaults(){ internetSpeed.value = "10"; internetSpeedBase.value = "10^6"; internetOverhead.value = "0.9"; fileSize.value = "1"; fileSizeBase.value = "2^30"; } function calc(){ var internet = { speed: internetSpeed.value, factor: internetSpeedBase.value, overhead: internetOverhead.value, } internet.speed = parseFloat(internet.speed); internet.overhead = parseFloat(internet.overhead); internet.factor = { base: internet.factor.match(/(\d+)\^(\d+)/)[1], power: internet.factor.match(/(\d+)\^(\d+)/)[2] } internet.bitsPerSec = internet.speed * Math.pow(internet.factor.base, internet.factor.power); internet.bytesPerSec = internet.bitsPerSec/8; var file = { size: fileSize.value, factor: fileSizeBase.value, } file.size = parseFloat(file.size); file.factor = { base: file.factor.match(/(\d+)\^(\d+)/)[1], power: file.factor.match(/(\d+)\^(\d+)/)[2] } file.bytes = file.size * Math.pow(file.factor.base, file.factor.power); internet.effectiveBytesPerSec = internet.bytesPerSec * internet.overhead; var transferTime_ms = (file.bytes/internet.effectiveBytesPerSec)*1000; document.querySelector("#results .time").innerHTML = moment.preciseDiff(0, transferTime_ms); document.querySelector("#results .size").innerHTML = prefixByteLong(file.bytes); document.querySelector("#results .speed").innerHTML = prefixByte(internet.effectiveBytesPerSec); document.getElementById("results").style.visibility = "visible"; document.getElementById("downloadSimulatorWindow").style.visibility = "visible"; downloadSimulator.start(file.bytes, internet.effectiveBytesPerSec, "Simulation"); if(window.location){ var uri=[]; uri.push("file="+fileSize.value+"x"+fileSizeBase.value); uri.push("speed="+internetSpeed.value+"x"+internetSpeedBase.value); uri.push("overhead="+internetOverhead.value); window.location.hash = uri.join("&"); } if(window.localStorage){ window.localStorage.setItem('downloadtime.speed', internetSpeed.value); window.localStorage.setItem('downloadtime.speedBase', internetSpeedBase.value); window.localStorage.setItem('downloadtime.overhead', internetOverhead.value); window.localStorage.setItem('downloadtime.file', fileSize.value); window.localStorage.setItem('downloadtime.fileBase', fileSizeBase.value); } var t = msToTime(transferTime); console.log(t); str = []; if(t.years >= 1) str.push( t.years + " year" + (t.years>=2?"s":"") ); if(t.months >= 1) str.push( t.months + " month" + (t.months>=2?"s":"") ); if(t.weeks >= 1) str.push( t.weeks + " week" + (t.weeks>=2?"s":"") ); if(t.days >= 1) str.push( t.days + " day" + (t.days>=2?"s":"") ); if(t.hours >= 1) str.push( t.hours + " hour" + (t.hours>=2?"s":"") ); if(t.minutes >= 1) str.push( t.minutes + " minute" + (t.minutes>=2?"s":"") ); if(t.seconds >= 1) str.push( t.seconds + " second" + (t.seconds>=2?"s":"") ); if(t.ms >= 1) str.push( t.ms + " ms" ); time.innerHTML = str.join(", ")+"."; time.innerHTML = moment.duration(transferTime).humanize(); } function msToTime(ms) { debugger;; var t={}; t.ms = ms % 1000; ms = (ms - t.ms) / 1000; t.seconds = ms % 60; ms = (ms - t.seconds) / 60; t.minutes = ms % 60; ms = (ms - t.minutes) / 60; t.hours = ms % 60; ms = (ms - t.hours) / 60; t.days = ms % 24; ms = (ms - t.days) / 24; t.weeks = ms % 7; ms = (ms - t.weeks) / 7; t.months = ms % ((365/12)/7); ms = (ms - t.months) / ((365/12)/7); t.years = ms % (365/12); ms = (ms - t.years) / (365/12); console.log(JSON.stringify(t)); return t; } (function(moment) { var STRINGS = { nodiff: '', year: 'year', years: 'years', month: 'month', months: 'months', day: 'day', days: 'days', hour: 'hour', hours: 'hours', minute: 'minute', minutes: 'minutes', second: 'second', seconds: 'seconds', delimiter: ' ' }; moment.fn.preciseDiff = function(d2) { return moment.preciseDiff(this, d2); }; moment.preciseDiff = function(d1, d2) { var m1 = moment(d1), m2 = moment(d2); if (m1.isSame(m2)) { return STRINGS.nodiff; } if (m1.isAfter(m2)) { var tmp = m1; m1 = m2; m2 = tmp; } var yDiff = m2.year() - m1.year(); var mDiff = m2.month() - m1.month(); var dDiff = m2.date() - m1.date(); var hourDiff = m2.hour() - m1.hour(); var minDiff = m2.minute() - m1.minute(); var secDiff = m2.second() - m1.second(); if (secDiff < 0) { secDiff = 60 + secDiff; minDiff--; } if (minDiff < 0) { minDiff = 60 + minDiff; hourDiff--; } if (hourDiff < 0) { hourDiff = 24 + hourDiff; dDiff--; } if (dDiff < 0) { var daysInLastFullMonth = moment(m2.year() + '-' + (m2.month() + 1), "YYYY-MM").subtract('months', 1).daysInMonth(); if (daysInLastFullMonth < m1.date()) { // 31/01 -> 2/03 dDiff = daysInLastFullMonth + dDiff + (m1.date() - daysInLastFullMonth); } else { dDiff = daysInLastFullMonth + dDiff; } mDiff--; } if (mDiff < 0) { mDiff = 12 + mDiff; yDiff--; } function pluralize(num, word) { return num + ' ' + STRINGS[word + (num === 1 ? '' : 's')]; } var result = []; if (yDiff) { result.push(pluralize(yDiff, 'year')); } if (mDiff) { result.push(pluralize(mDiff, 'month')); } if (dDiff) { result.push(pluralize(dDiff, 'day')); } if (hourDiff) { result.push(pluralize(hourDiff, 'hour')); } if (minDiff) { result.push(pluralize(minDiff, 'minute')); } if (secDiff) { result.push(pluralize(secDiff, 'second')); } return result.join(STRINGS.delimiter); }; }(moment)); function Downloader(elm){ var self = this; this.fileSize; this.speed; this.DOM = { progress: elm.querySelector('progress'), percent: elm.querySelector('.percent'), downloaded: elm.querySelector('.downloaded'), details: elm.querySelector('.details'), size: elm.querySelector('.size'), speed: elm.querySelector('.speed'), remaining: elm.querySelector('.remaining'), filename: elm.querySelector('.filename') } var _transferTime; var _startTime; var _elapsedTime; var _remainingTime; var _downloaded; var _percent; var _timer; this.start = function(fileSize, speed, filename){ this.DOM.filename.innerHTML = filename; clearInterval(_timer); _startTime = Date.now(); _downloaded = 0; _percent = 0; self.fileSize = fileSize; self.speed = speed; _transferTime = (fileSize / speed)*1000; this.DOM.details.style.display = ""; self.update(); _timer = setInterval(function(){self.update()},500); } this.update = function(){ var now = Date.now(); _elapsedTime = now - _startTime; _remainingTime = _transferTime - _elapsedTime; _percent = (_elapsedTime / _transferTime) * 100; _downloaded = this.fileSize * (_elapsedTime / _transferTime); this.DOM.progress.value = _percent; this.DOM.percent.innerHTML = (_percent<<0) + "%"; this.DOM.downloaded.innerHTML = prefixByte(_downloaded); this.DOM.size.innerHTML = prefixByte(this.fileSize); this.DOM.speed.innerHTML = prefixByte(this.speed); this.DOM.remaining.innerHTML = moment.duration(_remainingTime).humanize(); if(_elapsedTime>=_transferTime){ this.stop(); } } this.stop = function(){ clearInterval(_timer); _elapsedTime = -1; _remainingTime = 0; _percent = 100; _downloaded = this.fileSize; this.DOM.progress.value = 100; this.DOM.percent.innerHTML = "100%"; this.DOM.downloaded.innerHTML = prefixByte(this.fileSize); this.DOM.size.innerHTML = prefixByte(this.fileSize); this.DOM.speed.innerHTML = prefixByte(this.speed); this.DOM.remaining.innerHTML = "0"; this.DOM.details.style.display = "none"; } } function Prefixer(unit, prefix, format){ for(var i=0; i<prefix.length; i++){ prefix[i][4] = Math.pow(prefix[i][0], prefix[i][1]); } return function(x){ x=parseFloat(x); var r, n=x<0?-1:1; x = x*n; for(var i=0; i<prefix.length; i++){ if(x>=prefix[i][4]-1){ r = prefix[i]; } else break; } x = x*n; x = (x/r[4]); var obj = { value: x, symbol: r[2], prefix: r[3], base: r[0], factor: r[1], plural: x!=1?true:false, s: x!=1?"s":"", unit: unit, units: x!=1?unit+"s":unit }; return format?format.apply(obj):obj; } } var prefixByte = new Prefixer("B",[ [2, 0, '', ''], [2, 10, 'K', 'Kilo'], [2, 20, 'M', 'Mega'], [2, 30, 'G', 'Giga'], [2, 40, 'T', 'Tera'], [2, 50, 'P', 'Peta'], [2, 60, 'E', 'Exa'], [2, 70, 'Z', 'Zetta'], [2, 80, 'Y', 'Yotta'] ], function(){ return parseFloat(this.value.toFixed(2))+" "+this.symbol+this.unit; } ); var prefixByteLong = new Prefixer("byte",[ [2, 0, '', ''], [2, 10, 'K', 'Kilo'], [2, 20, 'M', 'Mega'], [2, 30, 'G', 'Giga'], [2, 40, 'T', 'Tera'], [2, 50, 'P', 'Peta'], [2, 60, 'E', 'Exa'], [2, 70, 'Z', 'Zetta'], [2, 80, 'Y', 'Yotta'] ], function(){ return parseFloat(this.value.toFixed(2))+" "+this.prefix+this.units; } ); var prefixBit = new Prefixer("bit",[ [10, 0, '', ''], [10, 3, 'K', 'Kilo'], [10, 6, 'M', 'Mega'], [10, 9, 'G', 'Giga'], [10, 12, 'T', 'Tera'], [10, 15, 'P', 'Peta'], [10, 18, 'E', 'Exa'], [10, 21, 'Z', 'Zetta'], [10, 24, 'Y', 'Yotta'] ], function(){ return this.value+" "+this.symbol+this.unit; } ); var prefixBitLong = new Prefixer("bit",[ [10, 0, '', ''], [10, 3, 'K', 'Kilo'], [10, 6, 'M', 'Mega'], [10, 9, 'G', 'Giga'], [10, 12, 'T', 'Tera'], [10, 15, 'P', 'Peta'], [10, 18, 'E', 'Exa'], [10, 21, 'Z', 'Zetta'], [10, 24, 'Y', 'Yotta'] ], function(){ return this.value+" "+this.prefix+this.units; } ); </script> </body></html>