Created
August 8, 2017 05:13
-
-
Save brandonregard/32709a55e56a61bd9e9b6399db09f56b to your computer and use it in GitHub Desktop.
wunderground using jQuery, backbone, and flot...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
wui.Models = {}; | |
wui.Collections = {}; | |
wui.Views = {}; | |
wui.backbone = {}; | |
(function(b, c) { | |
var a = { | |
isValidMeasurement: function(d) { | |
if (d === null) { | |
return false | |
} else { | |
if (typeof (d) == "undefined") { | |
return false | |
} else { | |
if (d === "") { | |
return false | |
} else { | |
if (d == "-999") { | |
return false | |
} else { | |
if (d == "-9999") { | |
return false | |
} else { | |
if (parseFloat(d) <= -999) { | |
return false | |
} else { | |
return true | |
} | |
} | |
} | |
} | |
} | |
} | |
}, | |
convertNumbersInString: function(j, i) { | |
if (_.isNull(j) || _.isUndefined(j) || _.isUndefined(i)) { | |
return j | |
} | |
var f = /\d+/g; | |
var k = 0; | |
var g = 0; | |
var e = ""; | |
var h; | |
var d; | |
j = j.toString(); | |
while ((d = f.exec(j)) !== null) { | |
e += j.substring(k, d.index); | |
h = i(d); | |
e += h; | |
k = d.index + d.toString().length | |
} | |
return e | |
}, | |
filterObject: function(f, e) { | |
var d = {}; | |
_.each(f, function(h, g) { | |
if (e(g, h)) { | |
d[g] = h | |
} | |
}); | |
return d | |
}, | |
fromDateObjectToTimestamp: function(e, d) { | |
var f = (d) ? d.tz_offset_hours : 0; | |
return Date.UTC(parseInt(e.year, 10), parseInt(e.mon, 10) - 1, parseInt(e.mday, 10), parseInt(e.hour, 10) + f, parseInt(e.min, 10)) | |
}, | |
fromPrefToBoolean: function(d, e) { | |
if (d === "1" || d === 1 || d === "true" || d === true) { | |
return true | |
} else { | |
if (d === "0" || d === 0 || d === "false" || d === false) { | |
return false | |
} else { | |
return e | |
} | |
} | |
}, | |
getBeginningOfDay: function(f, h) { | |
var g = new Date(f); | |
var e = b.date.increment(g, h, "hour"); | |
var i = b.date.floor(e, "day"); | |
return i | |
}, | |
getTimestamp: function(i, e) { | |
var h = (e) ? e.tz_offset_hours : 0; | |
if (c.type(i) === "date") { | |
var g = b.date.create(h, "hour", i); | |
var f = g.getTime(); | |
return f | |
} else { | |
if (i.utcdate) { | |
return a.fromDateObjectToTimestamp(i.utcdate, e) | |
} else { | |
if (i.FCTTIME) { | |
return (parseFloat(i.FCTTIME.epoch) + h * 3600) * 1000 | |
} else { | |
if (i.date && i.date.epoch) { | |
var f = (parseFloat(i.date.epoch) + h * 3600) * 1000; | |
return f | |
} else { | |
if (i.epoch) { | |
var f = (parseFloat(i.epoch) + h * 3600) * 1000; | |
return f | |
} | |
} | |
} | |
} | |
} | |
return null | |
}, | |
getTimeAgo: function(j, g) { | |
g = c.extend({ | |
now: null, | |
numFields: 0 | |
}, g); | |
var m = []; | |
var e = g.now; | |
if (!e) { | |
e = new Date() | |
} | |
var l = e - j; | |
var k = Math.round(l / 1000); | |
var n = k % 60 | |
, f = Math.floor(k / 60) % 60 | |
, h = Math.floor(k / 3600); | |
if (h > 0) { | |
m.push({ | |
period: "hour", | |
label: "hr", | |
value: h | |
}) | |
} | |
if (f > 0) { | |
m.push({ | |
period: "minute", | |
label: "min", | |
value: f | |
}) | |
} | |
if (true) { | |
m.push({ | |
period: "second", | |
label: "sec", | |
value: n | |
}) | |
} | |
if (g.numFields) { | |
m = _.first(m, g.numFields) | |
} | |
var i = _.map(m, function(d) { | |
return d.value + " " + d.label | |
}).join(" "); | |
i += " ago"; | |
return i | |
}, | |
getTimezoneFromAPI: function(e) { | |
var f = null; | |
var d = e.get("response.date"); | |
if (d) { | |
f = _.pick(d, ["tz_short", "tz_long", "tz_offset_text", "tz_offset_hours"]) | |
} | |
return f | |
}, | |
getAstronomyMarkings: function(s, e, m) { | |
var n = null | |
, f = null | |
, k = [] | |
, e = e || {} | |
, o = null | |
, q = null | |
, g = (e.dayColor != "transparent") | |
, r = (e.nightColor != "transparent") | |
, m = m || null; | |
if (!s) { | |
return k | |
} | |
for (var j = 0, h = s.length; j < h; j++) { | |
var p = s[j]; | |
if (p.sunrise.date.epoch) { | |
n = new Date(p.sunrise.date.epoch * 1000); | |
o = a.getTimestamp(n, m) | |
} | |
if (r) { | |
f = c.extend({ | |
xaxis: { | |
from: q, | |
to: o | |
} | |
}, { | |
color: e.nightColor, | |
yaxis: e.yaxis | |
}); | |
k.push(f) | |
} | |
if (p.sunset.date.epoch) { | |
n = new Date(p.sunset.date.epoch * 1000); | |
q = a.getTimestamp(n, m) | |
} | |
if (g) { | |
f = c.extend({ | |
xaxis: { | |
from: o, | |
to: q | |
} | |
}, { | |
color: e.dayColor, | |
yaxis: e.yaxis | |
}); | |
k.push(f) | |
} | |
} | |
if (r) { | |
f = c.extend({ | |
xaxis: { | |
from: q, | |
to: null | |
} | |
}, { | |
color: e.nightColor, | |
yaxis: e.yaxis | |
}); | |
k.push(f) | |
} | |
return k | |
}, | |
getVariableUnits: function(e, g, d) { | |
var f = ""; | |
if (c.isFunction(e.units)) { | |
f = e.units.call(null, g, e, d) | |
} else { | |
if (e.units) { | |
f = '<span class="units">' + e.units + "</span>" | |
} | |
} | |
return f | |
}, | |
hourlyStripes: function(i) { | |
var l = i.xaxis; | |
if (l.options.mode != "time") { | |
return null | |
} | |
var g = []; | |
var f = b.date.floor(new Date(l.min), "day") | |
, n = new Date(l.max) | |
, m = (l.max - l.min) | |
, j = 86400 * 1000 * 1.02 | |
, k = (m > j) ? 6 : 1 | |
, h = b.date.roundDownTo(f, k, "hour") | |
, e = null; | |
while (h < n) { | |
e = b.date.create(k, "hour", h); | |
h = b.date.create(k, "hour", e); | |
g.push({ | |
xaxis: { | |
from: e.getTime(), | |
to: h.getTime() | |
}, | |
color: "#ffffff" | |
}) | |
} | |
return g | |
}, | |
rotate: function(e, i) { | |
var h = false; | |
if (Modernizr && Modernizr.csstransforms) { | |
h = true | |
} | |
if (!h) { | |
return | |
} | |
var g; | |
var f; | |
var d = (i % 1) ? i.toFixed(4) : i; | |
if (h) { | |
g = "transform"; | |
f = "rotate(" + d + "deg)"; | |
if (Modernizr && Modernizr.prefixed) { | |
g = Modernizr.prefixed(g) | |
} | |
} | |
if (g) { | |
e.css(g, f) | |
} | |
}, | |
roundTimestamp: function(d, e) { | |
e = e || 1; | |
return Math.round(d / e) * e | |
}, | |
setTransitionDuration: function(d, g) { | |
var h = false; | |
if (Modernizr && Modernizr.csstransitions) { | |
h = true | |
} | |
if (!h) { | |
return | |
} | |
var f = "TransitionDuration"; | |
var e = "" + g + "ms"; | |
if (Modernizr && Modernizr.prefixed) { | |
f = Modernizr.prefixed(f) | |
} | |
if (f) { | |
d.css(f, e) | |
} | |
}, | |
symbols: { | |
arrow: function(g, f, j, e, i) { | |
var d = 2 * e; | |
var h = d * 2 / 3; | |
g.moveTo(f - h / 2, j - d / 2); | |
g.lineTo(f, j - d / 4); | |
g.lineTo(f + h / 2, j - d / 2); | |
if (!i) { | |
g.lineTo(f, j + d / 2); | |
g.lineTo(f - h / 2, j - d / 2) | |
} | |
} | |
}, | |
tickPresets: { | |
"1day": { | |
tickSize: [1, "day"], | |
timeformat: "%a %m/%d" | |
}, | |
"3hour": { | |
tickSize: [3, "hour"], | |
timeformat: "%l %p" | |
} | |
}, | |
tickZoomPresets: { | |
"1day3hour": function(e) { | |
var d = a.tickPresets; | |
if (e) { | |
return d["3hour"] | |
} else { | |
return d["1day"] | |
} | |
} | |
}, | |
translate: function(j, d) { | |
var m = d.x || 0; | |
var k = d.y || 0; | |
var i = d.z || 0; | |
var l = (m % 1) ? m.toFixed(4) : m; | |
var g = (k % 1) ? k.toFixed(4) : k; | |
var f = (i % 1) ? i.toFixed(4) : i; | |
var o; | |
var n; | |
var e = false; | |
var h = false; | |
if (Modernizr && Modernizr.csstransforms3d) { | |
h = true | |
} | |
if (Modernizr && Modernizr.csstransforms) { | |
e = true | |
} | |
if (h || e) { | |
o = "transform"; | |
if (Modernizr && Modernizr.prefixed) { | |
o = Modernizr.prefixed(o) | |
} | |
if (h) { | |
n = "translate3d(" + l + "px, " + g + "px, " + f + "px)" | |
} else { | |
if (e) { | |
n = "translate(" + l + "px, " + g + "px)" | |
} | |
} | |
} else { | |
o = "left"; | |
n = m | |
} | |
if (o) { | |
j.css(o, n) | |
} | |
}, | |
updateVariable: function(g, d, f, e) { | |
e = c.extend(true, { | |
classNames: { | |
updated: "wx-updated", | |
windDirVariable: "wind-dir-vrb", | |
wxdata: "wx-data", | |
wxunit: "wx-unit", | |
wxvalue: "wx-value" | |
}, | |
duration: 5000, | |
unit: null | |
}, e); | |
if (e.duration > 0) { | |
g.addClass(e.classNames.updated).delay(e.duration).queue(function() { | |
c(this).removeClass(e.classNames.updated).dequeue() | |
}) | |
} | |
g.find("." + e.classNames.wxvalue).html(f); | |
if (e.unit !== null) { | |
g.find("." + e.classNames.wxunit).html(e.unit) | |
} | |
}, | |
generateCityQuery: function(e) { | |
var d = ""; | |
var f = e.country ? e.country.toLowerCase() : "us"; | |
d += "/zmw:" + e.zip + "." + e.magic + "." + e.wmo; | |
return d | |
} | |
}; | |
b.backbone.utils = a | |
})(wui, jQuery); | |
(function(b, c) { | |
var a = b.backbone.utils; | |
var d = { | |
createPlotGroupModel: function(e) { | |
e = e || {}; | |
var g = e.weather; | |
var n = e.prefs; | |
if (!n && b.bootstrapped) { | |
n = b.bootstrapped.prefs | |
} | |
var j = g.get("forecast.days[0]"); | |
var m = j.summary.date; | |
var k = a.fromPrefToBoolean(n.EXPFCT, true) || g.get("forecast.source") === "bestfct"; | |
var h = k ? 10 : 7; | |
var l = a.getBeginningOfDay(m.epoch * 1000, m.tz_offset_hours); | |
var f = b.date.create(h, "day", l); | |
var i = new b.Models.PlotGroup({ | |
astronomy: { | |
markings: { | |
show: true | |
} | |
}, | |
bufferLeft: c(window).width(), | |
bufferRight: c(window).width(), | |
date_min: l, | |
date_max: f, | |
legends: true, | |
needleNow: true, | |
selectors: { | |
editDone: "#editDone", | |
editMode: "#editMode", | |
variablesMenu: "#plotVariablesMenu" | |
}, | |
tickZoomPreset: "1day3hour", | |
zoomable: true, | |
flot: { | |
series: { | |
grow: { | |
active: false | |
} | |
}, | |
}, | |
plots: [{ | |
variables: [], | |
astronomy: { | |
markings: { | |
show: false | |
} | |
}, | |
flot: { | |
datelabel: { | |
show: true | |
}, | |
yaxis: { | |
show: false | |
} | |
} | |
}, { | |
autoscale: true, | |
variables: [{ | |
preset: "dewpoint", | |
show: a.fromPrefToBoolean(n.CP_VAR_dp, false) | |
}, { | |
preset: "feelslike", | |
show: a.fromPrefToBoolean(n.CP_VAR_fl, false) | |
}, { | |
preset: "temperature", | |
show: a.fromPrefToBoolean(n.CP_VAR_temp, true) | |
}], | |
flot: { | |
grid: { | |
borderWidth: { | |
top: 0, | |
right: 1, | |
bottom: 1, | |
left: 1 | |
} | |
}, | |
yaxis: { | |
tickUnitsPreset: "temperature" | |
} | |
}, | |
freezeline: true, | |
reserveSpace: [10, 10] | |
}, { | |
variables: [{ | |
preset: "cloudcover", | |
show: a.fromPrefToBoolean(n.CP_VAR_cc, false) | |
}, { | |
preset: "pop", | |
show: a.fromPrefToBoolean(n.CP_VAR_pop, true), | |
legend: false, | |
options: { | |
lines: { | |
fill: false | |
} | |
} | |
}, { | |
preset: "pop_type_notsnow", | |
show: a.fromPrefToBoolean(n.CP_VAR_pop, true) | |
}, { | |
preset: "pop_type_snow", | |
show: a.fromPrefToBoolean(n.CP_VAR_pop, true) | |
}, { | |
preset: "humidity", | |
show: a.fromPrefToBoolean(n.CP_VAR_h, false) | |
}, { | |
preset: "pressure", | |
show: a.fromPrefToBoolean(n.CP_VAR_p, true), | |
options: { | |
yaxis: 2 | |
} | |
}], | |
flot: { | |
yaxes: [{ | |
min: 0, | |
max: 100, | |
ticks: [0, 25, 50, 75, 100], | |
tickUnitsPreset: "humidity" | |
}, { | |
tickDecimalsPreset: "pressure" | |
}] | |
} | |
}, { | |
variables: [{ | |
preset: "precip_today", | |
show: a.fromPrefToBoolean(n.CP_VAR_precip, false) | |
}, { | |
preset: "liquid_precip", | |
show: a.fromPrefToBoolean(n.CP_VAR_qpf, false) | |
}], | |
flot: { | |
yaxis: { | |
min: 0, | |
tickDecimalsPreset: "precip", | |
ticksPreset: "precip" | |
} | |
} | |
}, { | |
variables: [{ | |
preset: "wind_speed_dir", | |
show: a.fromPrefToBoolean(n.CP_VAR_wspd, true) | |
}] | |
}] | |
}); | |
return i | |
} | |
}; | |
b.backbone.configs = d | |
})(wui, jQuery); | |
wui.global.colorscales = { | |
"-60": "#9f94a7", | |
"-59": "#9f94a7", | |
"-58": "#9f94a7", | |
"-57": "#9f94a7", | |
"-56": "#9f94a7", | |
"-55": "#896ea0", | |
"-54": "#896ea0", | |
"-53": "#896ea0", | |
"-52": "#896ea0", | |
"-51": "#896ea0", | |
"-50": "#754a9a", | |
"-49": "#754a9a", | |
"-48": "#754a9a", | |
"-47": "#754a9a", | |
"-46": "#754a9a", | |
"-45": "#7c409f", | |
"-44": "#7c409f", | |
"-43": "#7c409f", | |
"-42": "#7c409f", | |
"-41": "#7c409f", | |
"-40": "#883da5", | |
"-39": "#883da5", | |
"-38": "#883da5", | |
"-37": "#883da5", | |
"-36": "#883da5", | |
"-35": "#953aac", | |
"-34": "#953aac", | |
"-33": "#953aac", | |
"-32": "#953aac", | |
"-31": "#953aac", | |
"-30": "#8341b4", | |
"-29": "#8341b4", | |
"-28": "#8341b4", | |
"-27": "#8341b4", | |
"-26": "#8341b4", | |
"-25": "#6f47bc", | |
"-24": "#6f47bc", | |
"-23": "#6f47bc", | |
"-22": "#6f47bc", | |
"-21": "#6f47bc", | |
"-20": "#5b4ec4", | |
"-19": "#5b4ec4", | |
"-18": "#5b4ec4", | |
"-17": "#5b4ec4", | |
"-16": "#5b4ec4", | |
"-15": "#445bc7", | |
"-14": "#445bc7", | |
"-13": "#445bc7", | |
"-12": "#445bc7", | |
"-11": "#445bc7", | |
"-10": "#4655c9", | |
"-9": "#4655c9", | |
"-8": "#4655c9", | |
"-7": "#4655c9", | |
"-6": "#4655c9", | |
"-5": "#1767c3", | |
"-4": "#1767c3", | |
"-3": "#1767c3", | |
"-2": "#1767c3", | |
"-1": "#1767c3", | |
"0": "#1278c8", | |
"1": "#1278c8", | |
"2": "#1278c8", | |
"3": "#1278c8", | |
"4": "#1278c8", | |
"5": "#1f91d7", | |
"6": "#1f91d7", | |
"7": "#1f91d7", | |
"8": "#1f91d7", | |
"9": "#1f91d7", | |
"10": "#2aa8e5", | |
"11": "#2aa8e5", | |
"12": "#2aa8e5", | |
"13": "#2aa8e5", | |
"14": "#2aa8e5", | |
"15": "#36c1f3", | |
"16": "#36c1f3", | |
"17": "#36c1f3", | |
"18": "#36c1f3", | |
"19": "#36c1f3", | |
"20": "#30bfef", | |
"21": "#30bfef", | |
"22": "#30bfef", | |
"23": "#30bfef", | |
"24": "#30bfef", | |
"25": "#28b7e6", | |
"26": "#28b7e6", | |
"27": "#28b7e6", | |
"28": "#28b7e6", | |
"29": "#28b7e6", | |
"30": "#1fafdd", | |
"31": "#1fafdd", | |
"32": "#1fafdd", | |
"33": "#1fafdd", | |
"34": "#1fafdd", | |
"35": "#32afb1", | |
"36": "#32afb1", | |
"37": "#32afb1", | |
"38": "#32afb1", | |
"39": "#32afb1", | |
"40": "#52b673", | |
"41": "#52b673", | |
"42": "#52b673", | |
"43": "#52b673", | |
"44": "#52b673", | |
"45": "#71bc3c", | |
"46": "#71bc3c", | |
"47": "#71bc3c", | |
"48": "#71bc3c", | |
"49": "#71bc3c", | |
"50": "#93c124", | |
"51": "#93c124", | |
"52": "#93c124", | |
"53": "#93c124", | |
"54": "#93c124", | |
"55": "#b6c609", | |
"56": "#b6c609", | |
"57": "#b6c609", | |
"58": "#b6c609", | |
"59": "#b6c609", | |
"60": "#f4b701", | |
"61": "#f4b701", | |
"62": "#f4b701", | |
"63": "#f4b701", | |
"64": "#f4b701", | |
"65": "#feae3c", | |
"66": "#feae3c", | |
"67": "#feae3c", | |
"68": "#feae3c", | |
"69": "#feae3c", | |
"70": "#fe9a3b", | |
"71": "#fe9a3b", | |
"72": "#fe9a3b", | |
"73": "#fe9a3b", | |
"74": "#fe9a3b", | |
"75": "#fd843b", | |
"76": "#fd843b", | |
"77": "#fd843b", | |
"78": "#fd843b", | |
"79": "#fd843b", | |
"80": "#ec5a34", | |
"81": "#ec5a34", | |
"82": "#ec5a34", | |
"83": "#ec5a34", | |
"84": "#ec5a34", | |
"85": "#da2f2f", | |
"86": "#da2f2f", | |
"87": "#da2f2f", | |
"88": "#da2f2f", | |
"89": "#da2f2f", | |
"90": "#d72a36", | |
"91": "#d72a36", | |
"92": "#d72a36", | |
"93": "#d72a36", | |
"94": "#d72a36", | |
"95": "#da3a45", | |
"96": "#da3a45", | |
"97": "#da3a45", | |
"98": "#da3a45", | |
"99": "#da3a45", | |
"100": "#dc4953", | |
"101": "#dc4953", | |
"102": "#dc4953", | |
"103": "#dc4953", | |
"104": "#dc4953", | |
"105": "#df5961", | |
"106": "#df5961", | |
"107": "#df5961", | |
"108": "#df5961", | |
"109": "#df5961", | |
"110": "#e26870", | |
"111": "#e26870", | |
"112": "#e26870", | |
"113": "#e26870", | |
"114": "#e26870", | |
"115": "#e5787f", | |
"116": "#e5787f", | |
"117": "#e5787f", | |
"118": "#e5787f", | |
"119": "#e5787f", | |
"120": "#e8878d", | |
"121": "#e8878d", | |
"122": "#e8878d", | |
"123": "#e8878d", | |
"124": "#e8878d", | |
"125": "#e8878d", | |
"126": "#e8878d", | |
"127": "#e8878d", | |
"128": "#e8878d", | |
"129": "#e8878d", | |
"130": "#e8878d", | |
"131": "#e8878d", | |
"132": "#e8878d", | |
"133": "#e8878d", | |
"134": "#e8878d", | |
"135": "#e8878d", | |
"136": "#e8878d", | |
"137": "#e8878d", | |
"138": "#e8878d", | |
"139": "#e8878d", | |
"140": "#e8878d", | |
"141": "#e8878d", | |
"142": "#e8878d", | |
"143": "#e8878d", | |
"144": "#e8878d", | |
"145": "#e8878d", | |
"146": "#e8878d", | |
"147": "#e8878d", | |
"148": "#e8878d", | |
"149": "#e8878d", | |
"150": "#e8878d", | |
"151": "#e8878d", | |
"152": "#e8878d", | |
"153": "#e8878d", | |
"154": "#e8878d", | |
"155": "#e8878d" | |
}; | |
(function(a) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Models.Page = Backbone.NestedModel.extend({ | |
defaults: function() { | |
return { | |
classNames: { | |
hover: "hover", | |
loading: "loading", | |
open: "open", | |
selected: "selected", | |
updated: "wx-updated", | |
windDirVariable: "wind-dir-vrb", | |
wxdata: "wx-data", | |
wxunit: "wx-unit", | |
wxvalue: "wx-value" | |
}, | |
iconset: "k", | |
favorites: { | |
bar: { | |
show: false | |
}, | |
list: { | |
enabled: false, | |
show: false | |
} | |
}, | |
timezone: { | |
"short": "UTC", | |
"long": "UTC", | |
offset: { | |
text: "+0000", | |
hours: 0 | |
} | |
}, | |
zmw: "" | |
} | |
}, | |
initialize: function(b, d) { | |
var e = _.result(this, "defaults"); | |
var c = a.extend(true, {}, e, b); | |
this.set(c, d); | |
this.changed = {} | |
} | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Views.Header = Backbone.View.extend({ | |
events: { | |
"submit #wuForm": "onSearchSubmit", | |
"focus #wuSearch": "onSearchOpen", | |
"blur #wuSearch": "onSearchClose", | |
"click .geolocate-wrap": "onGeolocate", | |
"click .menu-geolocate": "onGeolocate" | |
}, | |
initialize: function(c) { | |
this.options = c || {}; | |
var d = b("#feature-menu-mobile"); | |
if (wui.sidebar && wui.Menu && d[0]) { | |
b("<a>", { | |
id: "sidebar-gutter" | |
}).appendTo("#inner-wrap"); | |
var e = { | |
classNames: { | |
selected: "sidebar-active" | |
}, | |
eventName: "click.sidebar", | |
selectors: { | |
toggles: "#sidebarButton, #sidebar-gutter" | |
} | |
}; | |
wui.sidebar.initialize(e); | |
new wui.Menu({ | |
selectors: { | |
container: "#feature-menu-mobile .sidebar-wrapper" | |
} | |
}) | |
} | |
a(); | |
if (wui.HorizontalMenu) { | |
new wui.HorizontalMenu({ | |
menu: b("#feature-menu"), | |
selectors: { | |
menu: "ul.menu-list.primary-menu", | |
menu_item: "li" | |
}, | |
active_menu_class: "active", | |
hidden_menu_class: "hidden" | |
}); | |
b(".subnav-contain").each(function() { | |
new wui.HorizontalMenu({ | |
menu: b(this), | |
selectors: { | |
menu: "> .subnav.subnav-left", | |
right_matter: "> .subnav.subnav-right" | |
}, | |
active_menu_class: "active" | |
}) | |
}); | |
b(".wui-tabs-more-dl").each(function() { | |
new wui.HorizontalMenu({ | |
menu: b(this), | |
selectors: { | |
menu: "> dl", | |
menu_item: "dd" | |
}, | |
tags: { | |
menu: "dl", | |
menu_item: "dd" | |
} | |
}) | |
}) | |
} | |
}, | |
onSearchSubmit: function(c) { | |
var f = this.$el.find("#wuSearch"); | |
var d = f.val(); | |
if (!d) { | |
c.preventDefault(); | |
f.focus() | |
} | |
}, | |
onSearchOpen: function() { | |
this.$el.addClass("search-open") | |
}, | |
onSearchClose: function() { | |
this.$el.removeClass("search-open") | |
}, | |
onGeolocate: function() { | |
var e = this; | |
var d = { | |
searching: "Finding your location...", | |
success: "Loading forecast...", | |
successWundermap: "Loading location...", | |
error_permissions: "Can't find location. Check permissions.", | |
error_generic: "Couldn't find location. Try searching.", | |
}; | |
var c = wui.bootstrapped && wui.bootstrapped.pageType === "WunderMap"; | |
if (navigator.geolocation) { | |
this.$alertBar = b("#header-alert-bar").addClass("active").removeClass("not-found"); | |
this.$alertBar.text(d.searching); | |
navigator.geolocation.getCurrentPosition(function(f) { | |
var j = false; | |
if (f && f.coords) { | |
var h = f.coords.latitude; | |
var i = f.coords.longitude; | |
if (typeof h !== "undefined" && typeof i !== "undefined") { | |
var g = h + "," + i; | |
j = true; | |
e.showGeolocateFinished(c ? d.successWundermap : d.success, true); | |
if (c) { | |
b("#wuSearch").val(g); | |
wundermap.search.useAutocomplete(g, {}); | |
b("#wuSearch").val("") | |
} else { | |
window.location = "/cgi-bin/findweather/getForecast?query=" + g | |
} | |
} | |
} | |
if (!j) { | |
e.showGeolocateFinished(d.error_generic, false) | |
} | |
}, function(f) { | |
if (f.code == f.PERMISSION_DENIED) { | |
e.showGeolocateFinished(d.error_permissions, false) | |
} else { | |
e.showGeolocateFinished(d.error_generic, false) | |
} | |
}) | |
} else { | |
this.showGeolocateFinished(d.error_generic, false) | |
} | |
return false | |
}, | |
showGeolocateFinished: function(d, e) { | |
var g = this; | |
var c = e ? "found" : "not-found"; | |
var f = e ? 1000 : 5000; | |
this.$alertBar.addClass(c).text(d); | |
setTimeout(function() { | |
g.$alertBar.removeClass("active") | |
}, f) | |
} | |
}); | |
function a() { | |
var f = b("#feature-menu") | |
, c = f.children(".menu-list") | |
, d = b("<ul>", { | |
"class": "menu-list primary-menu" | |
}) | |
, e = f.find("> ul > li"); | |
e.each(function() { | |
var i = b(this); | |
if (i.is(":has(> ul.menu-list)")) { | |
var h = b("<li>").append(i.children("label")) | |
, g = b("<div>", { | |
"class": "menu-wrapper" | |
}) | |
, j = i.children("ul.menu-list"); | |
d.append(h); | |
h.data("menu", g.get(0)); | |
g.append(j); | |
f.append(g) | |
} else { | |
i.addClass("more-menu-only"); | |
d.append(i) | |
} | |
}); | |
f.append(d); | |
c.remove(); | |
f.addClass("visible") | |
} | |
})(jQuery); | |
$(function() { | |
var a = $("#global-header")[0]; | |
if (a) { | |
new wui.Views.Header({ | |
el: a | |
}) | |
} | |
}); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Models.Weather = Backbone.NestedModel.extend({ | |
defaults: function() { | |
return {} | |
}, | |
fetchMore: function(d) { | |
var c = this.url(d); | |
return this.fetch({ | |
url: c | |
}) | |
}, | |
getDays: function() { | |
var c = []; | |
var d; | |
d = this.get("history.days"); | |
if (d && d.length) { | |
c = c.concat(d) | |
} | |
d = this.get("forecast.days"); | |
if (d && d.length) { | |
c = c.concat(d) | |
} | |
return c | |
}, | |
getStationId: function() { | |
var c = this.get("current_observation.station.id"); | |
return c | |
}, | |
getUpdatedTimeAgo: function() { | |
var e = ""; | |
var f = this.get("current_observation.updated"); | |
if (_.isUndefined(f)) { | |
f = this.get("current_observation.date.epoch") | |
} | |
if (_.isUndefined(f)) { | |
var c = this.get("labels.not_available.label") || "--"; | |
e = c | |
} else { | |
var g = new Date(parseFloat(f) * 1000); | |
e = a.getTimeAgo(g, { | |
numFields: 1 | |
}) | |
} | |
return e | |
}, | |
initialize: function(c, d) { | |
this.options = b.extend(true, { | |
autoFetch: false | |
}, d); | |
if (this.options.autoFetch) { | |
this.fetch() | |
} | |
this.on("change:current_observation", this.onChangeCurrentObservation, this) | |
}, | |
isOffline: function() { | |
var f = this.get("current_observation.updated"); | |
var e = (new Date()).getTime() / 1000; | |
var d = true; | |
var c = 10800; | |
if (_.isUndefined(f)) { | |
f = this.get("current_observation.date.epoch") | |
} | |
if (!_.isUndefined(f) && e - f <= c) { | |
d = false | |
} | |
return d | |
}, | |
lookupWindString: function(c) { | |
if (c > 360) { | |
c = c % 360 | |
} | |
if (c >= 0 && c < 11.25) { | |
return "N" | |
} | |
if (c >= 11.25 && c < 33.75) { | |
return "NNE" | |
} | |
if (c >= 33.75 && c < 67.5) { | |
return "NE" | |
} | |
if (c >= 67.5 && c < 78.75) { | |
return "ENE" | |
} | |
if (c >= 78.75 && c < 101.25) { | |
return "E" | |
} | |
if (c >= 101.25 && c < 123.75) { | |
return "ESE" | |
} | |
if (c >= 123.75 && c < 146.25) { | |
return "SE" | |
} | |
if (c >= 146.25 && c < 168.75) { | |
return "SSE" | |
} | |
if (c >= 168.75 && c < 191.25) { | |
return "S" | |
} | |
if (c >= 191.25 && c < 213.75) { | |
return "SSW" | |
} | |
if (c >= 213.75 && c < 236.25) { | |
return "SW" | |
} | |
if (c >= 236.25 && c < 258.75) { | |
return "WSW" | |
} | |
if (c >= 258.75 && c < 281.25) { | |
return "W" | |
} | |
if (c >= 281.25 && c < 303.75) { | |
return "WNW" | |
} | |
if (c >= 303.75 && c < 326.25) { | |
return "NW" | |
} | |
if (c >= 326.25 && c < 348.75) { | |
return "NNW" | |
} | |
if (c >= 348.75) { | |
return "N" | |
} | |
return "-" | |
}, | |
mergeRapidfire: function(g) { | |
if (g) { | |
var e = this.get("current_observation"); | |
var d = a.filterObject(g, function(h, i) { | |
return i !== null | |
}); | |
if (_.has(d, "wind_dir_degrees")) { | |
var c = this.lookupWindString(d.wind_dir_degrees); | |
d.wind_dir = c | |
} | |
var f = b.extend(true, {}, e, d); | |
this.set({ | |
current_observation: f | |
}) | |
} | |
this.trigger("rapidfire", this, g) | |
}, | |
onChangeCurrentObservation: function() { | |
var d = this.getStationId(); | |
var c = this.previous("current_observation"); | |
if (c) { | |
if (c.station.id !== d) { | |
this.trigger("currentStationChange", d, c.station.id) | |
} | |
} | |
}, | |
sync: function(e, d, c) { | |
if (e == "read") { | |
c.cache = true | |
} | |
return Backbone.sync.call(this, e, d, c) | |
}, | |
url: function(d) { | |
d = b.extend({}, this.options, d); | |
var c = "//api-ak-aws.wunderground.com/api/" + this.options.apikey; | |
if (d.features) { | |
c += "/" + d.features.join("/"); | |
if ("history"in d.features) { | |
c.replace("/history/", "/history_" + wui.date.strftime("%Y%m%d") + "/") | |
} | |
} | |
if (d.lang) { | |
c += "/lang:" + d.lang | |
} | |
if (d.units) { | |
c += "/units:" + d.units | |
} | |
if (d.version) { | |
c += "/v:" + d.version | |
} | |
if (wui.arrayContains(d.bestfct, [0, false])) { | |
c += "/bestfct:0" | |
} | |
if (wui.arrayContains(d.bestfct, [1, true])) { | |
c += "/bestfct:1" | |
} | |
c += "/q/" + d.query + ".json"; | |
c += "?ttl=300"; | |
if (d.fodqa) { | |
c += "&qa=1&fod=1" | |
} | |
if (d.selected_pws) { | |
c += "&sp=" + d.selected_pws | |
} | |
return c | |
} | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Models.Location = Backbone.NestedModel.extend({ | |
defaults: function() { | |
return { | |
lat: 0, | |
lon: 0, | |
name: "", | |
type: "", | |
zmw: "" | |
} | |
}, | |
idAttribute: "zmw" | |
}) | |
})(jQuery); | |
(function(a) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Models.PlotGroup = Backbone.NestedModel.extend({ | |
defaults: function() { | |
return { | |
astronomy: { | |
markings: { | |
show: false, | |
dayColor: "transparent", | |
nightColor: "#f4f4f4", | |
yaxis: {} | |
} | |
}, | |
bufferLeft: 0, | |
bufferRight: 0, | |
classNames: { | |
editMode: "editMode", | |
hasHeader: "has-header", | |
hasPrecip: "has-precip", | |
header: "plot-header", | |
hidden: "hidden", | |
legend: "plot-legend", | |
needle: "plot-needle", | |
needleLabelBottom: "needle-label-bottom", | |
needleLabelTop: "needle-label-top", | |
needleLine: "plot-needle-line", | |
needleNow: "plot-needle-now", | |
numberedItem: "n", | |
lastPlot: "plot-last", | |
plot: "plot", | |
plots: "plots", | |
selected: "selected" | |
}, | |
date_min: "auto", | |
date_max: "auto", | |
dayMaxWidth: 82, | |
editMode: false, | |
fitDuration: 250, | |
iconset: "v3", | |
legends: false, | |
mode: "forecast", | |
needleDateFormat: null, | |
needleDateLabels: false, | |
needleNow: false, | |
panDuration: 1000, | |
selectors: { | |
checkboxes: null, | |
editDone: null, | |
editMode: null, | |
variablesMenu: null | |
}, | |
tickZoomPreset: "", | |
zoomable: false, | |
zoomDuration: 1000, | |
flot: { | |
grid: { | |
autoHighlight: false, | |
clickable: false, | |
hoverable: false, | |
labelMargin: 0, | |
minBorderMargin: 0, | |
mouseActiveRadius: 5 | |
}, | |
legend: { | |
show: false | |
}, | |
needle: { | |
show: true | |
}, | |
series: { | |
bars: { | |
barWidth: 60 * 60 * 1000 | |
}, | |
shadowSize: 0 | |
}, | |
touch: { | |
autoHeight: false, | |
autoWidth: false, | |
childrenSelector: "canvas, .flot-header", | |
pan: "x", | |
scale: "x" | |
}, | |
xaxis: { | |
labelHeight: 0.1, | |
tickFormatter: function(c, b) { | |
return "" | |
} | |
}, | |
yaxis: { | |
alignTicksWithAxis: 1, | |
labelHeight: 1, | |
labelWidth: 30, | |
tickDecimals: 0, | |
tickFormatter: function(c, b) { | |
return c.toFixed(b.tickDecimals) + (b.options.tickUnits || "") | |
} | |
} | |
}, | |
plots: [] | |
} | |
}, | |
initialize: function(b, d) { | |
var e = _.result(this, "defaults"); | |
var c = a.extend(true, {}, e, b); | |
this.set(c, d); | |
this.changed = {} | |
} | |
}) | |
})(jQuery); | |
(function(c) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
var b = wui.bootstrapped.prefs; | |
wui.Models.Precip = Backbone.NestedModel.extend({ | |
events: {}, | |
defaults: function() { | |
return {} | |
}, | |
fetch: function(d) { | |
var e = this; | |
return Backbone.Model.prototype.fetch.apply(this, d).fail(function() { | |
e.set("success", false); | |
e.set("graphMessage", wui.bootstrapped.precip.errors.graph); | |
e.set("tableMessage", wui.bootstrapped.precip.errors.table); | |
e.set("precipUpdated", new Date().getTime()) | |
}) | |
}, | |
fetchStatement: function() { | |
this.updateURL(); | |
var d = this.urlBase + "/forecast/wwir.json" + this.urlQueryString; | |
var e = this; | |
c.ajax(d).done(function(g) { | |
var f = g.forecast; | |
if (f) { | |
e.set("eventType", e.eventTypes[f.overall_type]); | |
e.set("statementTerse", f.terse_phrase); | |
e.set("statement", f.phrase); | |
e.set("lastUpdated", new Date()); | |
e.set("statementSuccess", true) | |
} | |
}).fail(function() { | |
e.set("eventType", "noprecip"); | |
e.set("statementSuccess", false); | |
e.set("statement", wui.bootstrapped.precip.errors.statement) | |
}) | |
}, | |
setEndTime: function() { | |
this.endTime = this.startTime + 3600 * 6 | |
}, | |
getTimezone: function(e) { | |
if (this.timezone) { | |
return this.timezone | |
} | |
var d = e.length; | |
return this.timezone = d ? e.substring(d - 5, d - 2) : "" | |
}, | |
initialize: function(d, e) { | |
var f = this; | |
this.options = c.extend(true, { | |
autoFetch: false | |
}, e); | |
this.apiKey = this.options.apikey; | |
this.lang = this.options.lang || "en"; | |
this.units = this.options.units === "metric" ? "m" : "e"; | |
this.lat = this.options.lat; | |
this.lon = this.options.lon; | |
this.version = this.options.version || "v1"; | |
if (this.lang && this.lang.indexOf("-") !== -1) { | |
this.lang = this.lang.split("-")[0] | |
} | |
if (this.lang && this.lang.indexOf("_") !== -1) { | |
this.lang = this.lang.split("_")[0] | |
} | |
this.eventTypes = ["noprecip", "rain", "snow", "mix", "thunder"]; | |
this.intensityLabels = ["", "Light", "Moderate", "Heavy"]; | |
this.typeLabels = ["No Precipitation", "Rain", "Snow", "Mix", "Rain"]; | |
this.typeLabelMap = { | |
noprecip: "No Precipitation", | |
rain: "Rain", | |
snow: "Snow", | |
mix: "Mix", | |
thunder: "Rain" | |
}; | |
this.intensityHeights = [0, 49, 99, 150]; | |
this.yValues = ["", 101, 51, 0]; | |
this.timezone = ""; | |
this.updateURL(); | |
if (this.options.autoFetch) { | |
this.fetch().done(function(g) { | |
f.set("precipUpdated", new Date().getTime()) | |
}) | |
} | |
if (this.options.fetchStatement) { | |
this.fetchStatement() | |
} | |
}, | |
updateURL: function() { | |
var d = "//api.weather.com/" + this.version + "/geocode"; | |
var e = new Date().getTime(); | |
if (this.lat) { | |
d += "/" + this.lat + e | |
} | |
if (this.lon) { | |
d += "/" + this.lon + e | |
} | |
this.urlBase = d; | |
this.urlQueryString = "?apiKey=" + this.apiKey + "&units=" + this.units + "&language=" + this.lang | |
}, | |
getIntensity: function(j, m, l) { | |
var g = 0; | |
if (m !== "noprecip") { | |
var j = l === "m" ? (m === "rain" ? j / 25.4 : j / 2.54) : j; | |
var d = [0, 0.1, 0.4]; | |
var e = [0, 1, 2]; | |
var f = m === "rain" ? d : e; | |
for (var h = 0, k = f.length; h < k; h++) { | |
if (j >= f[h]) { | |
g = h | |
} | |
} | |
g++ | |
} | |
return g | |
}, | |
parse: function(d) { | |
return wui.bootstrapped.precip && wui.bootstrapped.precip.chunky ? this.parsePrecip(d) : this.parseFifteen(d) | |
}, | |
parseFifteen: function(j) { | |
if (typeof j.forecasts === "undefined" || !j.forecasts.length) { | |
return false | |
} | |
var m = this; | |
var h = 900; | |
var d = 3600 * 6; | |
var r = []; | |
var q = 0; | |
var f = 0; | |
var e = false; | |
var p = false; | |
var o = j.metadata.units; | |
var n = j.forecasts[0]; | |
var l = m.getTimezone(n.fcst_valid_local); | |
var i = j.metadata.transaction_id; | |
var g = b.BrowserCode || b.LangCode; | |
var k = []; | |
this.startTime = n.fcst_valid; | |
this.setEndTime(); | |
_.each(j.forecasts, function(x, B) { | |
var w = g.indexOf("en") >= 0 ? "%l:%M %P" : "%H:%M"; | |
var s = x.fcst_valid; | |
var z = s + h; | |
var E = x.precip_type === "precip" ? "mix" : x.precip_type; | |
var C = E === "rain" || E == "mix" ? x.precip_rate : x.snow_rate; | |
if (x.pop < 30 && C === 0) { | |
E = "noprecip" | |
} | |
var y = C * 0.25; | |
var t = m.getIntensity(C, E, o); | |
var A = k.length; | |
var v = 15; | |
var u = { | |
epoch: s, | |
tz_offset_hours: l | |
}; | |
var D = { | |
epoch: z, | |
tz_offset_hours: l | |
}; | |
if (!A || k[A - 1].type !== E || k[A - 1].intensity !== t) { | |
k.push({ | |
type: E, | |
intensity: t, | |
timeStart: wui.date.strftime(w, u), | |
timeEnd: wui.date.strftime(w, D), | |
amount: y, | |
duration: 15, | |
height: m.intensityHeights[t], | |
y: m.yValues[t], | |
intensityLabel: m.intensityLabels[t], | |
typeLabel: m.typeLabelMap[E], | |
hasThunder: false | |
}) | |
} else { | |
var F = k[A - 1]; | |
F.duration += 15; | |
F.timeEnd = wui.date.strftime(w, D); | |
F.amount += y | |
} | |
if (E === "rain" || E === "mix") { | |
e = true; | |
q += y | |
} else { | |
if (E === "snow") { | |
p = true; | |
f += y | |
} | |
} | |
}); | |
return { | |
success: true, | |
totals: { | |
liquid: q, | |
snow: f | |
}, | |
hasLiquid: e, | |
hasSnow: p, | |
events: k | |
} | |
}, | |
parsePrecip: function(g) { | |
if (typeof g.forecasts === "undefined" || !g.forecasts.length) { | |
return false | |
} | |
var j = this; | |
var f = 900; | |
var h = 32; | |
var l = f / h; | |
var o = []; | |
var n = 0; | |
var e = 0; | |
var d = false; | |
var m = false; | |
var k = g.forecasts[0]; | |
var i = j.getTimezone(k.event_start_local); | |
_.each(g.forecasts, function(u, x) { | |
if (x === 0) { | |
j.startTime = u.event_start; | |
j.setEndTime() | |
} | |
var q = {}; | |
var z = u.event_start < j.startTime ? j.startTime : u.event_start; | |
var w = u.event_end > j.endTime ? j.endTime : u.event_end; | |
var p = u.event_type; | |
var r = u.intensity; | |
var v = p === 2 ? u.snow_qpf : u.qpf; | |
var t = { | |
epoch: z, | |
tz_offset_hours: i | |
}; | |
var A = { | |
epoch: w, | |
tz_offset_hours: i | |
}; | |
var s = "%l:%M %P"; | |
var y = j.eventTypes[p]; | |
if (z >= j.endTime) { | |
return false | |
} | |
if (p) { | |
q = { | |
width: (w - z) / l - 1, | |
x: (z - j.startTime) / l + 1 + h, | |
height: j.intensityHeights[r], | |
y: j.yValues[r] | |
} | |
} | |
if (y === "rain" || y === "mix" || y === "thunder") { | |
d = true; | |
n += v | |
} else { | |
if (y === "snow") { | |
m = true; | |
e += v | |
} | |
} | |
y = y === "thunder" ? "rain" : y; | |
c.extend(q, { | |
duration: (w - z) / 60, | |
type: y, | |
amount: v, | |
timeStart: wui.date.strftime(s, t), | |
timeEnd: wui.date.strftime(s, A), | |
intensityLabel: j.intensityLabels[r], | |
typeLabel: j.typeLabels[p], | |
hasThunder: p === 4 | |
}); | |
o.push(q) | |
}); | |
return { | |
totals: { | |
liquid: n, | |
snow: e | |
}, | |
hasLiquid: d, | |
hasSnow: m, | |
events: o | |
} | |
}, | |
url: function(e) { | |
var f = wui.bootstrapped.precip && wui.bootstrapped.precip.chunky ? "precipitation" : "fifteenminute"; | |
this.updateURL(); | |
var d = this.urlBase + "/forecast/" + f + ".json" + this.urlQueryString; | |
return d | |
} | |
}) | |
})(jQuery); | |
(function(c) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
var b = wui.bootstrapped.prefs; | |
wui.Models.Pollen = Backbone.NestedModel.extend({ | |
events: {}, | |
defaults: function() { | |
return {} | |
}, | |
fetch: function(d) { | |
var e = this; | |
return Backbone.Model.prototype.fetch.apply(this, d) | |
}, | |
parse: function(e) { | |
var g = {}; | |
if (e && e.length) { | |
var d = e[0]; | |
var j = 0; | |
var f = ""; | |
g.grass = d.vt1pollenforecast.grass; | |
g.tree = d.vt1pollenforecast.tree; | |
g.weed = d.vt1pollenforecast.weed; | |
for (var i in g) { | |
if (g[i]) { | |
var h = g[i][0]; | |
if (h !== null && h > j) { | |
j = h; | |
f = i | |
} | |
} | |
} | |
g.highestLevel = j; | |
g.pollenType = f | |
} | |
return g | |
}, | |
initialize: function(d, e) { | |
var f = this; | |
this.lat = e.lat; | |
this.lon = e.lon; | |
this.apiKey = e.apiKey; | |
this.fetch().done(function(g) { | |
f.set("success", true) | |
}) | |
}, | |
url: function(e) { | |
var d = "//api.weather.com/v2/turbo/vt1pollenforecast?geocodes=" + this.lat + "," + this.lon + "&format=json&language=en&apiKey=" + this.apiKey; | |
return d | |
} | |
}) | |
})(jQuery); | |
(function(c) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
var b = wui.bootstrapped.prefs; | |
wui.Models.WeatherFiveDay = Backbone.NestedModel.extend({ | |
events: {}, | |
defaults: function() { | |
return {} | |
}, | |
fetch: function(d) { | |
var e = this; | |
return Backbone.Model.prototype.fetch.apply(this, d) | |
}, | |
parse: function(d) { | |
return d | |
}, | |
initialize: function(d, e) { | |
var f = this; | |
this.lat = e.lat; | |
this.lon = e.lon; | |
this.apiKey = e.apiKey; | |
this.fetch().done(function(g) { | |
f.set("success", true) | |
}) | |
}, | |
url: function(e) { | |
var d = "//api.weather.com/v1/geocode/" + this.lat + "/" + this.lon + "/forecast/daily/5day.json?language=en-US&units=e&apiKey=" + this.apiKey; | |
return d | |
} | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Models.Station = Backbone.NestedModel.extend({ | |
defaults: function() { | |
return { | |
id: "", | |
lat: 0, | |
lon: 0, | |
name: "", | |
type: "", | |
} | |
} | |
}) | |
})(jQuery); | |
(function(c) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
var b = { | |
1: "85x64", | |
2: "85x64", | |
3: "85x64", | |
4: "85x64", | |
5: "155x155", | |
6: "155x114", | |
7: "320x260", | |
8: "320x180", | |
9: "485x273", | |
10: "650x366", | |
11: "815x458", | |
12: "980x551", | |
15: "640x598" | |
}; | |
wui.Models.Video = Backbone.NestedModel.extend({ | |
defaults: function() { | |
return { | |
clipid: "", | |
title: "", | |
description: "", | |
thumb: "", | |
video_source: "" | |
} | |
}, | |
idAttribute: "clipid", | |
getFormattedTime: function(g) { | |
var e; | |
var d; | |
var f; | |
var h; | |
g = g ? String(g) : "0"; | |
if (g.indexOf(":") > -1) { | |
e = g.split(":") | |
} else { | |
return g | |
} | |
if (e.length === 2) { | |
d = 0; | |
f = parseInt(e[0]) || 0; | |
h = parseInt(e[1]) || 0 | |
} else { | |
d = parseInt(e[0]) || 0; | |
f = parseInt(e[1]) || 0; | |
h = parseInt(e[2]) || 0 | |
} | |
if (d && d !== 0) { | |
d = d * 3600 | |
} | |
if (f && f !== 0) { | |
f = f * 60 | |
} | |
h = Math.round(d + f + h); | |
return h | |
}, | |
getMimeType: function(d) { | |
var f = (/[.]/.exec(d)) ? /[^.]+$/.exec(d) : []; | |
var e; | |
switch (f[0]) { | |
case "mp4": | |
case "mov": | |
e = "video/mp4"; | |
break; | |
case "mpeg": | |
e = "video/mpeg"; | |
break; | |
case "mp4a": | |
e = "audio/mp4"; | |
break; | |
case "flv": | |
e = "video/x-flv"; | |
break; | |
case "m3u8": | |
e = "application/x-mpegURL"; | |
break; | |
case "ts": | |
e = "video/MP2T"; | |
break; | |
case "3gp": | |
e = "video/3gpp"; | |
break; | |
case "avi": | |
e = "video/x-msvideo"; | |
break; | |
case "wmv": | |
e = "video/x-ms-wmv"; | |
break; | |
default: | |
e = ""; | |
break | |
} | |
return e | |
}, | |
parse: function(f, g) { | |
var j = f; | |
var h = 9; | |
j.clipid = j.source_guid; | |
if (j.variants && j.variants.legacy) { | |
j.video_source = c.trim(j.variants.legacy) | |
} else { | |
j.video_source = j.mezzanine_url | |
} | |
if (!j.video_source && j.variants && j.variants.hds) { | |
j.video_source = j.variants.hds | |
} | |
var i = ("lastmodifieddate"in j) ? j.lastmodifieddate : ""; | |
if (!("lastModDate"in j)) { | |
j.lastModDate = i | |
} | |
if (!j.lastModDate) { | |
console.log("WARNING: Clip does not have last lastModDate") | |
} | |
if (!("mimeType"in j)) { | |
j.mimeType = this.getMimeType(j.video_source) | |
} | |
j.duration = ("duration"in j) ? this.getFormattedTime(j.duration) : ""; | |
var d = null; | |
if (j.variants) { | |
j.mediaURL = j.variants[h] | |
} | |
var e = j; | |
return e | |
}, | |
setSelected: function(d) { | |
d = !!d; | |
if (d == this.selected) { | |
return | |
} | |
this.selected = d; | |
this.trigger("selected", this, d) | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Models.Wundermap = Backbone.Model.extend({ | |
defaults: { | |
currentLatLng: {}, | |
country: "", | |
enticement: null, | |
lat: 0, | |
lon: 0, | |
layers: [], | |
hasRadar: false, | |
gMapType: "", | |
gMapUnits: "", | |
zoom: 7, | |
mapTypeId: "", | |
mapTypeControl: false, | |
maxZoom: 16, | |
minZoom: 7 | |
}, | |
initialize: function(c) { | |
this.set("lat", c.lat); | |
this.set("lon", c.lon); | |
this.set("country", c.country); | |
this.set("gMapType", c.gMapType); | |
this.set("gMapUnits", c.gMapUnits); | |
this.set("mapTypeControl", false); | |
var b = { | |
zoom: this.get("zoom"), | |
minZoom: this.get("minZoom"), | |
maxZoom: this.get("maxZoom"), | |
mapTypeControl: false | |
}; | |
a.extend(b, c); | |
this.set("mapOptions", b) | |
}, | |
checkCountryHasRadar: function(c) { | |
var f = this.toTitleCase(c); | |
var b = ["Ireland", "United Kingdom", "France", "Spain", "Portugal", "Belgium", "Netherlands", "Germany", "Switzerland", "Italy", "Austria", "Czech Republic", "Poland", "Denmark"]; | |
var d = ["Us", "Canada", "Australia"]; | |
var e = d.concat(b); | |
return ( a.inArray(f, e) != -1) | |
}, | |
toTitleCase: function(b) { | |
return b.replace(/\w\S*/g, function(c) { | |
return c.charAt(0).toUpperCase() + c.substr(1).toLowerCase() | |
}) | |
} | |
}) | |
})(jQuery); | |
(function(c) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
var b = wui.bootstrapped.prefs; | |
wui.Models.AlertsList = Backbone.NestedModel.extend({ | |
events: {}, | |
defaults: function() { | |
return {} | |
}, | |
fetch: function(d) { | |
var e = this; | |
return Backbone.Model.prototype.fetch.apply(this, d) | |
}, | |
parse: function(k) { | |
var o = {}; | |
var u = []; | |
var r = []; | |
var p = false; | |
var t = false; | |
if (k && k.alerts) { | |
var q = k.alerts; | |
var m = wui.bootstrapped.citypage.city; | |
var e = wui.bootstrapped.citypage.state; | |
var g = wui.bootstrapped.citypage.country; | |
var f = wui.bootstrapped.citypage.zip; | |
if (q.length && m && e) { | |
var d = m + ", " + e; | |
if (f === "00000") { | |
d = m + ", " + g | |
} | |
for (var n = 0; n < q.length; n++) { | |
var s = q[n].city; | |
var l = s.cityname; | |
if (s.zip === "00000") { | |
l += ", " + s.country | |
} | |
if (s.altemail.alerts.periods.email === "1") { | |
u.push(l); | |
if (d === l) { | |
p = true | |
} | |
} | |
var j = false; | |
for (var h in s.altemail.alerts) { | |
if (h !== "periods" && s.altemail.alerts.hasOwnProperty(h)) { | |
if (s.altemail.alerts[h].email === "1") { | |
if (!j) { | |
r.push(l); | |
j = true | |
} | |
if (d === s.cityname) { | |
t = true | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
return { | |
forecast: { | |
activeCity: p, | |
cities: u | |
}, | |
severe: { | |
activeCity: t, | |
cities: r | |
} | |
} | |
}, | |
initialize: function() { | |
var d = this; | |
this.fetch().done(function(e) { | |
d.set("success", true) | |
}) | |
}, | |
url: function(e) { | |
var d = "/weather-alerts/list-cities"; | |
return d | |
} | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Collections.Weather = Backbone.Collection.extend({ | |
model: wui.Models.Weather, | |
getStationIds: function() { | |
var c = this.pluck("current_observation.station.id"); | |
c = _.uniq(c); | |
return c | |
}, | |
initialize: function() { | |
this._rapidfire = { | |
interval: 1000 * 60 * 15, | |
started: false, | |
timer: null | |
}; | |
if (wui.bootstrapped && wui.bootstrapped.prefs) { | |
if (_.has(wui.bootstrapped.prefs, "rapidfire")) { | |
this._rapidfire.interval = parseInt(wui.bootstrapped.prefs.rapidfire, 0) * 1000 | |
} | |
} | |
}, | |
parseRapidfire: function(c, d) { | |
var e = c.stations; | |
this.each(function(h) { | |
var g = h.getStationId(); | |
var f = e[g]; | |
h.mergeRapidfire(f) | |
}) | |
}, | |
rapidfire: function(d) { | |
if (this.size() > 0) { | |
var e = b.extend(true, {}, this._rapidfire, d); | |
var c = this.urlRapidfire(e); | |
var f = b.ajax({ | |
context: this, | |
dataType: "jsonp", | |
url: c, | |
success: function(g) { | |
this.parseRapidfire(g); | |
if (this._rapidfire.started) { | |
this.rapidfireDelay() | |
} | |
} | |
}); | |
return f | |
} else { | |
if (this._rapidfire.started) { | |
this.rapidfireDelay() | |
} | |
return false | |
} | |
}, | |
rapidfireDelay: function() { | |
if (this._rapidfire.interval) { | |
var c = _.bind(this.rapidfire, this); | |
this._rapidfire.timer = setTimeout(c, this._rapidfire.interval) | |
} | |
}, | |
rapidfireSetOptions: function(c) { | |
this._rapidfire = b.extend(true, this._rapidfire, c) | |
}, | |
rapidfireStart: function(c) { | |
this.rapidfireStop(); | |
this.rapidfireSetOptions(c); | |
this._rapidfire.started = true; | |
this.rapidfire() | |
}, | |
rapidfireStop: function() { | |
this._rapidfire.started = false; | |
if (this._rapidfire.timer) { | |
clearTimeout(this._rapidfire.timer) | |
} | |
this._rapidfire.timer = null | |
}, | |
urlRapidfire: function(d) { | |
d = b.extend(true, { | |
format: "json", | |
maxage: 10, | |
stations: null, | |
units: "english", | |
v: "2.0" | |
}, d); | |
if (!d.stations) { | |
d.stations = this.getStationIds() | |
} | |
var c = "//stationdata.wunderground.com/cgi-bin/stationlookup?"; | |
c += b.param({ | |
format: d.format, | |
maxage: d.maxage, | |
station: d.stations.join(","), | |
units: d.units, | |
v: d.v | |
}); | |
return c | |
} | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Collections.Location = Backbone.Collection.extend({ | |
model: wui.Models.Location, | |
initialize: function() {}, | |
getZMWs: function() { | |
var c = this.pluck("zmw"); | |
c = _.uniq(c); | |
return c | |
}, | |
hasZMW: function(d) { | |
var c = this.findWhere({ | |
zmw: d | |
}); | |
return !!c | |
}, | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Collections.Favorites = wui.Collections.Location.extend({ | |
initialize: function() { | |
var c = this; | |
this.listenTo(this, "sort", this.reorderFavorites) | |
}, | |
addFavorite: function(e, d) { | |
var c = this; | |
var f = this._requestAdd(e); | |
f.done(function(i, k) { | |
var j = "Error"; | |
var g = i.RESULTS || i; | |
if (g.indexOf(j.toLowerCase()) >= 0) { | |
c._requestError(g) | |
} else { | |
if (i.location) { | |
c.add(i.location) | |
} else { | |
var h = "Error: unknown favorite location"; | |
c._requestError(h) | |
} | |
} | |
}); | |
return f | |
}, | |
delFavorite: function(e, d) { | |
var c = this; | |
var f = this._requestDel(e); | |
f.done(function(i, k) { | |
var j = "Error"; | |
var h = i.RESULTS || i; | |
if (h.indexOf(j.toLowerCase()) >= 0) { | |
c._requestError(h) | |
} else { | |
var g = c.get(e); | |
if (g) { | |
c.remove(g) | |
} | |
if (!c.length) { | |
b("#favorites-edit-list").html("<h3>You do not have any favorite cities loaded.</h3><p>If you had previously set your favorite cities, this may be due to your cookie settings being deleted, that you are using a different computer or are not signed in.</p>"); | |
b("#favorites-edit-list").removeClass() | |
} | |
} | |
}); | |
return f | |
}, | |
favoritesCallback: function(h) { | |
var k = h.current_observation; | |
var p = h.response["location"]; | |
if (k == undefined) { | |
return | |
} | |
var n = k.temperature | |
, f = p.canonical | |
, c = k.forecast_url | |
, g = k.condition | |
, m = k.station["latitude"] | |
, e = k.station["longitude"] | |
, d = k.icon | |
, o = p.zip + "." + p.magic + "." + p.wmo | |
, j = this.zmwParse(o); | |
var l; | |
if (p.zip == "00000") { | |
l = p.city + ", " + p.country | |
} else { | |
l = p.city + ", " + p.state | |
} | |
var q = h.alerts.length !== 0; | |
var i = q ? h.alerts[0].defcon : 0; | |
this.favoriteObjects[j] = { | |
name: l, | |
type: "favorite", | |
url: f, | |
lat: m, | |
lon: e, | |
zmw: j, | |
has_alerts: q, | |
condition: { | |
temperature: n, | |
icon: d, | |
condition: g, | |
severe: q, | |
defcon: i | |
}, | |
current_observation: k | |
} | |
}, | |
reorderFavorites: function() { | |
var c = this._requestReorder(); | |
return c | |
}, | |
toggleFavorite: function(d) { | |
var c = this.hasZMW(d); | |
if (c) { | |
return this.delFavorite(d) | |
} else { | |
return this.addFavorite(d) | |
} | |
}, | |
_request: function(h, d) { | |
var c = this; | |
h = b.extend({ | |
action: "" | |
}, h); | |
d = b.extend({ | |
dataType: "jsonp", | |
jsonp: "jsonp", | |
type: "get", | |
error: function(j) { | |
var i = "Error: favorites ajax request failed"; | |
c._requestError(i) | |
} | |
}, d); | |
var f = ""; | |
if (document.domain.indexOf(".wunderground.com") < 0 || 1) { | |
f = "https://www.wunderground.com" | |
} | |
var e = f + "/favorites/submit.html"; | |
d.data = h; | |
d.url = e; | |
var g = b.ajax(d); | |
return g | |
}, | |
_requestAdd: function(c) { | |
var d = { | |
action: "addfavorite", | |
conditions: true, | |
place: c | |
}; | |
return this._request(d) | |
}, | |
_requestDel: function(c) { | |
var d = { | |
action: "delfavorite", | |
conditions: true, | |
place: c | |
}; | |
return this._request(d) | |
}, | |
_requestReorder: function() { | |
var e = this.getZMWs(); | |
var c = "," + e.join(","); | |
var f = { | |
action: "reorderfavorites", | |
order: c | |
}; | |
var d = { | |
dataType: "html", | |
type: "post" | |
}; | |
return this._request(f, d) | |
}, | |
_requestError: function(c) { | |
wui.log(c) | |
}, | |
checkSelectedPWS: function(h) { | |
h = h.replace(/\./g, ""); | |
var e = wui.bootstrapped.prefs.raw_string; | |
var d = e.indexOf(h); | |
var f = ""; | |
if (d != -1) { | |
var g = e.indexOf(":", d); | |
var c = e.indexOf("|", g); | |
var f = e.substring(g + 1, c) | |
} | |
return f | |
}, | |
loadAsync: function(h) { | |
var e = decodeURIComponent(h); | |
var d = e.split(","); | |
var g = []; | |
var c = []; | |
this.favoriteObjects = {}; | |
this.citylist = h; | |
var f = this; | |
b.each(d, function(r, v) { | |
if (v == "") { | |
return | |
} | |
var p = f.zmwParse(v); | |
var j = p.replace(/\./g, ""); | |
var w = f.checkSelectedPWS(p); | |
if (isNaN(j) || b.inArray(j, c) >= 0) { | |
j = g.length | |
} | |
c.push(j); | |
var x = wui.bootstrapped.prefs; | |
var q = "eb7a37c339cfd624"; | |
var m = x.LangCode; | |
var s = x.Units; | |
var i = "//api-ak-aws"; | |
var n = i + ".wunderground.com/api/" + q + "/conditions/alerts/v:2.0"; | |
if (m) { | |
n += "/lang:" + m | |
} | |
if (s) { | |
n += "/units:" + s | |
} | |
var o = "/q/zmw:"; | |
var u = ".json?ttl=300"; | |
var k = n + o + p + u; | |
var l = new Date().getTime() / 1000; | |
var t = 300; | |
f.favoriteObjects[p] = {}; | |
g.push(b.ajax({ | |
url: k, | |
dataType: "jsonp", | |
timeout: 10000, | |
cache: true, | |
jsonpCallback: "favoritesCallback" + j, | |
success: function(y) { | |
f.favoritesCallback(y) | |
} | |
})) | |
}); | |
b.when.apply(b, g).then(function() { | |
if (b.isEmptyObject(f.favoriteObjects)) { | |
return | |
} | |
var i = []; | |
for (var j in f.favoriteObjects) { | |
i.push(f.favoriteObjects[j]) | |
} | |
f.add(i); | |
wui.favorites.stars.initialize() | |
}) | |
}, | |
zmwParse: function(h) { | |
var c = h.split("."); | |
var e, g, d; | |
if (c.length == 3) { | |
e = c[0]; | |
g = c[1]; | |
d = c[2] | |
} else { | |
if (c[0] == "00000") { | |
e = "00000"; | |
g = "1"; | |
d = c[1] | |
} else { | |
e = c[0]; | |
g = c[1]; | |
d = "99999" | |
} | |
} | |
var f = e + "." + g + "." + d; | |
return f | |
} | |
}) | |
})(jQuery); | |
(function(e) { | |
if (!window.Backbone) { | |
return | |
} | |
var c = wui.backbone.utils; | |
var b = "_distance"; | |
var a = "_latLng"; | |
var g = "_title"; | |
var f = 35; | |
var d = 10; | |
wui.Collections.Station = Backbone.Collection.extend({ | |
model: wui.Models.Station, | |
initialize: function(i, h) { | |
this.options = { | |
bounds: null, | |
minlat: null, | |
minlon: null, | |
maxlat: null, | |
maxlon: null, | |
maxstations: f, | |
minstations: d, | |
center: null, | |
centerLat: null, | |
centerLon: null, | |
requiredVariables: [], | |
units: "english" | |
}; | |
this.setOptions(h); | |
this.numFetches = 0; | |
this.listenTo(this, "sync", this.incrementFetches) | |
}, | |
checkCenter: function() { | |
var h = this.options; | |
if (h.center === null) { | |
if (h.centerLat !== null && h.centerLon !== null) { | |
h.center = { | |
lat: wui.bootstrapped.citypage.lat, | |
lon: wui.bootstrapped.citypage.lon | |
} | |
} | |
} | |
}, | |
comparator: b, | |
defaultStations: [], | |
fetchDefaultStations: function(i) { | |
i = e.extend({ | |
distance: 19.53125, | |
maxstations: f, | |
minstations: d, | |
initialStations: false, | |
selectedStation: null | |
}, i); | |
this.checkCenter(); | |
var h = this.options.center; | |
var j = i.distance * 1000; | |
this.setOptions({ | |
isFetchDefaultStations: true, | |
maxstations: f | |
}); | |
this.fetch({ | |
initialStations: i.initialStations, | |
fetchDefaultStations: true, | |
selectedStation: i.selectedStation | |
}) | |
}, | |
getDefaultStations: function(h) { | |
h = h || {}; | |
var j = this.defaultStations; | |
var i = h.bounds; | |
if (i) { | |
j = _.filter(j, function(k) { | |
var l = k[a]; | |
return i.contains(l) | |
}) | |
} | |
return j | |
}, | |
getTitle: function(h) { | |
var i = []; | |
if (h.neighborhood) { | |
i.push(h.neighborhood) | |
} | |
if (h.city) { | |
i.push(h.city) | |
} else { | |
if (h.adm1) { | |
i.push(h.adm1) | |
} | |
} | |
if (h.state) { | |
i.push(h.state) | |
} else { | |
if (h.adm2 && h.adm2 != h.adm1) { | |
i.push(h.adm2) | |
} | |
} | |
var j = i.join(", "); | |
return j | |
}, | |
incrementFetches: function() { | |
this.numFetches++ | |
}, | |
parse: function(i, j) { | |
var h = this.options.center; | |
if (h) {} | |
var m = i.stations; | |
var k = this.options.requiredVariables; | |
if (k && k.length) { | |
m = _.reject(m, function(n) { | |
var o = _.some(k, function(p) { | |
if (_.has(n, p)) { | |
return n[p] === null | |
} else { | |
return true | |
} | |
}); | |
return o | |
}) | |
} | |
_.each(m, function(n) { | |
if (h) { | |
var o = parseFloat(n.latitude); | |
var p = parseFloat(n.longitude) | |
} | |
n[g] = this.getTitle(n) | |
}, this); | |
var l = j.selectedStation; | |
if (l) {} | |
this.setOptions({ | |
zoom: this.options.zoom | |
}); | |
this.defaultStations = _.sortBy(m, b); | |
return m | |
}, | |
setOptions: function(h) { | |
e.extend(this.options, h) | |
}, | |
sync: function(k, j, i) { | |
if (k == "read") { | |
i.dataType = "jsonp" | |
} | |
var h = e.extend(this.options, i, i.data, { | |
data: null | |
}); | |
return Backbone.sync.call(this, k, j, h) | |
}, | |
url: function() { | |
var k = this.options; | |
var m = k.maxstations; | |
if (!m) { | |
m = "" | |
} | |
var o = k.minstations; | |
if (!o) { | |
o = "" | |
} | |
var i = k.minlat; | |
var j = k.minlon; | |
var l = k.centerLat; | |
var n = k.centerLon; | |
var h = ""; | |
if (true) { | |
h = "//stationdata.wunderground.com/cgi-bin/stationdata?" + e.param({ | |
centerLat: l, | |
centerLon: n, | |
format: "json", | |
maxage: 1800, | |
maxstations: f, | |
minstations: o, | |
height: 400, | |
width: 400, | |
iconsize: 2, | |
type: "ICAO,PWS", | |
units: k.units, | |
v: "2.0" | |
}) | |
} else { | |
this.options.maxstations = 300; | |
h = "//stationdata.wunderground.com/cgi-bin/stationdata?" + e.param({ | |
minlat: i, | |
minlon: j, | |
maxlat: maxlat, | |
maxlon: maxlon, | |
format: "json", | |
maxage: 1800, | |
maxstations: 300, | |
minstations: o, | |
height: 400, | |
width: 400, | |
iconsize: 2, | |
type: "ICAO,PWS", | |
units: k.units, | |
v: "2.0" | |
}) | |
} | |
return h | |
} | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Collections.Video = Backbone.Collection.extend({ | |
model: wui.Models.Video, | |
initialize: function(d, c) { | |
this.options = { | |
id: "", | |
selectedId: null, | |
selectedIndex: null | |
}; | |
this.setOptions(c); | |
this.selected = null; | |
if (this.length) { | |
this.setInitialSelected() | |
} else { | |
this.once("sync", this.setInitialSelected, this) | |
} | |
}, | |
parse: function(e, f) { | |
var h = matchMedia(Foundation.media_queries.small).matches; | |
var k = []; | |
if (e && e.body && e.body.length) { | |
var j = b.isArray(e.body[0].doc) ? e.body[0].doc : [e.body[0].doc]; | |
if (typeof (j[0]) == "undefined") { | |
j = b.isArray(e.body) ? e.body : [e.body] | |
} | |
if (typeof (j[0].id) != "undefined") { | |
for (var g = 0, c = j.length; g < c; g++) { | |
var d = j[g].flags; | |
if ((d["Big Web"] && !h) || (d["Little Web"] && h)) { | |
k.push(j[g]) | |
} | |
} | |
} | |
} | |
return k | |
}, | |
select: function(c) { | |
c = c || null; | |
var e = (c) ? true : false; | |
if (c) { | |
if (c === this.selected) { | |
return | |
} | |
this.select(null); | |
if (c.setSelected) { | |
c.setSelected(e) | |
} | |
} else { | |
var d = this.selected; | |
if (!d) { | |
return | |
} | |
if (d.setSelected) { | |
d.setSelected(e) | |
} | |
} | |
this.selected = c | |
}, | |
setInitialSelected: function() { | |
var e = null; | |
var d = this.options.selectedId; | |
var c = this.options.selectedIndex; | |
if (!e && d) { | |
e = this.get(d) | |
} | |
if (!e && _.isNumber(c) && c >= 0) { | |
e = this.at(c) | |
} | |
if (e) { | |
this.select(e) | |
} | |
}, | |
setOptions: function(c) { | |
b.extend(this.options, c) | |
}, | |
sync: function(e, d, c) { | |
if (e == "read") { | |
c.dataType = "jsonp"; | |
c.jsonp = "jsonp" | |
} | |
return Backbone.sync.call(this, e, d, c) | |
}, | |
url: function() { | |
var d = this.options; | |
var c = ""; | |
var e = ""; | |
if (this.options.type == "playlist") { | |
c = "//dsx.weather.com/cms/orderedlist/video/" + this.options.collid | |
} else { | |
e = d.isSingleVideo ? "/" + d.collid + "?" : "?q=type:$in(%27video%27);pcollid:$in(%27" + (d.collid || "wunderground/news") + "%27)&sort=-publishdate&pg=0,50&"; | |
c = "//dsx.weather.com/cms/(assets)" + e + "api=7bb1c920-7027-4289-9c96-ae5e263980bc" | |
} | |
return c | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Views.Favorites = Backbone.View.extend({ | |
events: { | |
"click .favorites-list-toggle": "onClickList" | |
}, | |
initialize: function(b) { | |
this.options = b || {}; | |
this.models = this.options.models || {}; | |
this.collections = this.options.collections || {}; | |
this.listenTo(this.model, "change:favorites.list.enabled", this.onListEnabledChange); | |
this.listenTo(this.model, "change:favorites.list.show", this.onListShowChange); | |
this.createViews(); | |
this.render(); | |
this.checkListToggle() | |
}, | |
checkListToggle: function() { | |
var b = this.model.get("favorites.list.enabled"); | |
this.$el.find(".favorites-list-toggle").toggle(b) | |
}, | |
createViews: function() { | |
this.views = {}; | |
this.views.favoritesBarView = new wui.Views.FavoritesBar({ | |
model: this.model, | |
collections: { | |
favorites: this.collections.favorites, | |
recents: this.collections.recents, | |
popular: this.collections.popular, | |
}, | |
el: this.$el.find(".favorites-bar")[0] | |
}) | |
}, | |
createListView: function() { | |
if (!this.views.favoritesListView) { | |
this.views.favoritesListView = new wui.Views.FavoritesList({ | |
model: this.model, | |
collections: { | |
favorites: this.collections.favorites, | |
recents: this.collections.recents, | |
popular: this.collections.popular, | |
}, | |
el: this.$el.find(".favorites-list")[0], | |
sortable: true, | |
render: true | |
}) | |
} | |
}, | |
onClickList: function(c) { | |
var b = this.model.get("favorites.list.show"); | |
this.model.set("favorites.list.show", !b) | |
}, | |
onListEnabledChange: function(c, b) { | |
this.checkListToggle() | |
}, | |
onListShowChange: function(c, b) { | |
var d = this.model.get("classNames"); | |
this.$el.find(".favorites-list-toggle").toggleClass(d.selected, b); | |
this.createListView() | |
}, | |
render: function() { | |
_.each(this.views, function(b) { | |
b.render() | |
}); | |
return this | |
} | |
}); | |
wui.Views.FavoritesBar = Backbone.View.extend({ | |
initialize: function(b) { | |
this.options = b || {}; | |
this.models = this.options.models || {}; | |
this.collections = this.options.collections || {}; | |
this.template = _.template(a("script#favorites-bar-template").html()); | |
this.templateCity = _.template(a("script#favorites-city-template").html()); | |
if (a("script#favorites-alt-template").length) { | |
this.altTemplate = _.template(a("script#favorites-alt-template").html()) | |
} | |
this.listenTo(this.model, "change:favorites.bar.show", this.onShowChange); | |
this.listenTo(this.collections.favorites, "add", this.render); | |
this.listenTo(this.collections.favorites, "remove", this.render); | |
this.listenTo(this.collections.favorites, "sort", this.render); | |
this.listenTo(this.collections.recents, "add", this.render); | |
this.listenTo(this.collections.recents, "remove", this.render); | |
this.listenTo(this.collections.popular, "add", this.render); | |
this.listenTo(this.collections.popular, "remove", this.render); | |
var d = _.bind(this.onResize, this); | |
var c = _.debounce(d, 500); | |
a(window).resize(c); | |
if (this.options.render) { | |
this.render() | |
} | |
}, | |
checkListEnabled: function() { | |
var b = this.$el.width(); | |
var d = this.$el.children("ul").width(); | |
var c = (d > b); | |
this.model.set("favorites.list.enabled", c) | |
}, | |
onResize: function(b) { | |
this.checkListEnabled() | |
}, | |
onShowChange: function(c, b) { | |
this.toggle(b) | |
}, | |
render: function() { | |
var b = []; | |
var e = []; | |
var g = []; | |
if (this.collections.favorites) { | |
b = this.collections.favorites.toJSON() | |
} | |
if (this.collections.recents) { | |
e = this.collections.recents.toJSON() | |
} | |
if (this.collections.popular) { | |
g = this.collections.popular.toJSON() | |
} | |
var d = { | |
favorites: b, | |
favCityList: this.collections.favorites.citylist, | |
recents: e, | |
popular: g, | |
templateCity: this.altTemplate ? this.altTemplate : this.templateCity | |
}; | |
var f = this.template(d); | |
this.$el.html(f); | |
this.checkListEnabled(); | |
var c = (b.length || e.length || g.length); | |
this.model.set("favorites.bar.show", c); | |
return this | |
}, | |
toggle: function(b) { | |
this.$el.toggle(!!b) | |
} | |
}); | |
wui.Views.FavoritesList = Backbone.View.extend({ | |
events: { | |
"click .city-star": "onClickStar", | |
"click .city-home": "onClickHome" | |
}, | |
initialize: function(d) { | |
this.options = d || {}; | |
this.models = this.options.models || {}; | |
this.collections = this.options.collections || {}; | |
this.template = _.template(a("script#favorites-list-template").html()); | |
this.templateCity = _.template(a("script#favorites-city-template").html()); | |
this.listenTo(this.model, "change:favorites.list.enabled", this.onListEnabledChange); | |
this.listenTo(this.model, "change:favorites.list.show", this.onShowChange); | |
var b = this.collections.favorites; | |
if (b) { | |
this.listenTo(b, "add", this.onFavoritesChange); | |
this.listenTo(b, "remove", this.onFavoritesChange) | |
} | |
var c = this.collections.recents; | |
if (c) { | |
this.listenTo(c, "add", this.render); | |
this.listenTo(c, "remove", this.render) | |
} | |
var e = this.collections.popular; | |
if (e) { | |
this.listenTo(e, "add", this.render); | |
this.listenTo(e, "remove", this.render) | |
} | |
this._isSortable = false; | |
if (this.options.render) { | |
this.render() | |
} | |
}, | |
createSortComparator: function(b) { | |
var c = function(e) { | |
var f = e.get("zmw"); | |
var d = _.indexOf(b, f); | |
if (d < 0) { | |
d = b.length | |
} | |
return d | |
}; | |
return c | |
}, | |
onClickStar: function(e) { | |
e.preventDefault(); | |
var b = a(e.target); | |
var c = this.el; | |
var f = b.closest("li", c); | |
var d = f.attr("data-zmw"); | |
if (!d) { | |
return | |
} | |
this.toggleFav(d) | |
}, | |
onClickHome: function(f) { | |
f.preventDefault(); | |
var b = a(f.target); | |
var d = this.el; | |
var g = b.closest("li", d); | |
var e = g.attr("data-zmw"); | |
var c = g.attr("data-cityName"); | |
if (!e) { | |
return | |
} | |
if (!c) { | |
c = "" | |
} | |
this.toggleHome(e, b, c) | |
}, | |
onFavoritesChange: function() { | |
this.render(); | |
this.$el.sortable("refresh") | |
}, | |
onListEnabledChange: function(c, b) { | |
var d = this.model.get("classNames"); | |
if (!b) { | |
this.model.set("favorites.list.show", false); | |
this.$el.removeClass(d.open); | |
this.$el.hide() | |
} | |
if (b) { | |
this.$el.show() | |
} | |
}, | |
onShowChange: function(c, b) { | |
this.toggle(b) | |
}, | |
onSortUpdate: function(e, f) { | |
var d = this.$el.sortable("toArray", { | |
attribute: "data-zmw" | |
}); | |
var b = this.collections.favorites; | |
var c = b.comparator; | |
b.comparator = this.createSortComparator(d); | |
b.sort(); | |
b.comparator = c | |
}, | |
render: function() { | |
var b = []; | |
var d = []; | |
var f = []; | |
if (this.collections.favorites) { | |
b = this.collections.favorites.toJSON() | |
} | |
if (this.collections.recents) { | |
d = this.collections.recents.toJSON() | |
} | |
if (this.collections.popular) { | |
f = this.collections.popular.toJSON() | |
} | |
var c = { | |
favorites: b, | |
recents: d, | |
popular: f, | |
templateCity: this.templateCity | |
}; | |
var e = this.template(c); | |
this.$el.html(e); | |
if (!this._isSortable && this.options.sortable) { | |
this.setupSortable(); | |
this._isSortable = true | |
} | |
return this | |
}, | |
setupSortable: function() { | |
var b = { | |
axis: "y", | |
cancel: ".city-star", | |
containment: "parent", | |
distance: 2, | |
items: "> ul.list-favorites > li.is-fav", | |
tolerance: "pointer", | |
update: a.proxy(this.onSortUpdate, this) | |
}; | |
this.$el.sortable(b) | |
}, | |
toggle: function(b) {}, | |
toggleFav: function(b) { | |
this.collections.favorites.toggleFavorite(b) | |
}, | |
toggleHome: function(d, c, b) { | |
if (c.hasClass("active") == false) { | |
a(".city-home.active").removeClass("active") | |
} | |
wui.favorites.home.toggle(d, c, "active", "", b) | |
} | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Views.Location = Backbone.View.extend({ | |
events: { | |
"click #flagstationbutton": "flagStation" | |
}, | |
initialize: function(c) { | |
var d = this; | |
this.options = c || {}; | |
this.models = this.options.models || {}; | |
this.template = _.template(b("script#station-label-template").html()); | |
this.listenTo(this.models.weather, "change:current_observation", this.render); | |
if (this.options.render && this.models.weather.attributes.response) { | |
this.render() | |
} | |
b("#report_box").on("closed.fndtn.dropdown", function() { | |
d.resetReportStation() | |
}) | |
}, | |
render: function() { | |
var d = ""; | |
var c = { | |
labels: this.models.weather.attributes.labels, | |
weather: this.models.weather.attributes | |
}; | |
d = this.template(c); | |
this.$el.find("#station-label").html(d); | |
if (this.models.weather.get("current_observation").source === "PWS") { | |
this.$el.find("#report-link").removeClass("hide") | |
} else { | |
this.$el.find("#report-link").addClass("hide") | |
} | |
return this | |
}, | |
resetReportStation: function() { | |
b("#report-active").removeClass("hide"); | |
b("#report-inactive").addClass("hide"); | |
this.$el.find(".report-checkbox").prop("checked", false); | |
b("#report-error").text("").addClass("hide") | |
}, | |
flagStation: function(h) { | |
var j = b(h.target); | |
var d = this.models.weather; | |
var c = d.get("current_observation"); | |
var f = d.get("response"); | |
var k = c.station; | |
var l = f.location; | |
var i = f.units; | |
var g = { | |
type: "wxstation", | |
stationid: k.id, | |
zip: l.zip, | |
magic: l.magic, | |
wmo: l.wmo, | |
badtemp: b("#badtemp").is(":checked"), | |
badpress: b("#badpress").is(":checked"), | |
badwind: b("#badwind").is(":checked"), | |
badfct: b("#badfct").is(":checked"), | |
badoff: b("#badoff").is(":checked") | |
}; | |
g.temp_e = c.temperature; | |
g.press = c.pressure; | |
if (i === "metric") { | |
g.temp_e = g.temp_e * 1.8 + 32; | |
g.press /= 33.86 | |
} | |
b("#report-error").addClass("hide"); | |
if (!this.$el.find(".report-checkbox").is(":checked")) { | |
b("#report-error").text("Please select a reason below.").removeClass("hide") | |
} else { | |
j.prop("disabled", true).addClass("disabled"); | |
b.ajax({ | |
url: "/wuflag/flag.html", | |
data: g | |
}).complete(function(e, m) { | |
j.prop("disabled", false).removeClass("disabled") | |
}).done(function(e, m) { | |
b("#report-inactive").removeClass("hide"); | |
b("#report-active").addClass("hide") | |
}).fail(function() { | |
b("#report-error").text("Our reporting system is currently down. Please try again later.").removeClass("hide") | |
}) | |
} | |
return false | |
} | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Views.Current = Backbone.View.extend({ | |
events: { | |
"click .cc3-toggle-hide": "onClickHideCC3", | |
"click .cc3-toggle-show": "onClickShowCC3" | |
}, | |
initialize: function(c) { | |
this.options = c || {}; | |
this.models = this.options.models || {}; | |
var d = b("script#today_summary_template"); | |
if (d[0]) { | |
this.templateTodaySummary = _.template(d.html()) | |
} | |
this.listenTo(this.models.weather, "change:current_observation", this.updateVariables); | |
this.listenTo(this.models.weather, "change:forecast", this.updateWeatherQuickie); | |
this.listenTo(this.models.weather, "change:forecast", this.updateTodaySummary); | |
this.updateWeatherQuickie(); | |
this.updateTodaySummary() | |
}, | |
getPreviousValue: function(d) { | |
var f = null; | |
var c = this.models.weather.previousAttributes(); | |
var e = c.current_observation; | |
if (e) { | |
f = e[d] | |
} | |
return f | |
}, | |
getVariableElement: function(c, d) { | |
var f = this.model.get("classNames"); | |
var e = this.$el.find("." + f.wxdata + "[data-variable]"); | |
if (c) { | |
e = e.filter('[data-variable="' + c + '"]') | |
} | |
if (d) { | |
e = e.filter('[data-station="' + d + '"]') | |
} | |
return e | |
}, | |
onClickHideCC3: function(c) { | |
c.preventDefault(); | |
this.toggleCC3(false) | |
}, | |
onClickShowCC3: function(c) { | |
c.preventDefault(); | |
this.toggleCC3(true) | |
}, | |
toggleCC3: function(c) { | |
var d = this.model.get("classNames"); | |
this.$el.toggleClass(d.open, !!c) | |
}, | |
updateMetadata: function() { | |
var d = this.models.weather.getStationId(); | |
var c = ["station.elevation", "station.latitude", "station.longitude"]; | |
var e = this.models.weather.attributes.labels; | |
_.each(c, function(f) { | |
var h = this.models.weather.get("current_observation." + f); | |
var i = this.getVariableElement(f, d); | |
var g = {}; | |
if (f == "station.latitude") { | |
g.unit = "°" + (h < 0 ? e.south.abbrev : e.north.abbrev); | |
h = Math.abs(h).toFixed(2) | |
} | |
if (f == "station.longitude") { | |
g.unit = "°" + (h < 0 ? e.west.abbrev : e.east.abbrev); | |
h = Math.abs(h).toFixed(2) | |
} | |
a.updateVariable(i, f, h, g) | |
}, this) | |
}, | |
updateStation: function(c, d) { | |
var e = this.getVariableElement(null, c).attr("data-station", d); | |
this.updateMetadata() | |
}, | |
updateTodaySummary: function() { | |
if (!this.templateTodaySummary) { | |
return | |
} | |
var f = this.models.weather.get("forecast.days[0].summary.date"); | |
var k = new Date(f.epoch * 1000); | |
var j = wui.date.increment(k, f.tz_offset_hours, "hour"); | |
var c = wui.date.increment(j, -1, "day"); | |
var g = this.models.weather.get("response"); | |
var i = ""; | |
var e = { | |
labels: this.models.weather.attributes.labels, | |
weather: this.models.weather.attributes, | |
yesterday_date: c | |
}; | |
var h = wui.bootstrapped && wui.bootstrapped.precip ? wui.bootstrapped.precip.baseUrl : ""; | |
if (h && g.location) { | |
h += a.generateCityQuery({ | |
zip: g.location.zip, | |
magic: g.location.magic, | |
wmo: g.location.wmo, | |
country: g.location.country_iso3166 | |
}) | |
} | |
e.cityUrl = h; | |
i = this.templateTodaySummary(e); | |
this.$el.find("#todaySummary").html(i) | |
}, | |
updateVariableEffect: function(f, c, e) { | |
var d = f.attr("data-update-effect"); | |
if (d == "wind-compass") { | |
this.updateWindCompass(f, e) | |
} | |
if (c == "icon_url") { | |
this.updateIconImg(f, e) | |
} | |
if (c == "wind_dir") { | |
this.updateWindDir(f, e) | |
} | |
}, | |
initVariables: function() { | |
var g = this.models.weather; | |
var d = g.get("current_observation.station.id"); | |
var f = false; | |
var e = g.attributes.current_observation; | |
var c = this; | |
_.each(e, function(i, h) { | |
var j = c.getVariableElement(h, d); | |
var k = c.model.get("classNames"); | |
var j = c.$el.find("." + k.wxdata + "[data-variable]"); | |
j = j.filter('[data-variable="' + h + '"]'); | |
j.data("station", d); | |
if (j[0]) { | |
a.updateVariable(j, h, i, {}); | |
c.updateVariableEffect(j, h, i) | |
} | |
}); | |
this.updateStation(null, d) | |
}, | |
updateVariables: function(j, i) { | |
var c = j.previousAttributes(); | |
var g = c.current_observation; | |
var d = null; | |
var f = j.get("current_observation.station.id"); | |
var h = false; | |
if (g) { | |
d = g.station.id; | |
h = (f !== d) | |
} | |
if (h) { | |
this.updateStation(d, f) | |
} | |
var e = this; | |
_.each(i, function(m, l) { | |
var k = e.getPreviousValue(l); | |
if (m !== k) { | |
var n = e.getVariableElement(l, f); | |
if (n[0]) { | |
a.updateVariable(n, l, m, {}); | |
e.updateVariableEffect(n, l, m) | |
} | |
} | |
}) | |
}, | |
updateIconImg: function(d, c) { | |
d.attr({ | |
alt: this.models.weather.get("current_observation.condition"), | |
src: c | |
}) | |
}, | |
updateWeatherQuickie: function() { | |
var d = "weather_quickie"; | |
var i = this.models.weather; | |
var c = i.previousAttributes(); | |
var e = null; | |
var f = {}; | |
if (c.forecast) { | |
e = c.forecast.days[0].summary[d] | |
} else { | |
f.duration = 0 | |
} | |
var h = i.get("forecast.days[0].summary[" + d + "]"); | |
if (h !== e) { | |
var g = this.getVariableElement(d); | |
a.updateVariable(g, d, h, f) | |
} | |
}, | |
updateWindCompass: function(d, c) { | |
a.rotate(d, c) | |
}, | |
updateWindDir: function(d, c) { | |
var e = this.model.get("classNames"); | |
var f = this.models.weather.get("current_observation.wind_dir_variable"); | |
d.toggleClass(e.windDirVariable, !!f) | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Views.Forecast = Backbone.View.extend({ | |
events: {}, | |
initialize: function(b) { | |
this.options = b || {}; | |
this.weather = this.options.weather; | |
this.models = this.options.models || {}; | |
this.tabindex = this.options.tabindex || null; | |
if (this.options.render) { | |
this.initializeLater() | |
} | |
}, | |
initializeLater: function() { | |
this.checkThunderstorm(); | |
var b = this.$tabs = this.$el.find(".forecast-tabs"); | |
var d; | |
if (this.tabindex !== null) { | |
d = parseInt(this.tabindex, 10) | |
} else { | |
d = 2; | |
var c = Foundation.media_queries.medium; | |
var e = matchMedia(c).matches; | |
if (e) { | |
d = 0 | |
} | |
} | |
b.show(); | |
b.tabs({ | |
active: d, | |
activate: a.proxy(this.onTabsActivate, this) | |
}); | |
this.createViews(); | |
this.setupMetrics() | |
}, | |
createViews: function() { | |
this.views = {}; | |
var b = this.$tabs.tabs("option", "active"); | |
this.createViewsByTabIndex(b) | |
}, | |
checkThunderstorm: function() { | |
var f = this.weather.attributes.forecast.days; | |
var b = false; | |
for (var d = 0; d < 3; d++) { | |
if ((f[d].summary.condition == "Thunderstorm") || (f[d].summary.condition == "Chance of a Thunderstorm")) { | |
var b = true | |
} | |
} | |
var c = this.$el.find("#forcast-lightning-tab"); | |
if (b && (c.length == 0)) { | |
var e = a("script#forecast-lightning-tab-template"); | |
if (e) { | |
this.$el.find(".ui-tabs-nav").append(e.html()) | |
} | |
} else { | |
if (c.length && !b) { | |
c.remove() | |
} | |
} | |
}, | |
createViewsByTabIndex: function(b) { | |
if (b === 0 && !this.views.plotGroupView) { | |
this.views.plotGroupView = new wui.Views.PlotGroup({ | |
model: this.model, | |
models: { | |
plotGroup: this.models.plotGroup, | |
weather: this.weather | |
}, | |
render: true, | |
el: this.$el.find(".weather-graph").eq(0)[0] | |
}); | |
this.listenTo(this.views.plotGroupView.status, "change:zoomedIn", function(d, c, e) { | |
this.trigger("forecast_graph_zoom", { | |
date: e.d, | |
initiator: e.eventInitiator, | |
zoomedIn: c | |
}) | |
}) | |
} | |
if (b === 1 && !this.views.tableVerticalView) { | |
this.views.tableVerticalView = new wui.Views.TableVertical({ | |
model: this.model, | |
precip: this.models.precip, | |
weather: this.weather, | |
render: true, | |
el: a("#hourly-vertical")[0] | |
}) | |
} | |
if (b === 1 && !this.views.tableHorizontalView) { | |
this.views.tableHorizontalView = new wui.Views.TableHorizontal({ | |
model: this.model, | |
weather: this.weather, | |
render: true, | |
el: a("#hourly-horizontal")[0] | |
}) | |
} | |
if (b === 2 && !this.views.extendedView) { | |
this.views.extendedView = new wui.Views.Extended({ | |
model: this.model, | |
weather: this.weather, | |
render: true, | |
el: a("#extended")[0] | |
}) | |
} | |
if (b === 3 && !this.views.contextView) { | |
this.views.contextView = new wui.Views.Context({ | |
model: this.model, | |
weather: this.weather, | |
render: true, | |
el: a("#context-slideshow")[0] | |
}) | |
} | |
this.$el.addClass("loaded"); | |
this.$el.find(".content").removeClass("hidden-tab"); | |
this.$el.find(".loader-screen").remove() | |
}, | |
onTabsActivate: function(c, d) { | |
if (!this.views) { | |
return | |
} | |
var b = this.$tabs.tabs("option", "active"); | |
this.createViewsByTabIndex(b); | |
if (b !== 3) { | |
wui.storage.setLocal("cityForecastTab", b) | |
} | |
this.trigger("forecast_tabs_activate", { | |
tabIndex: b, | |
jQueryObjects: d | |
}) | |
}, | |
setupMetrics: function() { | |
this.listenTo(this.models.plotGroup, "change:editMode", function(b, c) { | |
if (c) { | |
this.trigger("forecast_variables_menu_open") | |
} else { | |
this.trigger("forecast_variables_menu_close") | |
} | |
}) | |
} | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Views.TableVertical = Backbone.View.extend({ | |
events: { | |
"click .accordion > dd": "fixPosition" | |
}, | |
initialize: function(c) { | |
this.options = c || {}; | |
this.weather = this.options.weather; | |
this.precip = this.options.precip; | |
this.template = _.template(b("script#table-vertical-template").html()); | |
this.listenTo(this.weather, "change:forecast", this.renderReady); | |
this.listenTo(this.precip, "change:statement", this.renderReady); | |
if (this.options.render && this.weather.attributes.forecast && this.precip.attributes.statement) { | |
this.render() | |
} | |
}, | |
renderReady: function() { | |
if (this.weather.get("forecast") && this.precip.get("statement")) { | |
this.render() | |
} | |
}, | |
render: function(g, j) { | |
var d = { | |
labels: this.weather.attributes.labels, | |
weather: this.weather.attributes, | |
precip: this.precip.attributes | |
}; | |
var e = this.weather.get("response"); | |
d.showPrecipDay = false; | |
d.showPrecipNight = false; | |
if (e && e.date) { | |
var c = e.date.hour; | |
if (c >= 1 && c < 19) { | |
d.showPrecipDay = true | |
} | |
if (c >= 13) { | |
d.showPrecipNight = true | |
} | |
} | |
var f = wui.bootstrapped && wui.bootstrapped.precip ? wui.bootstrapped.precip.baseUrl : ""; | |
if (f && e.location) { | |
f += a.generateCityQuery({ | |
zip: e.location.zip, | |
magic: e.location.magic, | |
wmo: e.location.wmo, | |
country: e.location.country_iso3166 | |
}) | |
} | |
d.cityUrl = f; | |
var i = this.template(d); | |
var h = this.$el.find(".accordion").eq(0); | |
h.append(i); | |
this.checkStorm(); | |
b(document).trigger("responsive_tables.new_table"); | |
return this | |
}, | |
checkStorm: function() { | |
if (wui.bootstrapped && wui.bootstrapped.citypage) { | |
var e = wui.bootstrapped.citypage.storm; | |
for (var d in e) { | |
var c = "dd#fctDay-" + d; | |
var f = "has-alert"; | |
if (e[d].type === "blizzard") { | |
f += " has-blizzard" | |
} | |
if (b(c).length) { | |
b(c).addClass(f) | |
} | |
} | |
} | |
}, | |
fixPosition: function(c) { | |
setTimeout(function() { | |
var d = b(c.target).offset().top; | |
var e = b(window).scrollTop(); | |
if (e > d) { | |
b(window).scrollTop(d - 35) | |
} | |
}, 0) | |
} | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Views.TableVerticalSimple = Backbone.View.extend({ | |
events: { | |
"click .accordion > dd": "fixPosition" | |
}, | |
initialize: function(c) { | |
this.options = c || {}; | |
this.weather = this.options.weather; | |
this.template = _.template(b("script#table-vertical-simple-template").html()); | |
this.listenTo(this.weather, "change:forecast", this.renderReady); | |
if (this.options.render && this.weather.attributes.forecast) { | |
this.render() | |
} | |
}, | |
renderReady: function() { | |
if (this.weather.get("forecast")) { | |
this.render() | |
} | |
}, | |
render: function(e, h) { | |
var c = { | |
labels: this.weather.attributes.labels, | |
weather: this.weather.attributes | |
}; | |
var d = this.weather.get("response"); | |
var g = this.template(c); | |
var f = this.$el.find(".accordion").eq(0); | |
f.append(g); | |
this.checkStorm(); | |
return this | |
}, | |
checkStorm: function() { | |
if (wui.bootstrapped && wui.bootstrapped.citypage) { | |
var e = wui.bootstrapped.citypage.storm; | |
for (var d in e) { | |
var c = "dd#fctDay-" + d; | |
var f = "has-alert"; | |
if (e[d].type === "blizzard") { | |
f += " has-blizzard" | |
} | |
if (b(c).length) { | |
b(c).addClass(f) | |
} | |
} | |
} | |
}, | |
fixPosition: function(c) { | |
setTimeout(function() { | |
var d = b(c.target).offset().top; | |
var e = b(window).scrollTop(); | |
if (e > d) { | |
b(window).scrollTop(d - 35) | |
} | |
}, 0) | |
} | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Views.TableHorizontal = Backbone.View.extend({ | |
events: { | |
"click #fctDayLeftArrow": "leftScroll", | |
"click #fctDayRightArrow": "rightScroll" | |
}, | |
initialize: function(c) { | |
this.options = c || {}; | |
this.weather = this.options.weather; | |
this.dayMaxWidth = 115; | |
this.templateDay = _.template(b("script#table-horizontal-day-template").html()); | |
this.templateDetails = _.template(b("script#table-horizontal-details-template").html()); | |
this.listenTo(this.weather, "change:forecast", this.render); | |
this._tabsCreated = false; | |
if (this.options.render && this.weather.attributes.forecast) { | |
this.render() | |
} | |
}, | |
checkArrows: function() { | |
var c = b("#fctDaySelect"); | |
var e = b("#fctDayScroll"); | |
var d = e.scrollLeft(); | |
var g = e.width(); | |
var f = c.width(); | |
var h = b("#fctDayLeftArrow"); | |
var i = b("#fctDayRightArrow"); | |
if (g < f) { | |
if (d == 0) { | |
h.hide() | |
} else { | |
h.show() | |
} | |
if ((d + g) >= f - 1) { | |
i.hide() | |
} else { | |
i.show() | |
} | |
} else { | |
h.hide(); | |
i.hide() | |
} | |
}, | |
leftScroll: function() { | |
var d = b("#fctDayScroll"); | |
var c = { | |
position: d.scrollLeft(), | |
width: d.width(), | |
amount: (d.width() / 2) | |
}; | |
d.animate({ | |
scrollLeft: (c.position - c.amount) | |
}, { | |
duration: "fast", | |
complete: function() {} | |
}) | |
}, | |
rightScroll: function() { | |
var d = b("#fctDayScroll"); | |
var c = { | |
position: d.scrollLeft(), | |
width: d.width(), | |
amount: (d.width() / 2) | |
}; | |
d.animate({ | |
scrollLeft: (c.position + c.amount) | |
}, { | |
duration: "fast", | |
complete: function() {} | |
}) | |
}, | |
fitDays: function() { | |
var k = b("#hourly-horizontal"); | |
var d = b("#fctDayScroll"); | |
var j = b("#fctDaySelect"); | |
var i = j.children("li"); | |
var c = i.length; | |
var h = k.width(); | |
var f = Math.floor(h / this.dayMaxWidth); | |
var l = d.height(); | |
if (f >= c) { | |
f = c | |
} | |
var g = h / f; | |
var e = g * c; | |
j.width(e); | |
i.width(g); | |
if (d.height() > l) { | |
j.width(e + 1) | |
} | |
this.checkArrows() | |
}, | |
render: function(i, g) { | |
var h = ""; | |
var j = { | |
labels: this.weather.attributes.labels, | |
weather: this.weather.attributes | |
}; | |
var e = this.weather.get("response"); | |
var c = wui.bootstrapped && wui.bootstrapped.precip ? wui.bootstrapped.precip.baseUrl : ""; | |
j.showPrecipDay = false; | |
j.showPrecipNight = false; | |
if (e && e.date) { | |
var f = e.date.hour; | |
if (f >= 1 && f < 19) { | |
j.showPrecipDay = true | |
} | |
if (f >= 13) { | |
j.showPrecipNight = true | |
} | |
} | |
var c = wui.bootstrapped && wui.bootstrapped.precip ? wui.bootstrapped.precip.baseUrl : ""; | |
if (c && e.location) { | |
c += a.generateCityQuery({ | |
zip: e.location.zip, | |
magic: e.location.magic, | |
wmo: e.location.wmo, | |
country: e.location.country_iso3166 | |
}) | |
} | |
j.cityUrl = c; | |
if (this._tabsCreated === true) { | |
this.$el.tabs("destroy") | |
} | |
this.$el.empty(); | |
h = this.templateDay(j); | |
this.$el.append(h); | |
if (this.options.mode !== "simple") { | |
h = this.templateDetails(j); | |
this.$el.append(h); | |
this.$el.tabs(); | |
this._tabsCreated = true | |
} | |
this.fitDays(); | |
var k = _.bind(this.fitDays, this); | |
var d = _.debounce(k, 500); | |
b(window).resize(d); | |
var l = this; | |
b("#fctDayScroll").scroll(function() { | |
l.checkArrows() | |
}); | |
l.checkStorm(); | |
return this | |
}, | |
checkStorm: function() { | |
if (wui.bootstrapped && wui.bootstrapped.citypage) { | |
var e = wui.bootstrapped.citypage.storm; | |
for (var d in e) { | |
var c = "li#fctDay-" + d; | |
var f = "has-alert"; | |
if (e[d].type === "blizzard") { | |
f += " has-blizzard" | |
} | |
if (b(c).length) { | |
b(c).addClass(f) | |
} | |
} | |
} | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Views.Context = Backbone.View.extend({ | |
events: {}, | |
initialize: function(b) { | |
this.options = b || {}; | |
this.weather = this.options.weather; | |
this.template = _.template(a("script#context-slideshow-template").html()); | |
this.listenTo(this.weather, "change:forecast", this.render); | |
if (this.options.render && this.weather.attributes.forecast) { | |
this.render() | |
} | |
}, | |
render: function(c, e) { | |
var b = { | |
labels: this.weather.attributes.labels, | |
weather: this.weather.attributes | |
}; | |
var d = this.template(b); | |
this.$el.html(d); | |
this.$el.foundation(); | |
return this | |
} | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Views.PlotGroup = Backbone.View.extend({ | |
events: { | |
"click .plot-pan-left": "onPanLeft", | |
"click .plot-pan-right": "onPanRight", | |
"click .plot-zoom-hourly": "onZoomIn", | |
"click .plot-zoom-daily": "onZoomOut", | |
"click .plots": "onClick", | |
"mousedown .plots": "onMousedown", | |
"mouseup .plots": "onMouseup", | |
"mousemove .plots": "onMousemove", | |
"mouseleave .plots": "onMouseleave", | |
"touchstart .plots": "onTouchstart", | |
"touchmove .plots": "onTouchmove", | |
"touchend .plots": "onTouchend", | |
"touchcancel .plots": "onTouchcancel" | |
}, | |
initialize: function(d) { | |
this.options = d || {}; | |
this.models = this.options.models || {}; | |
if (!this.models.plotGroup) { | |
console.error("missing required model `plotGroup` in this.models"); | |
return | |
} | |
if (!this.models.weather) { | |
console.error("missing required model `weather` in this.models"); | |
return | |
} | |
var f = this.$el.is(":visible"); | |
this._initialized = true; | |
this._now = null; | |
this._numRenders = 0; | |
this._touchstart = {}; | |
this._animateZoom = true; | |
this._presets = null; | |
this._presetsUnits = null; | |
if (Modernizr && Modernizr.touch) { | |
this._animateZoom = false | |
} else { | |
if (b(window).width() < 400) { | |
this._animateZoom = false | |
} | |
} | |
var c = this.checkDayPartsOnly(); | |
this.status = new Backbone.NestedModel({ | |
condition: null, | |
day: null, | |
dayPartsOnly: c, | |
dragging: false, | |
mousedown: false, | |
needle: { | |
locked: false, | |
timer: null, | |
x: 0, | |
y: 0 | |
}, | |
range: {}, | |
timestamp: null, | |
touching: false, | |
transition: { | |
duration: 0 | |
}, | |
translation: { | |
x: 0, | |
y: 0, | |
z: 0 | |
}, | |
zoomedIn: (this.options.zoomedIn) ? this.options.zoomedIn : false | |
}); | |
var e = this.models.plotGroup.get("classNames"); | |
this.plots = []; | |
this.variablesMenu = null; | |
this.$needle = null; | |
this.$needleLabels = null; | |
this.$plots = this.$el.find("." + e.plots); | |
this.listenTo(this.models.weather, "change", this.onWeatherChange); | |
this.listenTo(this.status, "change:timestamp", this.onTimestampChange); | |
this.listenTo(this.status, "change:dragging", this.onDraggingChange); | |
this.listenTo(this.status, "change:zoomedIn", this.onZoomedInChange); | |
this.listenTo(this.status, "change:range", this.onRangeChange); | |
this.listenTo(this.status, "change:translation", this.onTranslateChange); | |
this.listenTo(this, "plotpan", this.onPlotPan); | |
if (this.options.render && this.models.weather.attributes.forecast) { | |
this.render() | |
} | |
}, | |
initializeAtFirstRender: function() { | |
this.checkFlotAxesPresets({ | |
presetKey: "tickUnitsPreset", | |
valueKey: "tickUnits", | |
fnName: "getUnitPreset" | |
}); | |
this.checkFlotAxesPresets({ | |
presetKey: "tickDecimalsPreset", | |
valueKey: "tickDecimals", | |
fnName: "getTickDecimalsPreset" | |
}); | |
this.checkFlotAxesPresets({ | |
presetKey: "ticksPreset", | |
valueKey: "ticks", | |
fnName: "getTicksPreset" | |
}); | |
this.checkVariablesPresets(); | |
this.createViews(); | |
var d = _.some(this.plots, function(h) { | |
return h.isHeader() | |
}); | |
var f = this.models.plotGroup.get("classNames"); | |
this.$plots.toggleClass(f.hasHeader, d); | |
if (this.models.plotGroup.get("needleNow")) { | |
this.createNeedleNow() | |
} | |
this.createNeedle(); | |
if (this.models.plotGroup.get("needleDateLabels")) { | |
this.createNeedleLabels() | |
} | |
this.setZoomButtons(); | |
var g = _.bind(this.onResize, this); | |
var e = _.debounce(g, 500); | |
b(window).resize(e); | |
var c = _.bind(this.fitRangeY, this); | |
this.fitRangeYDebounced = _.debounce(c, 500); | |
b("body").on("mouseup", _.bind(this.onMouseup, this)); | |
this.listenTo(this.models.plotGroup, "change:plots", this.onVariablesChange); | |
this.checkPrecip() | |
}, | |
addPlotEvents: function(d) { | |
var e = this.plots[d]; | |
var c = this; | |
e.$el.bind("plotpan", function(g, f, h) { | |
c.trigger("plotpan", d, h) | |
}) | |
}, | |
animateRangeX: function(h, m, g, l, f) { | |
var o = this; | |
var c = null; | |
if (!l) { | |
l = this.getFirstPlot() | |
} | |
var n = l.flot.getAxes().xaxis | |
, d = n.min | |
, k = n.max | |
, j = (window.performance && window.performance.now) ? window.performance.now() : null; | |
var i = 0; | |
this.setStatusRange({}); | |
function e(u) { | |
if (j === null) { | |
j = u | |
} | |
i++; | |
var r = u - j; | |
var t = r / g; | |
var q = false; | |
if (t > 1) { | |
t = 1; | |
q = true | |
} | |
var s = d + t * (h - d); | |
var p = k - t * (k - m); | |
o.setRangeX(s, p); | |
o.setStatusRange({ | |
complete: q, | |
elapsed: r, | |
fraction: t, | |
frame: i, | |
min: s, | |
max: p | |
}); | |
if (q) { | |
if (f) { | |
f() | |
} | |
} else { | |
c = requestAnimationFrame(e) | |
} | |
} | |
c = requestAnimationFrame(e); | |
return c | |
}, | |
checkDayPartsOnly: function() { | |
var d = false; | |
var g = this.getDays(); | |
var e = g[0]; | |
var f = e.observations; | |
var c = e.hours; | |
if (f && f.length) { | |
d = false | |
} else { | |
if (c && c.length) { | |
d = false | |
} else { | |
d = true | |
} | |
} | |
return d | |
}, | |
checkFlotAxesPresets: function(c) { | |
c = b.extend({ | |
axis: "y", | |
presetKey: "", | |
valueKey: "", | |
fnName: "" | |
}, c); | |
var p = {}; | |
var f = c.axis + "axis"; | |
var d = c.axis + "axes"; | |
var h = this[c.fnName]; | |
var m = this.models.plotGroup.get("plots"); | |
for (var k = 0; k < m.length; k++) { | |
var l = m[k].flot; | |
if (l && l[f]) { | |
var q = l[f][c.presetKey]; | |
if (q) { | |
var n = h.call(this, q); | |
if (n) { | |
var o = "plots[" + k + "].flot." + f + "." + c.valueKey; | |
this.models.plotGroup.set(o, n) | |
} | |
} | |
} | |
if (l && l[d]) { | |
for (var g = l[d].length - 1; g >= 0; g--) { | |
var e = l[d][g]; | |
var q = e[c.presetKey]; | |
if (q) { | |
var n = h.call(this, q); | |
if (n) { | |
var o = "plots[" + k + "].flot." + d + "[" + g + "]." + c.valueKey; | |
this.models.plotGroup.set(o, n) | |
} | |
} | |
} | |
} | |
} | |
}, | |
checkInitialized: function() { | |
if (this._initialized !== true) { | |
this.initialize(this.options); | |
this.render() | |
} | |
}, | |
checkNeedleDirection: function(e) { | |
var d = e.pageX; | |
for (var c = 0; c < this.plots.length; c++) { | |
var f = this.plots[c]; | |
var g = f.flot.getOptions().needle; | |
if (g && g.show) { | |
f.flot.needle.checkDirection(d) | |
} | |
} | |
}, | |
checkNeedleLabels: function() { | |
var c = this.$needle.offset().left + this.$needle.width() / 2; | |
var f = 0; | |
var e = this.fromScreenToFlotPos(c, f); | |
this.checkPosition({ | |
lockNeedle: true, | |
pos: e | |
}); | |
var d = this; | |
_.defer(function() { | |
b("#forecastGraph").css("opacity", "1"); | |
b("#forecastGraph").css("filter", ""); | |
b("#forecastGraph").css("background-color", ""); | |
b("#plots").css("visibility", "visible"); | |
d.delegateEvents(); | |
d.checkStorm() | |
}) | |
}, | |
checkPanRange: function(c) { | |
var e = c; | |
var f = this._touchstart.x_min | |
, d = this._touchstart.x_max; | |
if (c > 0) { | |
if (f !== null && -c < f) { | |
e = -f | |
} | |
} else { | |
if (d !== null && -c > d) { | |
e = -d | |
} | |
} | |
return e | |
}, | |
checkPosition: function(c) { | |
c = b.extend({ | |
date: null, | |
event: null, | |
item: null, | |
lockNeedle: false, | |
plot: null, | |
pos: null | |
}, c); | |
var e = null | |
, f = null | |
, k = null; | |
var h = c.plot || this.getFirstPlot(); | |
if (c.date) { | |
b.extend(true, c, { | |
pos: { | |
x: c.date.getTime() | |
} | |
}) | |
} | |
if (h && c.pos) { | |
var g = this.getTimezone(); | |
var i = h.flot.getAxes() | |
, j = i.xaxis | |
, l = Math.min(Math.max(c.pos.x, j.min), j.max); | |
e = this.getClosestConditionByTimestamp(l); | |
if (e) { | |
k = a.getTimestamp(e, g); | |
var d = this.checkTimestampInViewport(k); | |
if (d) { | |
f = this.getDayByCondition(e) | |
} else { | |
e = null; | |
k = null | |
} | |
} | |
} | |
this.status.set({ | |
condition: e, | |
day: f, | |
"needle.locked": c.lockNeedle, | |
timestamp: k | |
}) | |
}, | |
checkPrecip: function() { | |
var f = this.models.plotGroup.get("classNames"); | |
var e = this.models.plotGroup.get("plots"); | |
var g = _.pluck(e, "variables"); | |
g = [].concat.apply([], g); | |
var c = _.some(g, function(h) { | |
return ( h.show === true && h.hasPrecip === true) | |
}); | |
var d = _.find(this.plots, function(h) { | |
return h.isHeader() | |
}); | |
if (d) { | |
d.$el.toggleClass(f.hasPrecip, c) | |
} | |
return c | |
}, | |
checkRangeOptions: function() { | |
var g = this.models.plotGroup.attributes; | |
var j = this.getTimezone(); | |
var q, f; | |
var o = _.filter(this.getDays(), function(d) { | |
return d.hasOwnProperty("observations") || d.hasOwnProperty("hours") | |
}) | |
, c = _.first(o) | |
, m = _.last(o); | |
if (g.date_min === "auto") { | |
var n = this.getHours(c); | |
var e = _.first(n) || c.summary; | |
var p = a.getTimestamp(e, j); | |
var l = new Date(p); | |
if (p && l) { | |
q = wui.date.roundDownTo(l, 1, "day") | |
} | |
} else { | |
if (g.date_min) { | |
q = g.date_min | |
} | |
} | |
if (g.date_max === "auto") { | |
var n = this.getHours(m); | |
var e = _.last(n) || m.summary; | |
var p = a.getTimestamp(e, j); | |
var l = new Date(p); | |
if (p && l) { | |
f = wui.date.roundUpTo(l, 1, "day") | |
} | |
} else { | |
if (g.date_max) { | |
f = g.date_max | |
} | |
} | |
for (var h = 0; h < this.plots.length; h++) { | |
var k = this.plots[h]; | |
k.setPanRange(q, f) | |
} | |
if (q) { | |
this.models.plotGroup.set("date_min", q) | |
} | |
if (f) { | |
this.models.plotGroup.set("date_max", f) | |
} | |
}, | |
checkTimestampInViewport: function(d) { | |
var c = this.getViewportDates(); | |
if (d >= c.begin.getTime() && d <= c.end.getTime()) { | |
return true | |
} else { | |
return false | |
} | |
}, | |
checkTouchmove: function(c) { | |
var f = false; | |
var e = this.models.plotGroup.get("bufferLeft"); | |
var d = this.models.plotGroup.get("bufferRight"); | |
if (e || d) { | |
if (e && c > 0 && c > e) { | |
f = true | |
} | |
if (d && c < 0 && -c > d) { | |
f = true | |
} | |
} | |
return f | |
}, | |
checkVariablesPresets: function() { | |
var k = this.models.plotGroup.get("plots"); | |
for (var g = 0; g < k.length; g++) { | |
var m = k[g].variables; | |
for (var e = 0; e < m.length; e++) { | |
var d = m[e]; | |
if (_.has(d, "preset")) { | |
var l = "plots[" + g + "].variables[" + e + "]"; | |
var f = this.getVariablePreset(d.preset); | |
if (f) { | |
var h = b.extend(true, {}, f, d); | |
this.models.plotGroup.set(l, h) | |
} else { | |
var c = "unknown preset `" + d.preset + "` in " + l; | |
console.error(c) | |
} | |
} | |
} | |
} | |
}, | |
createNeedle: function() { | |
var d = this.models.plotGroup.get("classNames"); | |
var c = b("<div />").addClass(d.needle).html('<div class="' + d.needleLine + '" />'); | |
this.$plots.append(c); | |
this.$needle = c | |
}, | |
createNeedleLabels: function() { | |
var h = this.models.plotGroup.get("classNames"); | |
var c = this.$needle; | |
var g = this.getFirstPlot(); | |
var e = g.createNeedleLabel(); | |
var f = e.clone(); | |
e.addClass(h.needleLabelTop).appendTo(c); | |
f.addClass(h.needleLabelBottom).appendTo(c); | |
var d = b().add(e).add(f); | |
this.$needleLabels = d | |
}, | |
createNeedleNow: function() { | |
var g = this.models.plotGroup.get("classNames"); | |
var c = b("<div />").addClass(g.needleNow); | |
var d = b("script#plotgroup-needle-now-template"); | |
if (d[0]) { | |
var f = _.template(d.html()); | |
var e = f({}); | |
c.html(e) | |
} | |
this.$plots.append(c); | |
this.$needleNow = c | |
}, | |
createViews: function() { | |
var k = this.models.plotGroup.get("classNames"); | |
var h = this.$plots; | |
var g = this.models.plotGroup.get("selectors"); | |
var c = this.models.plotGroup.get("plots"); | |
for (var f = 0; f < c.length; f++) { | |
var d = "" + k.numberedItem + f; | |
var e = b("<div />").addClass(k.plot).addClass(d).appendTo(h); | |
if (f === c.length - 1) { | |
e.addClass(k.lastPlot) | |
} | |
var j = new wui.Views.Plot({ | |
model: this.model, | |
models: { | |
plotGroup: this.models.plotGroup, | |
weather: this.models.weather | |
}, | |
el: e[0], | |
status: this.status, | |
plotIndex: f | |
}); | |
this.plots.push(j); | |
this.addPlotEvents(f) | |
} | |
this.variablesMenu = new wui.Views.PlotVariablesMenu({ | |
model: this.model, | |
models: { | |
plotGroup: this.models.plotGroup, | |
weather: this.models.weather | |
}, | |
el: b(g.variablesMenu)[0], | |
}) | |
}, | |
dragstart: function(k) { | |
k = b.extend(true, { | |
event: null, | |
currentTouch: null | |
}, k); | |
this.status.set("dragging", false); | |
var d = (k.currentTouch) ? k.currentTouch.pageX : k.event.pageX; | |
var c = (k.currentTouch) ? k.currentTouch.pageY : k.event.pageY; | |
var p = this.getFirstPlot() | |
, q = p.flot.getAxes() | |
, f = q.xaxis; | |
var n = p.getWidth(); | |
var s = null | |
, t = null; | |
var r = this.models.plotGroup.get("bufferLeft") | |
, j = this.models.plotGroup.get("bufferRight"); | |
var l = this.models.plotGroup.get("date_min") | |
, o = this.models.plotGroup.get("date_max"); | |
var h = this.getViewportDates(); | |
if (l) { | |
s = f.p2c(l.getTime()) - f.p2c(h.begin.getTime()) | |
} | |
if (o) { | |
t = f.p2c(o.getTime()) - f.p2c(h.begin.getTime()) - n | |
} | |
var i = this.status.get("translation"); | |
if (i.x) { | |
s -= i.x; | |
t -= i.x | |
} | |
var g = false; | |
if (k.currentTouch) { | |
var e = b(k.currentTouch.target); | |
var m = e.closest(this.$needle); | |
g = !!(m[0]) | |
} | |
this._touchstart = { | |
needle: g, | |
pageX: d, | |
pageY: c, | |
translation: { | |
x: i.x, | |
y: i.y | |
}, | |
x_min: s, | |
x_max: t | |
}; | |
this._lasttouch = { | |
pageX: d, | |
pageY: c | |
} | |
}, | |
dragmove: function(g) { | |
g = b.extend(true, { | |
event: null, | |
currentTouch: null | |
}, g); | |
this.status.set("dragging", true); | |
var f = (g.currentTouch) ? g.currentTouch.pageX : g.event.pageX; | |
var d = f - this._touchstart.pageX; | |
if (this._touchstart.translation) { | |
d += this._touchstart.translation.x | |
} | |
if (this._touchstart.needle) { | |
var h = this.fromEventToFlotPos(g.event); | |
this.checkPosition({ | |
event: g.event, | |
pos: h | |
}) | |
} else { | |
d = this.checkPanRange(d); | |
var e = this.checkTouchmove(d); | |
if (e) { | |
this.recenter(d) | |
} else { | |
this.status.set("translation.x", d) | |
} | |
var c = this.status.get("touching"); | |
if (c) { | |
this.checkNeedleLabels() | |
} | |
} | |
}, | |
dragend: function(f) { | |
f = b.extend(true, { | |
event: null, | |
eventInitiator: "dragend", | |
currentTouch: null | |
}, f); | |
var h = this.status.get("dragging"); | |
if (h) { | |
this.status.set("dragging", false); | |
return | |
} | |
var e = this._animateZoom; | |
var j = this.fromEventToFlotPos(f.event); | |
var i = this.fromEventToPlot(f.event); | |
var g = (i && i.isHeader()); | |
var d = this.models.plotGroup.get("zoomable"); | |
if (d && g) { | |
var c = this.status.get("zoomedIn"); | |
if (c) { | |
this.zoomOut({ | |
animate: e, | |
eventInitiator: f.eventInitiator | |
}) | |
} else { | |
if (this._scrollDirection != "y") { | |
this.zoomIn({ | |
animate: e, | |
d: new Date(j.x), | |
eventInitiator: f.eventInitiator | |
}) | |
} | |
} | |
} else { | |
this.checkPosition({ | |
event: event, | |
pos: j | |
}) | |
} | |
this.status.set("dragging", false) | |
}, | |
drawNeedleLabels: function(c) { | |
c = b.extend({ | |
condition: null, | |
day: null, | |
selectedVariable: "", | |
timestamp: null | |
}, c); | |
var e = c.condition | |
, o = c.day | |
, n = n | |
, l = c.timestamp; | |
var j = this.getTimezone() | |
, m = new Date(l) | |
, f = this.getNeedleDateLabel(m, j); | |
var h = this.models.plotGroup.get("mode"); | |
for (var g = 0; g < this.plots.length; g++) { | |
var k = this.plots[g]; | |
if (k.isHeader()) { | |
k.updateNeedleLabels({ | |
mode: h, | |
selectedVariable: n, | |
timestamp: l, | |
top: 0, | |
value: f | |
}) | |
} else { | |
k.updateNeedleLabels({ | |
condition: e, | |
day: o, | |
mode: h, | |
selectedVariable: n, | |
timestamp: l | |
}) | |
} | |
} | |
if (this.$needleLabels) { | |
this.$needleLabels.html(f) | |
} | |
}, | |
drawPlots: function(d) { | |
var e = b.extend(true, { | |
setupGrid: true, | |
xaxisOptions: this.getXAxisOptions() | |
}, d); | |
for (var c = 0; c < this.plots.length; c++) { | |
this.plots[c].draw(e) | |
} | |
}, | |
getLabels: function() { | |
var c = null; | |
if (!c && this.models.labels) { | |
c = this.models.labels.attributes | |
} | |
if (!c) { | |
c = this.models.weather.get("labels") | |
} | |
return c | |
}, | |
getNeedleDateFormat: function(g) { | |
var e = 86400 * 1000 | |
, h = e * 30; | |
var f = g.date.getUTCMinutes(); | |
var c = []; | |
if (g.zoomedIn || g.timespan > 10 * e) { | |
c.push("%a") | |
} | |
if (g.timespan > 10 * e) { | |
c.push("%b %d") | |
} | |
if (g.timespan > 365 * e) { | |
c.push(", %Y") | |
} | |
if (!g.dayPartsOnly) { | |
if (f > 0) { | |
c.push("%l:%M %P") | |
} else { | |
c.push("%l %P") | |
} | |
} | |
var d = c.join(" "); | |
return d | |
}, | |
getNeedleDateString: function(d) { | |
var c = wui.date.strftime(d.format, d.date, true); | |
return c | |
}, | |
getNeedleDateLabel: function(j, i) { | |
var h = this.getViewportDates(); | |
var l = (h.end - h.begin); | |
var c = { | |
date: j, | |
dayPartsOnly: this.status.get("dayPartsOnly"), | |
timespan: l, | |
timezone: i, | |
zoomable: this.models.plotGroup.get("zoomable"), | |
zoomedIn: this.status.get("zoomedIn") | |
}; | |
var e = ""; | |
var k = this.models.plotGroup.get("needleDateFormat"); | |
if (b.isFunction(k)) { | |
e = k(c) | |
} else { | |
if (k) { | |
e = "" + k | |
} else { | |
e = this.getNeedleDateFormat(c) | |
} | |
} | |
b.extend(c, { | |
format: e | |
}); | |
var f = ""; | |
var g = this.models.plotGroup.get("needleDateString"); | |
if (b.isFunction(g)) { | |
f = g(c) | |
} else { | |
f = this.getNeedleDateString(c) | |
} | |
return f | |
}, | |
getTickDecimalsPreset: function(e) { | |
if (!this._presetsTickDecimals) { | |
var c = this.models.weather.get("response.units"); | |
var d = (c === "metric"); | |
this._presetsTickDecimals = { | |
precip: (d) ? 0 : 1, | |
pressure: (d) ? 0 : 2 | |
} | |
} | |
if (_.has(this._presetsTickDecimals, e)) { | |
return this._presetsTickDecimals[e] | |
} else { | |
return null | |
} | |
}, | |
getTicksPreset: function(e) { | |
if (!this._presetsTicks) { | |
var c = this.models.weather.get("response.units"); | |
var d = (c === "metric"); | |
this._presetsTicks = { | |
precip: function(h) { | |
var f = (d ? 10 : 0.4); | |
var j = []; | |
if (h.datamax !== null && h.datamax <= f) { | |
var g = f; | |
var i = (d ? 2 : 0.1); | |
if (h.max > g) { | |
g = h.max; | |
var k = 6; | |
i = g / (k - 1) | |
} | |
j = _.range(0, g, i); | |
j.push(g) | |
} else { | |
j = h.tickGenerator(h) | |
} | |
return j | |
} | |
} | |
} | |
if (_.has(this._presetsTicks, e)) { | |
return this._presetsTicks[e] | |
} else { | |
return null | |
} | |
}, | |
getUnitPreset: function(c) { | |
if (!this._presetsUnits) { | |
var d = this.getLabels(); | |
this._presetsUnits = { | |
humidity: d.humidity.units, | |
pressure: " " + d.pressure.units, | |
temperature: " " + d.temperature.units, | |
wind: " " + d.wind_speed.units, | |
wind_direction: "°", | |
rainfall: " " + d.rainfall.units | |
} | |
} | |
if (_.has(this._presetsUnits, c)) { | |
return this._presetsUnits[c] | |
} else { | |
return null | |
} | |
}, | |
getVariablePreset: function(c) { | |
if (!this._presets) { | |
var d = this.getLabels(); | |
this._presets = { | |
cloudcover: { | |
id: "cloudcover", | |
abbrev: "cc", | |
legendFillColor: "rgba(142, 143, 145, 0.3)", | |
options: { | |
label: d.cloudcover.label, | |
color: "#8e8f91", | |
lines: { | |
show: true, | |
fill: 0.3, | |
lineWidth: 1 | |
} | |
}, | |
show: true, | |
textColor: "#696969", | |
units: d.cloudcover.units | |
}, | |
dewpoint: { | |
id: "dewpoint", | |
abbrev: "dp", | |
filter: function(e) { | |
return ( e.dewpoint !== -99) | |
}, | |
show: true, | |
textColor: "#22730b", | |
units: " " + d.dewpoint.units, | |
options: { | |
label: d.dewpoint.label, | |
color: "#5b9f4a" | |
} | |
}, | |
feelslike: { | |
id: "feelslike", | |
abbrev: "fl", | |
show: true, | |
units: " " + d.feelslike.units, | |
missingFromNWS: true, | |
options: { | |
label: d.feelslike.label, | |
color: "#ad55a1" | |
} | |
}, | |
humidity: { | |
id: "humidity", | |
abbrev: "h", | |
options: { | |
label: d.humidity.label, | |
color: "#87c404" | |
}, | |
show: true, | |
textColor: "#5b9f49", | |
units: d.humidity.units, | |
}, | |
liquid_precip: { | |
id: "liquid_precip", | |
abbrev: "qpf", | |
hasPrecip: true, | |
legendUnits: d.rainfall.units, | |
missingFromNWS: true, | |
options: { | |
label: "Hourly Liquid Precip.", | |
color: "#22730b", | |
lines: { | |
show: true, | |
steps: true, | |
fill: 0.3, | |
lineWidth: 1 | |
} | |
}, | |
show: true, | |
units: function(h, f, e) { | |
var j = _.clone(h.date); | |
j.epoch += (3600); | |
var i = '<span class="units"> ' + d.rainfall.units + "</span>"; | |
var g = i + " (" + wui.date.strftime("%l%P-", h.date, true) + wui.date.strftime("%l%P", j, true) + ")"; | |
if (e) { | |
g += "<br />" + e.summary.liquid_precip + i + " total (" + wui.date.strftime("%a", e.summary.date, true) + ")" | |
} | |
return g | |
} | |
}, | |
max_temperature: { | |
id: "max_temperature", | |
abbrev: "tmax", | |
enabled: true, | |
enableWhen: function(e) { | |
return ( e.dayPartsOnly) | |
}, | |
options: { | |
label: "Max Temperature", | |
color: "#d6212a" | |
}, | |
show: true, | |
units: " " + d.temperature.units | |
}, | |
min_temperature: { | |
id: "min_temperature", | |
abbrev: "tmin", | |
enabled: true, | |
enableWhen: function(e) { | |
return ( e.dayPartsOnly) | |
}, | |
options: { | |
label: "Min Temperature", | |
color: "#0053ae" | |
}, | |
show: true, | |
units: " " + d.temperature.units | |
}, | |
pop: { | |
id: "pop", | |
abbrev: "pop", | |
show: true, | |
textColor: "#008fbf", | |
units: d.pop.units, | |
options: { | |
label: d.pop.abbrev, | |
color: "#16aadc", | |
lines: { | |
show: true, | |
steps: true, | |
fill: 0.3, | |
lineWidth: 1 | |
} | |
} | |
}, | |
pop_type_notsnow: { | |
id: "pop", | |
abbrev: "pop", | |
checkbox: false, | |
filter: function(e) { | |
return ( e.precip_type !== "snow") | |
}, | |
legendFillColor: "rgba(22, 170, 220, 0.5)", | |
needle: false, | |
options: { | |
label: d.pop.abbrev, | |
color: "#16aadc", | |
bars: { | |
show: true, | |
fill: 0.3, | |
lineWidth: 0 | |
}, | |
lines: { | |
show: false | |
} | |
}, | |
show: true, | |
textColor: "#008fbf", | |
units: d.pop.units | |
}, | |
pop_type_snow: { | |
id: "pop", | |
abbrev: "pop", | |
checkbox: false, | |
filter: function(e) { | |
return ( e.precip_type === "snow") | |
}, | |
legendFillColor: "rgba(128, 38, 116, 0.5)", | |
missingFromNWS: true, | |
needle: false, | |
options: { | |
label: d.chancesnow.label, | |
color: "#16aadc", | |
bars: { | |
show: true, | |
fillColor: "rgba(128, 38, 116, 0.3)", | |
lineWidth: 0 | |
}, | |
lines: { | |
show: false | |
} | |
}, | |
show: true, | |
textColor: "#008fbf", | |
units: d.pop.units | |
}, | |
precip_1hr: { | |
id: "precip_1hr", | |
abbrev: "precip_1hr", | |
show: true, | |
units: " " + d.rainfall.units, | |
options: { | |
label: d.precipitation.label, | |
color: "#87c404" | |
} | |
}, | |
precip_rate: { | |
id: "precip_rate", | |
abbrev: "precip_rate", | |
show: true, | |
units: " " + d.rainfall.units, | |
options: { | |
label: "Precip. Rate", | |
color: "#87c404" | |
} | |
}, | |
precip_today: { | |
id: "precip_today", | |
abbrev: "precip", | |
filter: function(e) { | |
return ( e.precip_today >= 0) | |
}, | |
hasPrecip: true, | |
missingFromNWS: true, | |
options: { | |
label: "Precip. Accum. Total", | |
color: "#0074a2", | |
}, | |
show: true, | |
units: " " + d.rainfall.units | |
}, | |
pressure: { | |
id: "pressure", | |
abbrev: "p", | |
missingFromNWS: true, | |
options: { | |
label: d.pressure.label, | |
color: "#1e2023" | |
}, | |
show: true, | |
units: " " + d.pressure.units | |
}, | |
temperature: { | |
id: "temperature", | |
abbrev: "temp", | |
enabled: true, | |
enableWhen: function(e) { | |
return ( !e.dayPartsOnly) | |
}, | |
options: { | |
label: d.temperature.label, | |
color: "#d6212a" | |
}, | |
show: true, | |
units: " " + d.temperature.units | |
}, | |
wind_speed: { | |
id: "wind_speed", | |
abbrev: "wspd", | |
show: true, | |
units: " " + d.wind_speed.units, | |
options: { | |
label: d.wind_speed.label, | |
color: "#002f80" | |
} | |
}, | |
wind_dir_degrees: { | |
id: "wind_dir_degrees", | |
abbrev: "wdir", | |
show: true, | |
legendUnits: false, | |
units: function(f, e) { | |
return '<span class="units"> deg</span> (from ' + f.wind_dir + ")" | |
}, | |
options: { | |
label: d.wind_direction.label, | |
color: "#002f80", | |
lines: { | |
show: false | |
}, | |
points: { | |
fill: false, | |
radius: 1, | |
show: true | |
} | |
} | |
}, | |
wind_gust: { | |
id: "wind_gust_speed", | |
abbrev: "gust", | |
show: true, | |
units: " " + d.wind_gust.units, | |
options: { | |
label: d.wind_gust.label, | |
color: "#EF9856", | |
lines: { | |
show: false | |
}, | |
points: { | |
fill: false, | |
radius: 1, | |
show: true | |
} | |
} | |
}, | |
wind_speed_dir: { | |
id: "wind_speed", | |
abbrev: "wspd", | |
legendUnits: false, | |
show: true, | |
units: function(f, e) { | |
return '<span class="units"> ' + d.wind_speed.units + "</span> from " + f.wind_dir | |
}, | |
color: "#002f80", | |
options: { | |
label: d.wind_speed.label, | |
color: "rgba(0,47,128,0.5)", | |
lines: { | |
show: true, | |
lineWidth: 1 | |
}, | |
rotatedmarker: { | |
id: "wind_dir_degrees", | |
show: true, | |
fill: true, | |
fillColor: "#002f80", | |
preventOverlap: true, | |
preventOverlapMargin: 2, | |
radius: 5, | |
symbol: wui.backbone.utils.symbols.arrow | |
} | |
} | |
}, | |
solarradiation: { | |
id: "solarradiation", | |
abbrev: "s", | |
enableWhen: function(e) { | |
return ( !e.dayPartsOnly) | |
}, | |
options: { | |
label: "Solar Radiation", | |
color: "#FFB92F" | |
}, | |
show: true, | |
units: " watts/m²" | |
}, | |
uv_index: { | |
id: "uv_index", | |
abbrev: "uv", | |
enableWhen: function(e) { | |
return ( !e.dayPartsOnly) | |
}, | |
options: { | |
label: d.uv_index.label, | |
color: "#802674" | |
}, | |
show: true, | |
units: "" | |
}, | |
aqpm10: { | |
id: "aqpm10", | |
abbrev: "pm10", | |
options: { | |
label: "PM 10", | |
color: "#CC5500" | |
}, | |
show: true, | |
units: " μg/m3" | |
}, | |
aqozone: { | |
id: "aqozone", | |
abbrev: "ozone", | |
options: { | |
label: "Ozone", | |
color: "#FFB580" | |
}, | |
show: true, | |
units: " ppb" | |
}, | |
aqpm25: { | |
id: "aqpm25", | |
abbrev: "pm2.5", | |
options: { | |
label: "PM 2.5", | |
color: "#990008" | |
}, | |
show: true, | |
units: " μg/m3" | |
}, | |
aqso2: { | |
id: "aqso2", | |
abbrev: "so2", | |
options: { | |
label: "SO2", | |
color: "#8ED1E9" | |
}, | |
show: true, | |
units: " ppb" | |
}, | |
aqno2: { | |
id: "aqno2", | |
abbrev: "no2", | |
options: { | |
label: "NO2", | |
color: "#AC54A0" | |
}, | |
show: true, | |
units: " ppb" | |
}, | |
aqco: { | |
id: "aqco", | |
abbrev: "co", | |
options: { | |
label: "CO", | |
color: "#6697CC" | |
}, | |
show: true, | |
units: " ppm" | |
} | |
} | |
} | |
if (_.has(this._presets, c)) { | |
return this._presets[c] | |
} else { | |
return null | |
} | |
}, | |
getViewportDates: function() { | |
var j = this.getFirstPlot() | |
, e = j.flot; | |
var k = e.getAxes() | |
, l = k.xaxis; | |
var g = new Date(l.min) | |
, m = new Date(l.max); | |
var i = this.fromBufferedToViewportDates(g, m); | |
var f = i.begin.getTime() | |
, h = i.end.getTime(); | |
var c = this.status.get("translation"); | |
if (c.x) { | |
var d = l.c2p(c.x) - l.c2p(0); | |
f -= d; | |
h -= d | |
} | |
return { | |
begin: new Date(f), | |
end: new Date(h) | |
} | |
}, | |
fitDays: function(d, c, g) { | |
var f = this.getFittedDates(c); | |
if (f) { | |
var e = this.fromViewportToBufferedDates(f.begin, f.end); | |
this.synchronizeZoom(null, e.begin, e.end, !!d, g) | |
} else { | |
this.drawPlots() | |
} | |
}, | |
fitRangeY: function() { | |
for (var c = 0; c < this.plots.length; c++) { | |
var d = this.plots[c]; | |
d.fitRangeY() | |
} | |
}, | |
fitRangeYDebounced: function() {}, | |
fromBufferedToViewportDates: function(h, n) { | |
var e = h.getTime() | |
, j = n.getTime(); | |
var i = this.models.plotGroup.get("bufferLeft"); | |
var l = this.models.plotGroup.get("bufferRight"); | |
if (i || l) { | |
var k = this.getFirstPlot() | |
, f = k.flot | |
, g = f.getPlotOffset() | |
, o = f.width() | |
, c = n - h; | |
var m = i / o | |
, d = l / o; | |
e = (e + m * c); | |
j = (j - d * c); | |
e = a.roundTimestamp(e, 1000); | |
j = a.roundTimestamp(j, 1000) | |
} | |
return { | |
begin: new Date(e), | |
end: new Date(j) | |
} | |
}, | |
fromElementToPlot: function(d) { | |
var f = this.models.plotGroup.get("classNames"); | |
var c = d.closest("." + f.plot); | |
var e = _.find(this.plots, function(g) { | |
return g.$el.is(c) | |
}); | |
return e | |
}, | |
fromEventToFlotPos: function(e) { | |
var d = e.pageX | |
, c = e.pageY; | |
var g = e.originalEvent; | |
if (g && g.changedTouches) { | |
var f = g.changedTouches[0]; | |
d = f.pageX; | |
c = f.pageY | |
} | |
return this.fromScreenToFlotPos(d, c) | |
}, | |
fromEventToPlot: function(d) { | |
var c = b(d.target); | |
return this.fromElementToPlot(c) | |
}, | |
fromScreenToFlotPos: function(h, g) { | |
var d = this.models.plotGroup.get("classNames"); | |
var i = this.models.plotGroup.get("bufferLeft"); | |
var j = this.getFirstPlot() | |
, k = j.flot.getAxes() | |
, m = k.xaxis; | |
var e = j.flot.getPlotOffset(); | |
var c = this.status.get("translation"); | |
var f = h - this.$plots.offset().left + i - e.left - c.x; | |
var l = { | |
x: m.c2p(f), | |
y: 0, | |
pageX: h, | |
pageY: g | |
}; | |
return l | |
}, | |
fromViewportToBufferedDates: function(g, q) { | |
var d = g.getTime() | |
, j = q.getTime(); | |
var k = this.getFirstPlot() | |
, e = k.flot; | |
var m = e.getAxes() | |
, o = m.xaxis; | |
var h = this.models.plotGroup.get("bufferLeft"); | |
var l = this.models.plotGroup.get("bufferRight"); | |
if (h || l) { | |
var f = e.getPlotOffset() | |
, n = k.getWidth() | |
, i = q - g; | |
var p = h / n | |
, c = l / n; | |
d = (d - p * i); | |
j = (j + c * i); | |
d = a.roundTimestamp(d, 1000); | |
j = a.roundTimestamp(j, 1000) | |
} | |
return { | |
begin: new Date(d), | |
end: new Date(j) | |
} | |
}, | |
getClosestConditionByTimestamp: function(g) { | |
var o = this.getDays(); | |
var c = 0; | |
var p = null; | |
var d = null; | |
var f = this.getTimezone(); | |
var l = []; | |
for (var e = 0; e < o.length; e++) { | |
var j = o[e]; | |
var k = this.getHours(j); | |
if (k) { | |
l = l.concat(k) | |
} else { | |
l.push(j.summary) | |
} | |
} | |
var n = (f) ? f.tz_offset_hours : 0; | |
var m = { | |
date: { | |
epoch: g / 1000 - n * 3600 | |
} | |
}; | |
var h = _.sortedIndex(l, m, function(i) { | |
return ((i || {}).date || {}).epoch | |
}); | |
p = l[h]; | |
return p | |
}, | |
getDayByCondition: function(g) { | |
var d = "%Y%m%d"; | |
var c = wui.date.strftime(d, g.date, true); | |
var f = this.getDays(); | |
var e = _.find(f, function(h) { | |
if (h.summary && h.summary.date) { | |
var i = wui.date.strftime(d, h.summary.date, true); | |
return ( c === i) | |
} else { | |
return false | |
} | |
}); | |
return e | |
}, | |
getDays: function() { | |
var c = this.models.weather.getDays(); | |
return c | |
}, | |
getFirstPlot: function() { | |
var c = this.getVisiblePlots(); | |
return c[0] || null | |
}, | |
getFittedDates: function(l) { | |
var d = this.status.get("zoomedIn"); | |
if (d) { | |
return null | |
} | |
var i = this.models.plotGroup.get("dayMaxWidth"); | |
if (!i) { | |
return null | |
} | |
var k = this.getFirstPlot(); | |
if (!k) { | |
return null | |
} | |
var c = k.getWidth() | |
, j = Math.floor(c / i) | |
, e = k.flot | |
, m = e.getAxes().xaxis; | |
var h = null; | |
if (l) { | |
var f = new Date((m.min + m.max) / 2); | |
h = wui.date.floor(f, "day"); | |
var g = Math.floor(j / 2); | |
wui.date.increment(h, -g, "day") | |
} else { | |
h = new Date(m.min) | |
} | |
var n = wui.date.create(j, "day", h); | |
this.validateDateRange(h, n); | |
return { | |
begin: h, | |
end: n | |
} | |
}, | |
getHours: function(d) { | |
var e = d.observations; | |
var c = d.hours; | |
if (e && e.length) { | |
return e | |
} else { | |
if (c && c.length) { | |
return c | |
} else { | |
return null | |
} | |
} | |
}, | |
getTimezone: function() { | |
return a.getTimezoneFromAPI(this.models.weather) | |
}, | |
getVisiblePlots: function() { | |
var c = []; | |
c = _.filter(this.plots, function(d) { | |
return d._visible | |
}); | |
return c | |
}, | |
getXAxisOptions: function() { | |
var g = {}; | |
var c = this.models.plotGroup.get("tickZoomPreset"); | |
var e = this.models.plotGroup.get("zoomable"); | |
var d = this.status.get("zoomedIn"); | |
if (e && c) { | |
var h = a.tickZoomPresets[c]; | |
var f = h.call(null, d); | |
b.extend(true, g, f) | |
} | |
return g | |
}, | |
onClick: function(c) { | |
this.dragend({ | |
event: c, | |
eventInitiator: "onClick" | |
}) | |
}, | |
onDraggingChange: function(d, e) { | |
if (e) { | |
var c = this.status.get("touching"); | |
if (!c) { | |
this.checkPosition({ | |
pos: null | |
}) | |
} | |
} else {} | |
}, | |
onMousedown: function(d) { | |
if (d.which === 1) { | |
this.status.set("mousedown", true); | |
var c = this.status.get("touching"); | |
if (!c) { | |
this.dragstart({ | |
event: d | |
}) | |
} | |
} | |
}, | |
onMouseleave: function(c) { | |
this.status.set("mousedown", false); | |
this.checkPosition({ | |
event: c, | |
pos: null | |
}) | |
}, | |
onMousemove: function(e) { | |
var d = this.status.get("mousedown"); | |
var c = this.status.get("touching"); | |
if (d) { | |
if (!c) { | |
this.dragmove({ | |
event: e | |
}) | |
} | |
} else { | |
var f = this.fromEventToFlotPos(e); | |
this.checkPosition({ | |
event: e, | |
pos: f | |
}); | |
this.checkNeedleDirection(e) | |
} | |
}, | |
onMouseup: function(c) { | |
this.status.set("mousedown", false) | |
}, | |
onPanLeft: function(c) { | |
c.stopPropagation(); | |
this.panLeft() | |
}, | |
onPanRight: function(c) { | |
c.stopPropagation(); | |
this.panRight() | |
}, | |
onPlotPan: function(c, d) { | |
this.synchronizePan(c, d) | |
}, | |
onRangeChange: function(c, d) { | |
if (d.complete) { | |
var e = (d.frame / d.elapsed * 1000).toFixed(1) | |
} | |
this.setNeedleNow() | |
}, | |
onResize: function(d) { | |
var c = this.models.plotGroup.get("dayMaxWidth"); | |
this.resize(); | |
if (c) { | |
this.fitDays() | |
} else { | |
this.drawPlots({ | |
setupGrid: false | |
}) | |
} | |
}, | |
onTimestampChange: function(h, l) { | |
var j = this.models.plotGroup.get("bufferLeft"); | |
var k = this.getFirstPlot() | |
, m = k.flot.getAxes() | |
, p = m.xaxis; | |
var e = k.flot.getPlotOffset(); | |
var c = this.status.get("translation"); | |
var i = this.status.get("needle.locked"); | |
if (this.$needle[0]) { | |
if (l === null) { | |
this.$needle.hide() | |
} else { | |
if (i) { | |
this.$needle.show() | |
} else { | |
this.$needle.show(); | |
var g = p.p2c(l) - j + e.left - this.$needle.width() / 2 + c.x; | |
this.status.set("needle.x", g); | |
a.translate(this.$needle, { | |
x: g | |
}) | |
} | |
} | |
} | |
if (!i) { | |
this.positionNeedleLabels(l) | |
} | |
var n = null; | |
var f = this.status.get("condition"); | |
var o = this.status.get("day"); | |
var d = this.status.get("needle.timer"); | |
if (!d) { | |
var q = this; | |
d = window.requestAnimationFrame(function() { | |
q.drawNeedleLabels({ | |
condition: f, | |
day: o, | |
selectedVariable: n, | |
timestamp: l | |
}); | |
q.status.set("needle.timer", null) | |
}); | |
this.status.set("needle.timer", d) | |
} | |
}, | |
onTouchstart: function(c) { | |
var e = c.originalEvent; | |
var d = e.changedTouches[0]; | |
this._scrollDirection = null; | |
this.status.set("touching", true); | |
this.dragstart({ | |
event: c, | |
currentTouch: d | |
}) | |
}, | |
onTouchmove: function(h) { | |
var j = h.originalEvent; | |
var i = j.changedTouches[0]; | |
var g = i.pageX; | |
var f = i.pageY; | |
var d = Math.abs(g - this._lasttouch.pageX); | |
var c = Math.abs(f - this._lasttouch.pageY); | |
var e = 3; | |
if (!this._scrollDirection) { | |
if (d > e || c > e) { | |
if (d > c) { | |
this._scrollDirection = "x" | |
} else { | |
this._scrollDirection = "y" | |
} | |
} | |
} | |
if (this._scrollDirection == "x") { | |
h.preventDefault(); | |
this.dragmove({ | |
event: h, | |
currentTouch: i | |
}) | |
} | |
this._lasttouch.pageX = g; | |
this._lasttouch.pageY = f | |
}, | |
onTouchend: function(c) { | |
this.status.set("touching", false); | |
this.checkNeedleLabels() | |
}, | |
onTouchcancel: function(c) { | |
this.status.set("touching", false); | |
this.dragend({ | |
event: c | |
}); | |
this.checkNeedleLabels() | |
}, | |
onTranslateChange: function(c, d) { | |
this.setNeedleNow() | |
}, | |
onVariablesChange: function() { | |
this.checkPrecip() | |
}, | |
onWeatherChange: function(c) { | |
if (_.has(c.changed, "forecast") || _.has(c.changed, "history")) { | |
this.render() | |
} | |
}, | |
onZoomedInChange: function(c, d) { | |
this.setZoomButtons(d); | |
this.drawPlots() | |
}, | |
onZoomIn: function(c) { | |
this.zoomIn({ | |
animate: this._animateZoom, | |
eventInitiator: "onZoomIn" | |
}) | |
}, | |
onZoomOut: function(c) { | |
this.zoomOut({ | |
animate: this._animateZoom, | |
eventInitiator: "onZoomOut" | |
}) | |
}, | |
pan: function(c) { | |
c = b.extend({ | |
amount: 1, | |
animate: false, | |
plot: null, | |
smooth: false | |
}, c); | |
var f = c.plot; | |
if (!f) { | |
f = this.getFirstPlot(); | |
if (!f) { | |
return null | |
} | |
} | |
var e = this.getViewportDates(); | |
var j = (e.end - e.begin) * c.amount | |
, d = new Date(e.begin.getTime() + j) | |
, l = new Date(e.end.getTime() + j); | |
this.validateDateRange(d, l); | |
if (c.smooth && c.animate) { | |
var g = f.flot.getAxes() | |
, i = g.xaxis; | |
var m = i.p2c(d.getTime()) - i.p2c(e.begin.getTime()); | |
this.recenter(); | |
var k = this; | |
_.defer(function() { | |
var n = k.models.plotGroup.get("panDuration"); | |
k.status.set("transition.duration", n); | |
k.status.set("translation.x", -m); | |
if (n) { | |
window.setTimeout(function() { | |
k.status.set("transition.duration", 0); | |
k.checkNeedleLabels() | |
}, n) | |
} | |
}) | |
} else { | |
var h = this.fromViewportToBufferedDates(d, l); | |
this.synchronizeZoom(f, h.begin, h.end, c.animate) | |
} | |
}, | |
panLeft: function() { | |
this.pan({ | |
animate: true, | |
amount: -1, | |
smooth: true | |
}) | |
}, | |
panRight: function() { | |
this.pan({ | |
animate: true, | |
amount: 1, | |
smooth: true | |
}) | |
}, | |
positionNeedleLabels: function(d) { | |
for (var c = 0; c < this.plots.length; c++) { | |
var e = this.plots[c]; | |
e.positionNeedleLabels({ | |
timestamp: d | |
}) | |
} | |
}, | |
recenter: function(d) { | |
if (!d && d !== 0) { | |
d = this.status.get("translation.x") | |
} | |
var g = this.getFirstPlot() | |
, f = g.flot.getAxes() | |
, h = f.xaxis; | |
var e = h.c2p(h.p2c(h.min) - d) | |
, c = h.c2p(h.p2c(h.max) - d); | |
this.setRangeX(e, c); | |
if (this._touchstart.translation) { | |
this._touchstart.translation.x = 0 | |
} | |
this.status.set("translation.x", 0); | |
this.setNeedleNow() | |
}, | |
render: function() { | |
if (this._numRenders < 1) { | |
this.initializeAtFirstRender(); | |
this.resize() | |
} | |
this.checkRangeOptions(); | |
var c = this.checkDayPartsOnly(); | |
this.status.set("dayPartsOnly", c); | |
this.drawPlots({ | |
astronomy: true, | |
fitRangeY: true | |
}); | |
this._numRenders++; | |
var f = this.models.plotGroup.get("dayMaxWidth"); | |
if (f && this._numRenders <= 1) { | |
this.fitDays() | |
} | |
if (this._numRenders <= 1) { | |
this._now = new Date(); | |
var g = this.getTimezone() | |
, e = a.getTimestamp(this._now, g) | |
, h = new Date(e); | |
this.checkPosition({ | |
date: h | |
}); | |
this.setNeedleNow() | |
} | |
this.checkStorm(); | |
this.$el.addClass("loaded"); | |
return this | |
}, | |
resize: function() { | |
var d = this.$el.is(":visible"); | |
if (!d) { | |
return | |
} | |
var c = this.getVisiblePlots(); | |
_.each(c, function(e) { | |
e.resize() | |
}) | |
}, | |
checkStorm: function() { | |
if (wui.bootstrapped.citypage) { | |
var d = this.status.get("zoomedIn"); | |
var f = wui.bootstrapped.citypage.storm; | |
for (var e in f) { | |
var c = ".flot-header .col-" + e + "T000000"; | |
var g = "has-alert"; | |
if (f[e].type === "blizzard") { | |
g += " has-blizzard" | |
} | |
if (b(c).length) { | |
if (d) { | |
b(c).removeClass(g) | |
} else { | |
b(c).addClass(g) | |
} | |
} | |
} | |
} | |
}, | |
setNeedleNow: function() { | |
if (!this.$needleNow || !this.$needleNow[0]) { | |
return | |
} | |
var h = this.getTimezone() | |
, m = a.getTimestamp(this._now, h) | |
, j = new Date(m); | |
var g = this.models.plotGroup.get("bufferLeft"); | |
var i = this.getFirstPlot() | |
, k = i.flot.getAxes() | |
, l = k.xaxis; | |
var e = i.flot.getPlotOffset(); | |
var c = this.status.get("translation"); | |
var f = l.p2c(m) - g + e.left - this.$needleNow.width() / 2 + c.x; | |
a.translate(this.$needleNow, { | |
x: f | |
}) | |
}, | |
setRangeX: function(e, c) { | |
for (var d = 0; d < this.plots.length; d++) { | |
var f = this.plots[d]; | |
f.setRangeX(e, c) | |
} | |
}, | |
setStatusRange: function(c) { | |
c = b.extend({ | |
complete: false, | |
elapsed: 0, | |
fraction: 0, | |
frame: 0, | |
min: 0, | |
max: 0 | |
}, c); | |
this.status.set({ | |
range: c | |
}) | |
}, | |
setZoomButtons: function(d) { | |
if (typeof d == "undefined") { | |
d = this.status.get("zoomedIn") | |
} | |
var c = this.$el.find(".plot-zoom-daily"); | |
var e = this.$el.find(".plot-zoom-hourly"); | |
var f = this.models.plotGroup.get("classNames"); | |
c.toggleClass(f.selected, !d); | |
e.toggleClass(f.selected, !!d) | |
}, | |
synchronizePan: function(c, g) { | |
for (var d = 0; d < this.plots.length; d++) { | |
if (c === d) { | |
continue | |
} | |
var f = this.plots[d]; | |
if (f) { | |
var e = b.extend({}, g, { | |
preventEvent: true | |
}); | |
f.flot.pan(e) | |
} | |
} | |
this.checkStorm() | |
}, | |
synchronizeZoom: function(i, e, d, c, h) { | |
var j = e.getTime() | |
, g = d.getTime(); | |
if (c) { | |
var f = this.models.plotGroup.get("zoomDuration"); | |
this.animateRangeX(j, g, f, i, h) | |
} else { | |
this.setRangeX(j, g); | |
if (h) { | |
h() | |
} | |
} | |
this.checkStorm() | |
}, | |
translate: function(c) { | |
for (var d = 0; d < this.plots.length; d++) { | |
var e = this.plots[d]; | |
e.translate(c) | |
} | |
}, | |
updateDates: function(c, e) { | |
for (var d in e) { | |
this.plots.setAdded(d) | |
} | |
}, | |
validateDateRange: function(e, d) { | |
var f = this.models.plotGroup.get("date_min"), c = this.models.plotGroup.get("date_max"), g; | |
if (f && e < f) { | |
g = f - e; | |
e.setTime(f.getTime()); | |
d.setTime(d.getTime() + g) | |
} | |
if (c && d > c) { | |
g = d - c; | |
e.setTime(e.getTime() - g); | |
d.setTime(c.getTime()) | |
} | |
if (f && e < f) { | |
e.setTime(f.getTime()) | |
} | |
if (c && d > c) { | |
d.setTime(c.getTime()) | |
} | |
}, | |
zoomCheck: function() { | |
this.undelegateEvents() | |
}, | |
zoomIn: function(c) { | |
this.zoomCheck(); | |
c = b.extend({ | |
animate: false, | |
d: null, | |
eventInitiator: "zoomIn", | |
plot: null | |
}, c); | |
var l = this | |
, h = c.plot | |
, i = c.d; | |
if (!h) { | |
var h = this.getFirstPlot(); | |
if (!h) { | |
return null | |
} | |
} | |
if (!i) { | |
var g = this.getViewportDates(); | |
i = g.begin | |
} | |
this.setZoomButtons(true); | |
var e = function() { | |
var d = { | |
d: i, | |
eventInitiator: c.eventInitiator | |
}; | |
l.status.set("zoomedIn", true, d); | |
l.recenter(); | |
l.checkNeedleLabels(); | |
l.checkStorm() | |
}; | |
var f = wui.date.roundDownTo(i, 1, "day") | |
, k = wui.date.roundUpTo(i, 1, "day"); | |
var j = this.fromViewportToBufferedDates(f, k); | |
this.synchronizeZoom(h, j.begin, j.end, c.animate, e); | |
this.checkStorm() | |
}, | |
zoomOut: function(c) { | |
this.zoomCheck(); | |
c = b.extend({ | |
animate: false, | |
eventInitiator: "zoomOut", | |
plot: null | |
}, c); | |
var k = this; | |
var h = c.plot; | |
if (!h) { | |
var h = this.getFirstPlot(); | |
if (!h) { | |
return null | |
} | |
} | |
this.setZoomButtons(false); | |
var f = { | |
eventInitiator: c.eventInitiator | |
}; | |
this.status.set("zoomedIn", false, f); | |
this.recenter(); | |
var d = function() { | |
k.checkNeedleLabels(); | |
k.checkStorm() | |
}; | |
var g = this.models.plotGroup.get("dayMaxWidth"); | |
if (g) { | |
var i = true; | |
this.fitDays(c.animate, i, d) | |
} else { | |
var l = this.models.plotGroup.get("date_min") | |
, e = this.models.plotGroup.get("date_max"); | |
var j = this.fromViewportToBufferedDates(l, e); | |
this.synchronizeZoom(h, j.begin, j.end, c.animate, d) | |
} | |
this.checkStorm() | |
} | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Views.Plot = Backbone.View.extend({ | |
initialize: function(d) { | |
this.options = d || {}; | |
this.status = this.options.status; | |
this.models = this.options.models || {}; | |
this.setOptions(d); | |
this.flot = null; | |
this.flotOptions = null; | |
this.legend = null; | |
this._needleLabels = []; | |
this._visible = true; | |
this.templateHeaderDaily = _.template(b("script#plotgroup-header-daily-template").html()); | |
this.templateHeaderHourly = _.template(b("script#plotgroup-header-hourly-template").html()); | |
this.checkVariablesEnabled(); | |
var c = this.getPlotOptions(); | |
var j = c.variables; | |
var f = "plots[" + this.options.plotIndex + "]"; | |
for (var e = 0; e < j.length; e++) { | |
this.listenTo(this.models.plotGroup, "change:" + f + ".variables[" + e + "]", this.onVariableChange) | |
} | |
this.listenTo(this.status, "change:dayPartsOnly", this.onDayPartsOnlyChange); | |
this.listenTo(this.status, "change:transition", this.onTransitionChange); | |
this.listenTo(this.status, "change:translation", this.onTranslateChange); | |
this.listenTo(this.status, "change:zoomedIn", this.onZoomedInChange); | |
this.createFlot(); | |
this.createNeedleLabels(); | |
if (c.legends === true) { | |
this.createLegend() | |
} else { | |
if (c.legends === false) {} else { | |
if (this.models.plotGroup.get("legends") === false) {} else { | |
this.createLegend() | |
} | |
} | |
} | |
var g = this.isHeader(); | |
if (g) { | |
var h = this.models.plotGroup.get("classNames"); | |
this.$el.addClass(h.header) | |
} | |
this.translate({ | |
x: 0, | |
y: 0, | |
z: 0 | |
}) | |
}, | |
animateRangeY: function(h, m, g, f) { | |
var n = this; | |
var c = null; | |
var l = this.flot.getAxes().yaxis | |
, d = l.min | |
, k = l.max | |
, j = (window.performance && window.performance.now) ? window.performance.now() : null; | |
var i = 0; | |
function e(t) { | |
if (j === null) { | |
j = t | |
} | |
i++; | |
var q = t - j; | |
var s = q / g; | |
var p = false; | |
if (s > 1) { | |
s = 1; | |
p = true | |
} | |
var r = d + s * (h - d); | |
var o = k - s * (k - m); | |
n.setRangeY(r, o); | |
if (p) { | |
if (f) { | |
f() | |
} | |
} else { | |
c = requestAnimationFrame(e) | |
} | |
} | |
c = requestAnimationFrame(e); | |
return c | |
}, | |
checkVariablesEnabled: function() { | |
var d = this.status.get("dayPartsOnly"); | |
var c = this.getPlotOptions(); | |
var k = c.variables; | |
var h = "plots[" + this.options.plotIndex + "]"; | |
var j = { | |
dayPartsOnly: d | |
}; | |
for (var g = 0; g < k.length; g++) { | |
var f = k[g]; | |
if (b.isFunction(f.enableWhen)) { | |
var e = f.enableWhen(j); | |
this.models.plotGroup.set(h + ".variables[" + g + "].enabled", e) | |
} | |
} | |
}, | |
createFlot: function() { | |
var f = []; | |
var e = this.models.plotGroup.attributes; | |
var k = this.getPlotOptions(); | |
var g = b.extend(true, {}, this.options.flot, e.flot, k.flot); | |
this.flotOptions = g; | |
var l = { | |
draw: [] | |
}; | |
var d = this.isHeader(); | |
if (d) { | |
l.draw.push(b.proxy(this.drawHeader, this)) | |
} | |
b.extend(true, g, { | |
hooks: l | |
}); | |
var h = this.models.plotGroup.get("bufferLeft"); | |
var j = this.models.plotGroup.get("bufferRight"); | |
if (h || j) { | |
this.$el.css({ | |
"margin-left": -h, | |
"margin-right": -j | |
}) | |
} | |
this.flot = b.plot(this.$el, f, g); | |
if (h || j) { | |
this.$el.children(".flot-text").css({ | |
left: h, | |
right: j | |
}) | |
} | |
if (k.freezeline) { | |
var i = this.getFreezelineMarkings(); | |
var c = this.flot.getOptions().grid; | |
if (c.markings && b.isArray(c.markings)) { | |
c.markings = i.concat(c.markings) | |
} else { | |
c.markings = i | |
} | |
} | |
}, | |
createLegend: function() { | |
if (!wui.Views.PlotLegend) { | |
return | |
} | |
var c = b("<div />"); | |
this.legend = new wui.Views.PlotLegend({ | |
model: this.model, | |
models: { | |
plotGroup: this.models.plotGroup, | |
weather: this.models.weather | |
}, | |
el: c[0], | |
plotIndex: this.options.plotIndex | |
}); | |
c.insertAfter(this.$el) | |
}, | |
createNeedleLabel: function(d) { | |
var e = this.flot.getOptions().needle; | |
var c = b("<div />").addClass(e.classNames.label); | |
if (d) { | |
c.css({ | |
color: d.textColor || d.color || d.options.color, | |
}) | |
} | |
return c | |
}, | |
createNeedleLabels: function(g) { | |
g = b.extend({}, g); | |
if (!this.flot.needle) { | |
return | |
} | |
var d = this.getPlotOptions(); | |
var k = d.variables; | |
var j = this._needleLabels; | |
var h = this.isHeader(); | |
if (h) { | |
var c = this.createNeedleLabel(); | |
j.push({ | |
top: 0, | |
node: c | |
}); | |
this.flot.needle.addLabel(c) | |
} | |
for (var f = 0; f < k.length; f++) { | |
var e = k[f]; | |
var c = this.createNeedleLabel(e); | |
j.push({ | |
top: 0, | |
node: c, | |
variableIndex: f | |
}); | |
this.flot.needle.addLabel(c) | |
} | |
}, | |
draw: function(e) { | |
var g = this.getFlotData(); | |
var c = (g.length > 0); | |
var f = this.isHeader(); | |
if (!c && f) { | |
var d = []; | |
this.setFlotData([d]); | |
this.drawFlot(e); | |
c = true | |
} else { | |
this.setFlotData(g); | |
this.drawFlot(e) | |
} | |
this._visible = c; | |
this.$el.toggle(c) | |
}, | |
drawFlot: function(d) { | |
d = b.extend(true, { | |
astronomy: false, | |
date: null, | |
fitRangeY: false, | |
setupGrid: false, | |
xaxisOptions: null | |
}, d); | |
var f = this.models.plotGroup.attributes; | |
var r = this.getPlotOptions(); | |
var j = this.getTimezone(); | |
var p = b.extend(true, {}, f, r); | |
if (d.setupGrid) { | |
var o = this.flot.getAxes().xaxis; | |
if (d.date) { | |
var s = wui.date.roundDownTo(d.date, 1, "day"); | |
var e = wui.date.roundUpTo(d.date, 1, "day"); | |
o.options.min = s.getTime(); | |
o.options.max = e.getTime() | |
} | |
if (p.flot && p.flot.xaxis) { | |
b.extend(o.options, p.flot.xaxis) | |
} | |
if (d.xaxisOptions) { | |
b.extend(o.options, d.xaxisOptions) | |
} | |
if (d.fitRangeY && r.autoscale) { | |
var l = this.flot.getAxes().yaxis; | |
var i = { | |
min: null, | |
max: null | |
}; | |
var g = this.models.plotGroup.get("bufferLeft"); | |
var k = this.models.plotGroup.get("bufferRight"); | |
if (g || k) { | |
i = this.getVisibleDataminDatamax() | |
} | |
if (i.min === null) { | |
i.min = l.datamin | |
} | |
if (i.max === null) { | |
i.max = l.datamax | |
} | |
this.padRangeY(i, l); | |
b.extend(l.options, i) | |
} | |
if (d.astronomy) { | |
var n = b.extend(true, {}, f.astronomy, r.astronomy); | |
if (n) { | |
var m = n.markings; | |
if (m && m.show) { | |
var q = this.models.weather.get("astronomy.days"); | |
var h = a.getAstronomyMarkings(q, m, j); | |
var c = this.flot.getOptions().grid; | |
if (c.markings && b.isArray(c.markings)) { | |
c.markings = h.concat(c.markings) | |
} else { | |
c.markings = h | |
} | |
} | |
} | |
} | |
this.flot.setupGrid() | |
} | |
this.flot.draw() | |
}, | |
drawHeader: function(e, c) { | |
var f = this.models.weather.get("forecast.days"); | |
if (!f) { | |
return | |
} | |
var d = this.status.get("zoomedIn"); | |
if (d) { | |
this.drawHeaderHourly() | |
} else { | |
this.drawHeaderDaily() | |
} | |
this.drawHeaderAstronomy(e) | |
}, | |
drawHeaderDaily: function() { | |
var j = this.getTimezone(); | |
var n = this.templateHeaderDaily; | |
var o = this.models.weather.get("forecast.days"); | |
var h = this.models.weather.get("labels"); | |
var k = this.models.weather.get("response.units"); | |
var c = this.models.weather.get("forecast.source"); | |
var d = { | |
iconset: this.model.get("iconset"), | |
labels: h, | |
source: c, | |
units: k, | |
zoomedIn: this.status.get("zoomedIn") | |
}; | |
for (var g = 0, f = o.length; g < f; g++) { | |
var m = o[g]; | |
var e = m.summary; | |
this.drawHeaderCondition(e, j, n, d) | |
} | |
}, | |
drawHeaderHourly: function() { | |
var k = this.getTimezone(); | |
var o = this.templateHeaderHourly; | |
var p = this.models.weather.get("forecast.days"); | |
var h = this.models.weather.get("labels"); | |
var c = { | |
iconset: this.model.get("iconset"), | |
labels: h, | |
zoomedIn: this.status.get("zoomedIn") | |
}; | |
for (var g = 0, e = p.length; g < e; g++) { | |
var m = p[g]; | |
var n = m.hours; | |
for (var f = 0; f < n.length; f++) { | |
var d = n[f]; | |
this.drawHeaderCondition(d, k, o, c) | |
} | |
} | |
}, | |
drawHeaderCondition: function(e, h, m, c) { | |
var i = a.getTimestamp(e, h); | |
var j = new Date(i); | |
if (!c.zoomedIn) { | |
j = wui.date.floor(j, "day") | |
} | |
var k = "col-" + wui.date.strftime("%Y%m%dT%H0000", j, true); | |
var l = this.$el.find("." + k).find(".col-body"); | |
if (l[0]) { | |
var g = { | |
condition: e, | |
labels: c.labels, | |
opts: c | |
}; | |
var f = m(g); | |
l.html(f) | |
} | |
}, | |
drawHeaderAstronomy: function(f) { | |
var f = f || this.flot; | |
var s = f.getAxes() | |
, e = s.xaxis; | |
var q = this.$el.find(".flot-header"); | |
var g = this.models.weather.get("astronomy.days"); | |
if (!g) { | |
return | |
} | |
var o = this.getTimezone(); | |
var y = this.status.get("zoomedIn"); | |
var v = true | |
, x = true | |
, j = true | |
, n = (y); | |
for (var u = 0, p = g.length; u < p; u++) { | |
var r = g[u]; | |
var c = null | |
, k = "" | |
, h = "" | |
, w = null | |
, m = 0; | |
if (v) { | |
w = new Date(r.sunrise.date.epoch * 1000); | |
m = a.getTimestamp(w, o); | |
w.setTime(m); | |
if (m > e.min && m < e.max) { | |
k = ""; | |
if (j) { | |
k += '<div class="icon-sunrise"></div>' | |
} | |
if (n) { | |
h = wui.date.strftime("%l:%M%P", w, true); | |
k += '<div class="icon-label">' + h + "</div>" | |
} | |
c = b("<div>" + k + "</div>").addClass("astronomy-marker sunrise").css({ | |
left: e.p2c(m) | |
}).appendTo(q) | |
} | |
} | |
if (x) { | |
w = new Date(r.sunset.date.epoch * 1000); | |
m = a.getTimestamp(w, o); | |
w.setTime(m); | |
if (m > e.min && m < e.max) { | |
k = ""; | |
if (j) { | |
k += '<div class="icon-sunset"></div>' | |
} | |
if (n) { | |
h = wui.date.strftime("%l:%M%P", w, true); | |
k += '<div class="icon-label">' + h + "</div>" | |
} | |
c = b("<div>" + k + "</div>").addClass("astronomy-marker sunset").css({ | |
left: e.p2c(m) | |
}).appendTo(q) | |
} | |
} | |
} | |
}, | |
fitRangeY: function(i) { | |
var d = this.getPlotOptions(); | |
if (!d.autoscale) { | |
if (i) { | |
i() | |
} | |
return | |
} | |
var h = this.models.plotGroup.get("fitDuration"); | |
var f = this.flot.getAxes().yaxis; | |
var g = this.getVisibleDataminDatamax(); | |
if (g.min === null) { | |
g.min = f.datamin | |
} | |
if (g.max === null) { | |
g.max = f.datamax | |
} | |
this.padRangeY(g, f); | |
var e = g.min | |
, c = g.max; | |
this.animateRangeY(e, c, h, i) | |
}, | |
fromConditionsToFlot: function(e, p, k, r) { | |
var f = []; | |
var m = (p.options.text && p.options.text.show); | |
var z = (p.options.rotatedmarker && p.options.rotatedmarker.show); | |
var u = b.isFunction(k); | |
var w = b.isFunction(p.filter); | |
var j = this.status.get("dayPartsOnly"); | |
var c = (m) ? p.options.text.y : 0; | |
var A = (z) ? p.options.rotatedmarker.id : null; | |
var n = this.getTimezone(); | |
for (var s = 0, o = e.length; s < o; s++) { | |
var t = e[s]; | |
var h = a.getTimestamp(t, n); | |
var g = 0; | |
var B = ""; | |
if (u) { | |
B = k.call(null, t) | |
} else { | |
B = t[k] | |
} | |
if (w) { | |
var d = p.filter.call(null, t, { | |
dayPartsOnly: j | |
}); | |
if (!d) { | |
B = null | |
} | |
} | |
if (m) { | |
g = c; | |
f.push([h, g, B]) | |
} else { | |
if (z) { | |
g = a.isValidMeasurement(B) ? parseFloat(B) : null; | |
var v = null; | |
if (_.isNumber(t[A])) { | |
var q = parseFloat(t[A]); | |
v = q / 180 * Math.PI | |
} | |
f.push([h, g, v]) | |
} else { | |
g = a.isValidMeasurement(B) ? parseFloat(B) : null; | |
f.push([h, g]) | |
} | |
} | |
} | |
return f | |
}, | |
getFlotData: function() { | |
var c = this.getPlotOptions(); | |
var j = []; | |
var k = _.reject(c.variables, function(i) { | |
return ( i.show === false || i.enabled === false) | |
}); | |
var h = this.models.weather.get("forecast.source"); | |
if (h == "nws") { | |
k = _.reject(k, function(i) { | |
return i.missingFromNWS | |
}) | |
} | |
for (var g = 0; g < k.length; g++) { | |
var d = k[g]; | |
var f = this.getFlotSeriesData(d); | |
var e = b.extend(true, {}, d.options, { | |
data: f | |
}); | |
j.push(e) | |
} | |
return j | |
}, | |
getFlotSeriesData: function(f) { | |
var e = this.models.weather; | |
var c = []; | |
var d = null; | |
var h = false; | |
var k = []; | |
d = f.id; | |
var m = e.get("history.days"); | |
if (m) { | |
for (var g = 0; g < m.length; g++) { | |
var j = m[g]; | |
k = this.getHours(j); | |
if (k && k.length && d) { | |
var l = []; | |
l = this.fromConditionsToFlot(k, f, d, j); | |
c = c.concat(l) | |
} | |
} | |
} | |
var m = e.get("forecast.days"); | |
if (m) { | |
for (var g = 0; g < m.length; g++) { | |
var j = m[g]; | |
k = this.getHours(j); | |
if (k && k.length && d && !h) { | |
var l = []; | |
l = this.fromConditionsToFlot(k, f, d, j); | |
c = c.concat(l) | |
} | |
} | |
} | |
return c | |
}, | |
getFreezelineMarkings: function() { | |
var d = this.models.weather.get("response.units"); | |
var e = (d == "metric") ? 0 : 32; | |
var c = [{ | |
yaxis: { | |
from: e, | |
to: e | |
}, | |
color: "#6697cc", | |
lineWidth: 1 | |
}]; | |
return c | |
}, | |
getHours: function(d) { | |
var e = d.observations; | |
var c = d.hours; | |
if (e && e.length) { | |
return e | |
} else { | |
if (c && c.length) { | |
return c | |
} else { | |
if (d.summary) { | |
return [d.summary] | |
} else { | |
return null | |
} | |
} | |
} | |
}, | |
getPlotOptions: function() { | |
var d = "plots[" + this.options.plotIndex + "]"; | |
var c = this.models.plotGroup.get(d); | |
return c | |
}, | |
getTimezone: function() { | |
return a.getTimezoneFromAPI(this.models.weather) | |
}, | |
getVariableValue: function(g, h, j, l) { | |
var d = false; | |
var f = ""; | |
var i = false; | |
var m = ["aqozone", "aqpm25", "aqpm10", "aqso2", "aqco", "aqno2"]; | |
i = (j && j.id == h.id); | |
if (g.hasOwnProperty(h.id)) { | |
d = true; | |
f = g[h.id] | |
} | |
if (f && (b.inArray(h.id, m) > -1)) { | |
f = Number.parseFloat(f).toFixed(1) | |
} | |
if (d) { | |
var c = b.isFunction(h.filter); | |
if (c) { | |
var k = this.status.get("dayPartsOnly"); | |
var e = h.filter.call(null, g, { | |
dayPartsOnly: k | |
}); | |
if (!e) { | |
d = false | |
} | |
} | |
} | |
if (d) { | |
return { | |
selected: i, | |
valid: d, | |
value: f | |
} | |
} else { | |
return null | |
} | |
}, | |
getVisibleDataminDatamax: function() { | |
var E = Number.POSITIVE_INFINITY | |
, w = Number.NEGATIVE_INFINITY | |
, g = Number.MAX_VALUE; | |
var v = this.flot.getData(); | |
var J, G, D; | |
var O, d, M; | |
var p = E | |
, r = w; | |
var o = this.flot | |
, I = o.getAxes() | |
, l = I.xaxis; | |
var e = l.min | |
, h = l.max; | |
var N = this.models.plotGroup.get("bufferLeft"); | |
var u = this.models.plotGroup.get("bufferRight"); | |
if (N || u) { | |
var c = o.width() | |
, x = h - e; | |
var P = N / c | |
, n = u / c; | |
e = (e + P * x); | |
h = (h - n * x) | |
} | |
var t = this.status.get("translation"); | |
if (t.x) { | |
var A = l.c2p(t.x) - l.c2p(0); | |
e -= A; | |
h -= A | |
} | |
for (J = 0; J < v.length; ++J) { | |
var y = v[J] | |
, H = y.datapoints.points | |
, C = y.datapoints.pointsize | |
, L = y.datapoints.format; | |
var z = E | |
, F = E | |
, B = w | |
, K = w; | |
var k = 0 | |
, q = 0; | |
for (G = 0; G < L.length; ++G) { | |
M = L[G]; | |
if (!M) { | |
continue | |
} | |
if (M.x) { | |
k = G | |
} | |
if (M.y) { | |
q = G | |
} | |
} | |
for (G = 0; G < H.length; G += C) { | |
if (H[G] == null) { | |
continue | |
} | |
O = H[G + k]; | |
d = H[G + q]; | |
if (d == g || d == -g) { | |
continue | |
} | |
if (O < e || O > h) { | |
continue | |
} | |
if (d < F) { | |
F = d | |
} | |
if (d > K) { | |
K = d | |
} | |
} | |
if (F < p && F != -g) { | |
p = F | |
} | |
if (K > r && K != g) { | |
r = K | |
} | |
} | |
if (p == E) { | |
p = null | |
} | |
if (r == w) { | |
r = null | |
} | |
return { | |
min: p, | |
max: r | |
} | |
}, | |
getWidth: function() { | |
var d = this.models.plotGroup.get("bufferLeft"); | |
var c = this.models.plotGroup.get("bufferRight"); | |
return this.flot.width() - d - c | |
}, | |
hideNeedleLabels: function() { | |
var f = this._needleLabels; | |
for (var e = 0; e < f.length; e++) { | |
var d = f[e]; | |
var c = d.node; | |
c.css("opacity", 0) | |
} | |
}, | |
isHeader: function() { | |
var c = this.flotOptions.datelabel; | |
return !!(c && c.show) | |
}, | |
onDayPartsOnlyChange: function(d, c) { | |
this.checkVariablesEnabled() | |
}, | |
onTranslateChange: function(c, d) { | |
this.translate(d) | |
}, | |
onTransitionChange: function(c, d) { | |
this.setTransitionDuration(d.duration) | |
}, | |
onVariableChange: function(c, g) { | |
var f = { | |
setupGrid: true | |
}; | |
this.draw(f); | |
var e = function() { | |
this.updateNeedleLabels({ | |
condition: this.status.get("condition"), | |
day: this.status.get("day"), | |
mode: this.models.plotGroup.get("mode"), | |
selectedVariable: null, | |
timestamp: this.status.get("timestamp") | |
}) | |
}; | |
var d = _.bind(e, this); | |
this.fitRangeY(d); | |
this.setVariablePref(g) | |
}, | |
onZoomedInChange: function(c, d) { | |
var e = this.flot.getOptions().datelabel; | |
if (e) { | |
e.hourly = !!d | |
} | |
}, | |
padRangeY: function(g, d) { | |
var l = this.getPlotOptions(); | |
var f = g.min | |
, h = g.max; | |
var c = d.options | |
, j = h - f; | |
var e = 0; | |
var k = d.box.height; | |
var i = l.reserveSpace; | |
if (i && b.isArray(i) && i.length >= 2) { | |
if (i[0]) { | |
e = i[0] / k; | |
f -= j * e; | |
if (f < 0 && d.datamin != null && d.datamin >= 0) { | |
f = 0 | |
} | |
} | |
if (i[1]) { | |
e = i[1] / k; | |
h += j * e; | |
if (h > 0 && d.datamax != null && d.datamax <= 0) { | |
h = 0 | |
} | |
} | |
} | |
g.min = f; | |
g.max = h | |
}, | |
positionNeedleLabels: function(c) { | |
c = b.extend({ | |
timestamp: null | |
}, c); | |
var d = this.status.get("translation"); | |
this.flot.needle.position({ | |
translation: d, | |
x: c.timestamp, | |
y: 0 | |
}) | |
}, | |
render: function() { | |
return this | |
}, | |
resize: function() { | |
this.flot.resize(); | |
this.flot.setupGrid() | |
}, | |
setFlotData: function(c) { | |
this.flot.setData(c) | |
}, | |
setOptions: function(c) { | |
var d = { | |
astronomy: { | |
markings: { | |
show: false, | |
dayColor: "transparent", | |
nightColor: "#f4f4f4" | |
} | |
}, | |
flot: { | |
crosshair: { | |
mode: "x" | |
}, | |
grid: { | |
autoHighlight: false, | |
borderColor: "#e8e8e9", | |
borderWidth: 1, | |
color: "#8e8f91", | |
hoverable: true | |
}, | |
series: { | |
bars: { | |
show: false | |
}, | |
lines: { | |
show: true | |
}, | |
points: { | |
show: false | |
}, | |
images: { | |
show: false | |
} | |
}, | |
xaxis: { | |
mode: "time" | |
}, | |
yaxis: { | |
labelWidth: 30, | |
panRange: false, | |
reserveSpace: true, | |
zoomRange: false | |
}, | |
yaxes: [{}, { | |
tickLength: "full", | |
position: "right" | |
}] | |
} | |
}; | |
this.options = b.extend(true, d, this.options, c); | |
if (c.date_begin) { | |
this.options.flot.xaxis.min = c.date_begin.getTime() | |
} | |
if (c.date_end) { | |
this.options.flot.xaxis.max = c.date_end.getTime() | |
} | |
}, | |
setPanRange: function(o, e) { | |
if (!this.flot) { | |
return | |
} | |
if (o || e) { | |
var c = o; | |
var i = e; | |
var m = this.flot.getAxes().xaxis; | |
var g = this.models.plotGroup.get("bufferLeft"); | |
var k = this.models.plotGroup.get("bufferRight"); | |
if (g || k) { | |
if (o) { | |
var j = o.getTime(); | |
var f = m.p2c(j) - g; | |
j = m.c2p(f); | |
c = new Date(j) | |
} | |
if (e) { | |
var n = e.getTime(); | |
var l = m.p2c(n) + k; | |
n = m.c2p(l); | |
i = new Date(n) | |
} | |
} | |
var d = m.options.panRange; | |
var h; | |
if (b.isArray(d) && d.length == 2) { | |
h = [d[0], d[1]] | |
} else { | |
h = [null, null] | |
} | |
if (c && b.type(c) == "date" && wui.date.isValid(c)) { | |
h[0] = c.getTime() | |
} | |
if (i && b.type(i) == "date" && wui.date.isValid(i)) { | |
h[1] = i.getTime() | |
} | |
m.options.panRange = h | |
} | |
}, | |
setRangeX: function(f, c) { | |
var d = this.getPlotOptions(); | |
var g = this.flot.getAxes().xaxis; | |
g.options.min = f; | |
g.options.max = c; | |
var e = "plot::setRangeX::draw index:" + this.options.plotIndex; | |
this.flot.setupGrid(); | |
this.flot.draw() | |
}, | |
setRangeY: function(d, c) { | |
var e = this.flot.getAxes().yaxis; | |
var f = { | |
min: d, | |
max: c | |
}; | |
e.options.min = f.min; | |
e.options.max = f.max; | |
this.flot.setupGrid(); | |
this.flot.draw() | |
}, | |
setTransitionDuration: function(d) { | |
var c = this.$el.find(".flot-base, .flot-header"); | |
a.setTransitionDuration(c, d) | |
}, | |
setVariablePref: function(e) { | |
var d = e.abbrev || e.id; | |
var c = (e.show !== false); | |
var f = "CP_VAR_" + d; | |
var g = c ? 1 : 0; | |
wui.prefs.set(f, g) | |
}, | |
translate: function(d) { | |
var c = this.$el.find(".flot-base, .flot-header"); | |
a.translate(c, d) | |
}, | |
updateNeedleLabels: function(m) { | |
m = b.extend({ | |
condition: null, | |
day: null, | |
mode: "forecast", | |
selectedVariable: null, | |
timestamp: null, | |
top: null, | |
value: "" | |
}, m); | |
if (!this.flot.needle) { | |
return | |
} | |
if (m.timestamp === null) { | |
return | |
} | |
var q = this.getPlotOptions(); | |
var f = q.variables; | |
var w = this.models.plotGroup.get("classNames"); | |
var v = this._needleLabels; | |
var u = []; | |
var c = 17; | |
var y = (m.mode == "forecast"); | |
var e = this.flot.getPlotOffset(); | |
var j = this.flot.getYAxes() | |
, t = null; | |
for (var s = 0; s < v.length; s++) { | |
var h = v[s]; | |
var r = null; | |
var l = h.variableIndex; | |
if (l || l === 0) { | |
r = f[l] | |
} | |
var z = h.node; | |
if (r && (r.show === false || r.enabled === false || r.needle === false)) { | |
z.css("opacity", 0); | |
continue | |
} | |
var p = ""; | |
var d = ""; | |
var k = ""; | |
var o = false; | |
if (m.value) { | |
p = m.value | |
} else { | |
if (!r) { | |
p = m.value | |
} else { | |
var x = this.getVariableValue(m.condition, r, m.selectedVariable, y); | |
if (!x || !x.valid) { | |
z.css("opacity", 0); | |
continue | |
} | |
p = x.value; | |
d = ""; | |
k = a.getVariableUnits(r, m.condition, m.day); | |
o = x.selected | |
} | |
} | |
if (p === null) { | |
z.css("opacity", 0); | |
continue | |
} | |
z.css("opacity", 1); | |
u.push(h); | |
var n = 0; | |
if (m.top || m.top === 0 || !r) { | |
n = m.top | |
} else { | |
if (r.options && r.options.yaxis > 0) { | |
t = j[r.options.yaxis - 1] | |
} else { | |
t = j[0] | |
} | |
n = t.p2c(p) + e.top - c; | |
if (n < 0) { | |
n = 0 | |
} | |
} | |
h.top = n; | |
d = p + k; | |
z.html(d) | |
} | |
u.sort(function(A, i) { | |
return A.top - i.top | |
}); | |
var g = []; | |
for (var s = 0; s < u.length; s++) { | |
var h = u[s]; | |
var n = h.top; | |
if (g.length && n < g[g.length - 1] + c) { | |
n = g[g.length - 1] + c; | |
h.top = n; | |
g = []; | |
g.push(n) | |
} else { | |
g = []; | |
g.push(n) | |
} | |
} | |
for (var s = 0; s < u.length; s++) { | |
var h = u[s]; | |
var z = h.node; | |
a.translate(z, { | |
y: h.top | |
}) | |
} | |
} | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Views.PlotLegend = Backbone.View.extend({ | |
initialize: function(d) { | |
this.options = d || {}; | |
this.models = this.options.models || {}; | |
var c = b("script#plotgroup-legend-template"); | |
if (!c[0]) { | |
console.error("missing required PlotLegend template"); | |
return | |
} | |
this.template = _.template(c.html()); | |
var e = "plots[" + this.options.plotIndex + "]"; | |
this.listenTo(this.models.plotGroup, "change:" + e + ".variables", this.onVariablesChange); | |
var f = this.models.plotGroup.get("classNames"); | |
this.$el.addClass(f.legend); | |
this.render() | |
}, | |
onVariablesChange: function(c, d) { | |
this.render({ | |
variables: d | |
}) | |
}, | |
render: function(f) { | |
var i; | |
var e = ""; | |
if (f && f.variables) { | |
i = f.variables | |
} else { | |
var d = "plots[" + this.options.plotIndex + "]"; | |
i = this.models.plotGroup.get(d + ".variables") | |
} | |
var h = !!(i && i.length); | |
if (h && this.models.weather) { | |
var g = this.models.weather.get("forecast.source"); | |
if (g == "nws") { | |
i = _.reject(i, function(j) { | |
return j.missingFromNWS | |
}) | |
} | |
} | |
h = !!(i && i.length); | |
if (h) { | |
var c = { | |
variables: i | |
}; | |
e = this.template(c) | |
} | |
this.$el.html(e); | |
this.$el.toggle(h); | |
return this | |
}, | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Views.PlotVariablesMenu = Backbone.View.extend({ | |
events: { | |
click: "onClick", | |
opened: "onDropdownOpened", | |
closed: "onDropdownClosed" | |
}, | |
initialize: function(c) { | |
this.options = c || {}; | |
this.models = this.options.models || {}; | |
this.template = _.template(b("script#plotgroup-variables-menu-template").html()); | |
this.listenTo(this.models.plotGroup, "change:plots", this.onVariablesChange); | |
this.listenTo(this.models.plotGroup, "change:editMode", this.onEditMode); | |
this.render() | |
}, | |
onClick: function(e) { | |
var c = b(e.target); | |
var f = this.models.plotGroup.get("editMode"); | |
if (c.is(this.$editDone)) { | |
this.models.plotGroup.set("editMode", false) | |
} else { | |
if (c.is("input[type=checkbox]")) { | |
var d = c[0].checked; | |
var g = c.attr("data-variable-id"); | |
if (f) { | |
this.toggleVariable(g, d) | |
} | |
} | |
} | |
if (!f) { | |
e.preventDefault() | |
} | |
}, | |
onDropdownOpened: function(c) { | |
this.models.plotGroup.set("editMode", true) | |
}, | |
onDropdownClosed: function(c) { | |
this.models.plotGroup.set("editMode", false) | |
}, | |
onEditMode: function(c, d) {}, | |
render: function(e) { | |
var c = { | |
forecastSource: this.models.weather.get("forecast.source"), | |
plots: this.models.plotGroup.get("plots") | |
}; | |
var d = this.template(c); | |
this.$el.html(d); | |
var f = this.models.plotGroup.get("editMode"); | |
return this | |
}, | |
toggleVariable: function(k, c) { | |
var g = this.models.plotGroup.get("plots"); | |
for (var f = 0; f < g.length; f++) { | |
var h = g[f].variables; | |
for (var d = 0; d < h.length; d++) { | |
if (h[d].id == k) { | |
var e = "plots[" + f + "].variables[" + d + "]"; | |
this.models.plotGroup.set(e + ".show", c) | |
} | |
} | |
} | |
} | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Views.Extended = Backbone.View.extend({ | |
events: { | |
"click .fct3-toggle-hide": "onClickHideFct3", | |
"click .fct3-toggle-show": "onClickShowFct3" | |
}, | |
initialize: function(c) { | |
this.options = c || {}; | |
this.weather = this.options.weather; | |
if (b("#extended-template").length > 0) { | |
this.template = _.template(b("script#extended-template").html()); | |
this.listenTo(this.weather, "change:forecast", this.render); | |
if (this.options.render && this.weather.attributes.forecast) { | |
this.render() | |
} | |
} | |
}, | |
onClickHideFct3: function(c) { | |
c.preventDefault(); | |
this.toggleFct3(false) | |
}, | |
onClickShowFct3: function(c) { | |
c.preventDefault(); | |
this.toggleFct3(true) | |
}, | |
render: function(g, i) { | |
var d = { | |
labels: this.weather.attributes.labels, | |
weather: this.weather.attributes | |
}; | |
var e = this.weather.get("response"); | |
d.showPrecipDay = false; | |
d.showPrecipNight = false; | |
if (e && e.date) { | |
var c = e.date.hour; | |
if (c >= 1 && c < 19) { | |
d.showPrecipDay = true | |
} | |
if (c >= 13) { | |
d.showPrecipNight = true | |
} | |
} | |
var f = wui.bootstrapped && wui.bootstrapped.precip ? wui.bootstrapped.precip.baseUrl : ""; | |
if (f && e.location) { | |
f += a.generateCityQuery({ | |
zip: e.location.zip, | |
magic: e.location.magic, | |
wmo: e.location.wmo, | |
country: e.location.country_iso3166 | |
}) | |
} | |
d.cityUrl = f; | |
var h = this.template(d); | |
this.$el.html(h); | |
this.checkStorm(); | |
return this | |
}, | |
toggleFct3: function(c) { | |
var d = this.model.get("classNames"); | |
this.$el.toggleClass(d.open, !!c) | |
}, | |
checkStorm: function() { | |
if (wui.bootstrapped.citypage) { | |
var e = wui.bootstrapped.citypage.storm; | |
for (var d in e) { | |
var c = "div#fctDay-" + d; | |
var f = "has-alert"; | |
if (e[d].type === "blizzard") { | |
f += " has-blizzard" | |
} | |
if (b(c).length) { | |
b(c).addClass(f) | |
} | |
} | |
} | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Views.PhotoSlideshow = Backbone.View.extend({ | |
initialize: function(b) { | |
this.options = b || {}; | |
this.models = this.options.models || {}; | |
if (this.options.render) { | |
this.initializeLater() | |
} | |
}, | |
initializeLater: function() { | |
this.template = _.template(a("script#photo-slideshow-template").html()); | |
this.render() | |
}, | |
getPhotos: function() { | |
var b = this.options.photos || []; | |
return b | |
}, | |
render: function() { | |
var c = { | |
photos: this.getPhotos() | |
}; | |
var b = this.template(c); | |
this.$el.find(".slideshow").html(b); | |
a(document).ready(function() { | |
a(".bxslider").bxSlider({ | |
captions: true | |
}) | |
}); | |
return this | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Views.Share = Backbone.View.extend({ | |
events: { | |
"click #shareButton": "onClickButton", | |
"click .share-icons #socialTwitter": "onClickTwitter", | |
"click .share-icons #socialFacebook": "onClickFacebook", | |
"click .share-icons #socialGoogle": "onClickGoogle", | |
"click .share-icons #socialReddit": "onClickReddit", | |
"click .share-icons #socialMail": "onClickMail", | |
"click #radioForm #fullLinkRadio": "onClickFullLink", | |
"click #radioForm #shortLinkRadio": "onClickShortLink" | |
}, | |
initialize: function(b) { | |
this.options = b || {}; | |
this.models = this.options.models || {}; | |
this._opened = false; | |
this.urls = new Backbone.Model({ | |
full: null, | |
mini: null | |
}); | |
this.templateButtons = _.template(a("script#share-buttons-template").html()); | |
this.templatePanel = _.template(a("script#share-panel-template").html()); | |
if (this.options.render) { | |
this.render() | |
} | |
}, | |
initializeAtFirstOpen: function() { | |
this.listenTo(this.urls, "change", this.renderURL) | |
}, | |
getURL: function() { | |
var b = ""; | |
var c = this.$el.find("#shortLinkRadio"); | |
if (c.is(":checked")) { | |
b = this.urls.get("mini") | |
} | |
if (!b) { | |
b = this.urls.get("full") | |
} | |
return b | |
}, | |
getFullURL: function() { | |
var b = ""; | |
if (wui && wui.bootstrapped && wui.bootstrapped.share) { | |
if (wui.bootstrapped.share.url) { | |
b = wui.bootstrapped.share.url | |
} | |
} | |
if (!b) { | |
b = a('meta[property="og:url"]').attr("content") | |
} | |
if (!b) { | |
b = a("link[rel=canonical]").attr("href") | |
} | |
if (!b) { | |
b = window.location.toString() | |
} | |
b = b.trim(); | |
return b | |
}, | |
getTitle: function() { | |
var b = ""; | |
if (wui && wui.bootstrapped && wui.bootstrapped.share) { | |
if (wui.bootstrapped.share.title) { | |
b = wui.bootstrapped.share.title | |
} | |
} | |
if (!b) { | |
b = a('meta[property="og:title"]').attr("content") | |
} | |
if (!b) { | |
b = document.title | |
} | |
b = b.trim(); | |
return b | |
}, | |
getDescription: function() { | |
var b = ""; | |
if (wui && wui.bootstrapped && wui.bootstrapped.share) { | |
if (wui.bootstrapped.share.description) { | |
b = wui.bootstrapped.share.description | |
} | |
} | |
if (!b) { | |
b = a('meta[property="og:description"]').attr("content") | |
} | |
if (!b) { | |
b = a('meta[name="description"]').attr("content") | |
} | |
b = b.trim(); | |
return b | |
}, | |
getImage: function() { | |
var b = ""; | |
if (wui && wui.bootstrapped && wui.bootstrapped.share) { | |
if (wui.bootstrapped.share.image) { | |
b = wui.bootstrapped.share.image | |
} | |
} | |
if (!b) { | |
b = a('meta[property="og:image"]').attr("content") | |
} | |
if (!b) { | |
b = "//icons.wxug.com/i/o/logo-footer.png" | |
} | |
b = b.trim(); | |
return b | |
}, | |
loadScripts: function() { | |
window.___gcfg = { | |
lang: "en-US" | |
}; | |
(function() { | |
var b = document.createElement("script"); | |
b.type = "text/javascript"; | |
b.async = true; | |
b.src = "https://apis.google.com/js/plusone.js"; | |
var c = document.getElementsByTagName("script")[0]; | |
c.parentNode.insertBefore(b, c) | |
})(); | |
window.fbAsyncInit = function() { | |
FB.init({ | |
appId: wui.facebook.app_id, | |
channelUrl: wui.facebook.channel_url, | |
status: true, | |
cookie: true, | |
xfbml: true, | |
version: "v2.0" | |
}); | |
wui.facebook.on_load_trigger() | |
} | |
; | |
(function(e) { | |
var c, f = "facebook-jssdk", b = e.getElementsByTagName("script")[0]; | |
if (e.getElementById(f)) { | |
return | |
} | |
c = e.createElement("script"); | |
c.id = f; | |
c.async = true; | |
c.src = "//connect.facebook.net/en_US/sdk.js"; | |
b.parentNode.insertBefore(c, b) | |
}(document)) | |
}, | |
onClickButton: function(b) { | |
if (!this._opened) { | |
this.initializeAtFirstOpen(); | |
this.renderPanel() | |
} | |
this._opened = true; | |
this.renderURL(); | |
this.updateMiniURL() | |
}, | |
onClickFullLink: function(b) { | |
this.updateFullURL(); | |
this.renderURL() | |
}, | |
onClickShortLink: function(b) { | |
this.updateMiniURL(); | |
this.renderURL() | |
}, | |
onClickFacebook: function(d) { | |
d.preventDefault(); | |
var b = this.getFullURL(); | |
var c = null; | |
if (wui && wui.bootstrapped && wui.bootstrapped.share) { | |
c = wui.bootstrapped.share | |
} | |
if (wui && wui.bootstrapped && (wui.bootstrapped.pageType == "CityPage")) { | |
facebook_share_forecast(b, c.image, c.now, c.temp_now, c.high_now, c.low_now, c.tonight, c.high_tonight, c.low_tonight, c.tomorrow, c.high_tomorrow, c.low_tomorrow, c.loc) | |
} else { | |
c = { | |
title: this.getTitle(), | |
description: this.getDescription(), | |
image: this.getImage() | |
}; | |
facebook_share_page(c.title, b, c.description, c.image) | |
} | |
}, | |
onClickGoogle: function(c) { | |
c.preventDefault(); | |
var b = this.getURL(); | |
window.open("https://plus.google.com/share?url=" + encodeURIComponent(b), "", "menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600") | |
}, | |
onClickMail: function(c) { | |
c.preventDefault(); | |
var b = this.getURL(); | |
var d = this.getTitle(); | |
window.open("mailto:?subject=Check this out on Weather Underground&body=" + encodeURIComponent(d) + "%20%20%0d" + b, "", "menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600") | |
}, | |
onClickTwitter: function(f) { | |
f.preventDefault(); | |
var d = ""; | |
var e = null; | |
var c = this.getURL(); | |
if (wui && wui.bootstrapped && wui.bootstrapped.share) { | |
e = wui.bootstrapped.share | |
} | |
if (e && e.content) { | |
d = e.content | |
} else { | |
if (e && e.content_template) { | |
var b = {}; | |
if (this.models.weather) { | |
b.weather = this.models.weather.attributes; | |
b.labels = b.weather.labels | |
} | |
d = _.template(e.content_template, b) | |
} else { | |
d = this.getTitle() | |
} | |
} | |
var g = { | |
related: "wunderground", | |
text: d, | |
url: c, | |
via: "wunderground" | |
}; | |
if (e && e.via) { | |
g.via = e.via | |
} | |
window.open("http://twitter.com/share?" + a.param(g), "twitterwindow", "menubar=1,resizable=0,width=550,height=368") | |
}, | |
onClickReddit: function(c) { | |
c.preventDefault(); | |
var b = this.getURL(); | |
window.open("http://www.reddit.com/submit?url=" + encodeURIComponent(b), "redditwindow", "menubar=1,resizable=0,width=750,height=500") | |
}, | |
render: function() { | |
this.loadScripts(); | |
var b = this.templateButtons(); | |
this.$el.find("#shareButtons").html(b); | |
return this | |
}, | |
renderPanel: function() { | |
var b = this.templatePanel(); | |
this.$el.find("#sharePanel").html(b); | |
return this | |
}, | |
renderURL: function() { | |
var b = this.getURL(); | |
this.$el.find("#urlInput").val(b) | |
}, | |
requestMiniURL: function() { | |
var b = this.updateFullURL({ | |
silent: true | |
}); | |
var c = a.ajax({ | |
url: "/miniurl/api.php?url=" + encodeURIComponent(b) | |
}); | |
return c | |
}, | |
updateFullURL: function(c) { | |
var b = this.getFullURL(); | |
this.urls.set("full", b, c); | |
return b | |
}, | |
updateMiniURL: function() { | |
var b = this; | |
var c = this.requestMiniURL(); | |
c.done(function(d, e) { | |
b.urls.set("mini", d) | |
}).fail(function() { | |
b.urls.set("mini", "") | |
}); | |
return c | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
var b = "https://www.wunderground.com"; | |
if (window.location.host && window.location.host.indexOf("www") === -1) { | |
b = "" | |
} | |
if (!window.Backbone) { | |
return | |
} | |
wui.Views.MembershipForm = Backbone.View.extend({ | |
events: { | |
"change #show-password": "showPassword", | |
"change #gift-code": "showGiftField", | |
"keydown #sign-up-form input": "debouncedChangeStatus", | |
"blur #sign-up-form input": "immediateChangeStatus", | |
"click .submit-button": "setMembershipType", | |
"change #terms": "setCheckedStatus", | |
"submit #sign-up-form": "submitSignUpForm", | |
"submit #sign-in-form": "submitSignInForm", | |
"click .gift-label-wrap": "disableLabelClick", | |
"submit #user-delete-form": "submitDeleteForm", | |
"click .cancel-delete-btn": "closeDeleteForm" | |
}, | |
initialize: function() { | |
this.validators = this.validatorFunctions(); | |
this.usedGiftCode = false; | |
this.views = {}; | |
this.$premiumBtn = a("#noads-submit"); | |
this.$basicBtn = a("#basic-submit"); | |
var c = wui.getParameterByName("giftcode"); | |
if (c) { | |
setTimeout(function() { | |
a("#gift-code").trigger("click"); | |
a("#register-gift").val(c).trigger("blur") | |
}, 0) | |
} | |
this.debouncedChangeStatus = _.debounce(this.changeStatus, 250) | |
}, | |
changeStatus: function(k, d) { | |
var l = k.target; | |
var c = a(l); | |
var m = c.val(); | |
var h = c.parent(); | |
var f = c.data("previousValue"); | |
var i = this; | |
var g = 2500; | |
if (c.attr("name") === "giftcode") { | |
g = 1000 | |
} | |
if (c.attr("type") === "checkbox" || c.attr("type") === "submit") { | |
return false | |
} | |
if (this.wait && !d) { | |
clearTimeout(this.wait) | |
} | |
if (!d) { | |
this.wait = setTimeout(j, g) | |
} else { | |
j() | |
} | |
function j() { | |
if (!d) { | |
if (!i.wait) { | |
return | |
} | |
i.wait = null | |
} | |
if (f !== m) { | |
c.data("previousValue", m); | |
if (c.val()) { | |
c.data("used", true) | |
} | |
if (c.data("used")) { | |
i.runValidator(c.attr("name"), m, h) | |
} | |
} | |
} | |
}, | |
immediateChangeStatus: function(c) { | |
this.changeStatus(c, true) | |
}, | |
checkIfExists: function(d, f, c) { | |
var h = this; | |
var c = typeof c !== "undefined" ? c : a("#sign-up-form").find('input[name="' + d + '"]'); | |
var e = {}; | |
var g = c.parent(); | |
e[d] = f; | |
this.checkIfExistsDone = function(i) { | |
if (i && i.member) { | |
var k; | |
var j = i.status === "success" && _.isNull(i.member.members); | |
if (!_.isNull(i.member.members)) { | |
k = "Already in use." | |
} | |
if (i.errors && i.errors.length) { | |
k = i.errors[0].error_string | |
} | |
h.setStatus(g, j, k) | |
} | |
} | |
; | |
g.find(".input-status").addClass("loading"); | |
return a.ajax(b + "/member/info/", { | |
data: e, | |
dataType: "json" | |
}).done(h.checkIfExistsDone) | |
}, | |
checkIfGiftCodeExists: function(d) { | |
var f = this; | |
var c = a("#register-gift"); | |
var e = c.parent(); | |
if (!d) { | |
return a.Deferred() | |
} | |
e.find(".input-status").addClass("loading"); | |
return a.ajax(b + "/member/validgiftcode", { | |
data: { | |
giftcode: d | |
}, | |
dataType: "json" | |
}).done(function(g) { | |
if (!a("#gift-code").is(":checked")) { | |
f.resetStatus(a("#register-gift").parent()); | |
return false | |
} | |
if (g && g.status === "success" && g.giftcode) { | |
if (g.giftcode.status === "success") { | |
f.setStatus(e, true); | |
f.giftCodeSuccess(g.giftcode) | |
} else { | |
if (!a("#gift-success").is(":visible")) { | |
f.checkErrors(g.giftcode.errors, e) | |
} else { | |
e.find(".input-status").removeClass("loading") | |
} | |
} | |
} | |
}) | |
}, | |
disableLabelClick: function(d) { | |
var c = a(d.currentTarget); | |
if ((c.find("input").is(":visible") || a("#gift-success").is(":visible")) && d.target !== d.currentTarget) { | |
return false | |
} | |
}, | |
activateButton: function(c) { | |
c.parent().removeClass("disabled"); | |
c.removeClass("disabled") | |
}, | |
deactivateButton: function(c) { | |
c.parent().addClass("disabled"); | |
c.addClass("disabled") | |
}, | |
giftCodeSuccess: function(d) { | |
if (d) { | |
var g = d.expire_epoch * 1000 - new Date(); | |
var c = Math.round(wui.date.millisecondsToUnit(g, "month")); | |
var e = "month" + (c !== 1 ? "s" : ""); | |
var f = d.mobile_gift_code ? "gift-code-mobile" : "gift-code-premium"; | |
this.giftCodeDuration = c + " " + e; | |
this.isMobileGiftCode = d.mobile_gift_code; | |
this.$el.find(".gift-code-duration").show().find(".duration").text(this.giftCodeDuration).end().find("." + f).removeClass("hide"); | |
a("#register-gift").addClass("hide"); | |
a(".gift-input-status").html(""); | |
if (!d.mobile_gift_code) { | |
a("#noads-submit").val("Premium - Free"); | |
this.deactivateButton(this.$basicBtn) | |
} | |
} | |
}, | |
resetGiftCode: function() { | |
a("#noads-submit").val("Premium - $10/yr"); | |
this.$el.find(".gift-code-duration").hide(); | |
this.$el.find(".gift-code-mobile").addClass("hide"); | |
this.$el.find(".gift-code-premium").addClass("hide"); | |
a("#register-gift").data("previousValue", ""); | |
this.activateButton(this.$basicBtn) | |
}, | |
setCheckedStatus: function(d) { | |
var c = a(d.target); | |
c.data("valid", c.is(":checked")) | |
}, | |
setInputStatus: function(e, g, f) { | |
var d = e.find(".input-status"); | |
var c = "status-icon fi-" + (g ? "check" : "x"); | |
d.removeClass("loading"); | |
if (!f) { | |
d.html('<i class="' + c + '" />') | |
} else { | |
d.html("") | |
} | |
}, | |
setMembershipType: function(d) { | |
var c = a(d.target).attr("name"); | |
a("#membership-type").val(c) | |
}, | |
setStatus: function(c, e, d) { | |
d = !e ? d : ""; | |
c.find("input").data("valid", e); | |
this.setInputStatus(c, e); | |
this.setStatusMessage(c, d) | |
}, | |
resetStatus: function(c) { | |
c.find("input").removeData("valid"); | |
this.setInputStatus(c, true, true); | |
this.setStatusMessage(c, "") | |
}, | |
setStatusMessage: function(c, d) { | |
c.find(".status-message").text(d) | |
}, | |
showPassword: function(i) { | |
var c = a("#register-password"); | |
var l = a("#register-password-text"); | |
var j = i.target; | |
var d = a(j); | |
var h = a(".password-state"); | |
var f = j.checked ? c : l; | |
var k = j.checked ? l : c; | |
var m = f.val(); | |
var g = f.data(); | |
h.text(j.checked ? "Hide" : "Show"); | |
f.hide(); | |
k.val(m).show() | |
}, | |
showGiftField: function(f) { | |
var d = f.target; | |
var c = a(d); | |
if (!d.checked) { | |
this.resetStatus(c.parent()); | |
this.resetGiftCode() | |
} | |
}, | |
submitSignInForm: function(f) { | |
var d = { | |
email: a("#sign-in-email").val(), | |
password: a("#sign-in-password").val() | |
}; | |
var g = this; | |
var c = a(f.target); | |
this.updateSignInSubmitButton(); | |
a.ajax({ | |
url: b + c.attr("action"), | |
data: d, | |
dataType: "json", | |
type: c.attr("method"), | |
xhrFields: { | |
withCredentials: true | |
} | |
}).done(function(h) { | |
var e = h.status; | |
var i = h.errors; | |
if (e === "success") { | |
g.resetStatus(c); | |
if (a("#wu-registration").length) { | |
if (a("#sign-in-form #redirect_url").val().length) { | |
location.href = a("#sign-in-form #redirect_url").val(); | |
window.location.reload() | |
} else { | |
window.location.reload() | |
} | |
} else { | |
window.location.href = document.referrer || "/" | |
} | |
} else { | |
if (i) { | |
g.checkErrors(i, a("#sign-in-form")); | |
g.updateSignInSubmitButton() | |
} else {} | |
} | |
}); | |
return false | |
}, | |
closeDeleteForm: function(c) { | |
a("#user-delete").foundation("reveal", "close") | |
}, | |
submitDeleteForm: function(f) { | |
var d = { | |
password: a("#delete-password").val() | |
}; | |
var g = this; | |
var c = a(f.target); | |
this.updateDeleteSubmitButton(); | |
a.ajax({ | |
url: b + c.attr("action"), | |
data: d, | |
dataType: "json", | |
type: c.attr("method"), | |
xhrFields: { | |
withCredentials: true | |
} | |
}).done(function(h) { | |
var e = h.status; | |
var i = h.errors; | |
if (e === "success") { | |
g.resetStatus(c); | |
if (a("#user-delete").length) { | |
if (a("#user-delete-form #redirect_url").val().length) { | |
location.href = a("#user-delete-form #redirect_url").val(); | |
window.location.reload() | |
} else { | |
window.location.reload() | |
} | |
} else { | |
window.location.href = document.referrer || "/" | |
} | |
} else { | |
if (i) { | |
g.checkErrors(i, a("#user-delete-form")); | |
g.updateDeleteSubmitButton() | |
} else {} | |
} | |
}); | |
return false | |
}, | |
checkErrors: function(g, f) { | |
if (g && g.length) { | |
for (var e = 0; e < g.length; e++) { | |
var c = g[e]; | |
var d = f.find('input[name="' + c.field_name + '"]').parent(); | |
this.setStatus(d, false, c.error_string) | |
} | |
} | |
}, | |
submitSignUpForm: function(h) { | |
var f = a("#membership-type").val() === "noads" ? this.$premiumBtn : this.$basicBtn; | |
if (f.hasClass("disabled")) { | |
return false | |
} | |
var g = { | |
email: a("#register-email").val(), | |
handle: a("#register-handle").val(), | |
password: a("#register-password").val() || a("#register-password-text").val(), | |
tos: a("#terms").is(":checked"), | |
optin: a("#optin").is(":checked"), | |
signupmode: "web_signup", | |
signup_ref: document.referrer | |
}; | |
var d = a(h.target); | |
var i = this; | |
var c = a("#register-gift").val(); | |
if (c.length) { | |
g.giftcode = c | |
} | |
if (!c.length || this.isMobileGiftCode) { | |
g.noads = a("#membership-type").val() === "noads" | |
} | |
this.updateSignUpSubmitButton(f, true); | |
this.submitDone = function(j) { | |
var e = j.status; | |
var l = j.errors || []; | |
var k = j.giftcode && j.giftcode.errors ? j.giftcode.errors : []; | |
if (e) { | |
if (e === "error" || k.length) { | |
l = l.concat(k); | |
i.checkErrors(l, a("#sign-up-form")); | |
i.updateSignUpSubmitButton(f) | |
} else { | |
if (e === "success") { | |
if ((g.noads && _.isNull(j.giftcode)) || this.isMobileGiftCode) { | |
i.directToPayment(g.email) | |
} else { | |
i.renderAlmostView(g) | |
} | |
} | |
} | |
} | |
} | |
; | |
a.ajax({ | |
url: b + d.attr("action"), | |
data: g, | |
dataType: "json", | |
type: d.attr("method"), | |
xhrFields: { | |
withCredentials: true | |
} | |
}).done(i.submitDone).fail(function(e) { | |
i.updateSignUpSubmitButton(f) | |
}); | |
return false | |
}, | |
renderAlmostView: function(e) { | |
var c = a("#wu-registration").length ? window.location.href : document.referrer || "/"; | |
if (c.indexOf("wunderground") < 0) { | |
c = "//www.wunderground.com" | |
} | |
var d = "newmember="; | |
if (c.indexOf(d) === -1) { | |
c += (c.indexOf("?") === -1 ? "?" : "&") + d + "1" | |
} | |
if (a("#sign-up-form #redirect_url").val().length) { | |
window.location.href = a("#sign-up-form #redirect_url").val(); | |
window.location.reload() | |
} else { | |
window.location.href = c | |
} | |
}, | |
render: function() { | |
return this | |
}, | |
runValidator: function(d, g, f) { | |
var e = this.validators[d]; | |
if (typeof e !== "undefined") { | |
var c = e.check(g); | |
if (!a.isFunction(c.done)) { | |
this.setStatus(f, c.valid, c.message); | |
return c.valid | |
} else { | |
return c | |
} | |
} | |
}, | |
updateDeleteSubmitButton: function() { | |
var d = a("#delete-btn"); | |
var c = d.val(); | |
d.val(d.data("alt-action")); | |
d.data("alt-action", c); | |
d.toggleClass("disabled") | |
}, | |
updateSignInSubmitButton: function() { | |
var d = a("#sign-in-btn"); | |
var c = d.val(); | |
d.val(d.data("alt-action")); | |
d.data("alt-action", c); | |
d.toggleClass("disabled") | |
}, | |
updateSignUpSubmitButton: function(d, e) { | |
var c = d.val(); | |
d.val(d.data("alt-action")); | |
d.data("alt-action", c); | |
d.siblings(".submit-status").toggleClass("loading"); | |
if (e) { | |
this.$premiumBtn.addClass("disabled"); | |
this.$basicBtn.addClass("disabled") | |
} else { | |
this.$premiumBtn.toggleClass("disabled"); | |
this.$basicBtn.toggleClass("disabled") | |
} | |
}, | |
directToPayment: function(c) { | |
a(".payment-form").find('input[name="os0"]').val(c); | |
a(".payment-form").submit() | |
}, | |
validatorFunctions: function() { | |
var c = this; | |
return { | |
email: { | |
check: function(f) { | |
var d = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; | |
var e = d.test(f); | |
if (!e) { | |
return { | |
valid: e, | |
message: !e ? "Email is invalid." : "" | |
} | |
} else { | |
this.done = function() {} | |
; | |
return c.checkIfExists("email", f) | |
} | |
} | |
}, | |
handle: { | |
check: function(f) { | |
var d = /^[a-zA-Z0-9]{1,20}$/; | |
var e = d.test(f); | |
if (!e) { | |
return { | |
valid: e, | |
message: !e ? "Letters and numbers only, please." : "" | |
} | |
} else { | |
this.done = function() {} | |
; | |
return c.checkIfExists("handle", f) | |
} | |
} | |
}, | |
giftcode: { | |
check: function(d) { | |
return c.checkIfGiftCodeExists(d) | |
} | |
}, | |
password: { | |
check: function(e) { | |
var d = (e.length >= 5 && e.length <= 30); | |
return { | |
valid: d, | |
message: !d ? "Must be 5 to 30 characters." : "" | |
} | |
} | |
}, | |
tos: { | |
check: function(e) { | |
var d = e === "on" ? true : false; | |
return { | |
valid: d, | |
message: !d ? "Required." : "" | |
} | |
} | |
} | |
} | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
var b = "https://www.wunderground.com"; | |
if (!window.Backbone) { | |
return | |
} | |
wui.Views.MembershipAlmost = Backbone.View.extend({ | |
events: {}, | |
initialize: function(c) { | |
this.options = c | |
}, | |
addParam: function(c, d) { | |
if (location.search.length) { | |
return c + "&" + d | |
} | |
return c + "?" + d | |
}, | |
checkValidation: function() { | |
var g = this; | |
if (!this.options.email) { | |
return false | |
} | |
var d = 2500; | |
var f = 300000; | |
var c = 0; | |
var e = setInterval(function() { | |
a.ajax(b + "/member/info/", { | |
data: { | |
email: g.options.email | |
}, | |
dataType: "json", | |
cache: false | |
}).done(function(h) { | |
var j = h.member; | |
if (h && h.status === "success" && j.members && j.members.length) { | |
var i = j.members[0].account_valid === "valid"; | |
if (i) { | |
window.location.href = g.addParam(window.location.href, "membervalidated=1"); | |
clearTimeout(e) | |
} | |
} | |
c++; | |
if (c >= f / d) { | |
clearTimeout(e) | |
} | |
}) | |
}, d); | |
a(document).on("closed.fndtn.reveal", "[data-reveal]", function() { | |
clearTimeout(e) | |
}) | |
}, | |
render: function() { | |
return this | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Views.Videos = Backbone.View.extend({ | |
initialize: function(b) { | |
this.options = b || {}; | |
this.models = this.options.models || {}; | |
if (this.options.render) { | |
this.initializeLater() | |
} | |
}, | |
initializeLater: function() { | |
var b = this.options.videos; | |
var c = this.$el.find("#videoImage"); | |
a.ajax({ | |
url: "//dsx.weather.com/cms/orderedlist/video/pl-wunderground-top-stories", | |
dataType: "jsonp", | |
jsonp: "jsonp", | |
success: function(i, k, h) { | |
var e = i.body; | |
if (e && e.length) { | |
var g = e[0]; | |
var d = g.variants[9]; | |
var j = g.title; | |
var f = '<div><a href="/video?video=' + g.source_guid + "\" onclick=\"_gaq.push(['_trackEvent', 'Meat TDU', 'Click'," + b.title + ']);" id="video-tdu-link"><img src="' + d + '" alt="' + g.title + '" /><span><img src="' + b.play_icon + '" alt="Play"></span><div class="content"><h4 class="video-caption">' + j + "</h4></div></a></div>"; | |
c.append(f) | |
} | |
} | |
}) | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Views.HPTileVideos = Backbone.View.extend({ | |
initialize: function(b) { | |
this.options = b || {}; | |
this.render() | |
}, | |
render: function() { | |
var b = this.$el; | |
a.ajax({ | |
url: "//dsx.weather.com/cms/orderedlist/video/pl-wunderground-top-stories", | |
dataType: "jsonp", | |
jsonp: "jsonp", | |
success: function(g, h, f) { | |
if (g && g.body && g.body.length) { | |
var e = g.body[0]; | |
var c = e.variants[8]; | |
var d = '<a href="/video/top-stories/?cm_ven=topstories_hptile&video=' + e.source_guid + '"><div class="row collapse has-playbtn"><div class="columns small-5 medium-12 large-12 cta-news"><div class="cta-image"><img src="' + c + '" title="' + e.title + '" /><span><img src="//icons.wxug.com/graphics/playBtn.png" alt="Play"></span></div></div><div class="columns small-7 medium-12 large-12"><h3>' + e.title + "</h3></div></div></a>"; | |
b.append(d) | |
} | |
} | |
}) | |
} | |
}) | |
})(jQuery); | |
(function(b) { | |
if (!window.Backbone) { | |
return | |
} | |
var a = wui.backbone.utils; | |
wui.Views.Wundermap = Backbone.View.extend({ | |
events: {}, | |
initialize: function(c) { | |
this.options = c || {}; | |
this.models = this.options.models || {}; | |
if (!this.models.wundermap) { | |
console.error("missing required model `wundermap` in this.models"); | |
return | |
} | |
if (this.options.render) { | |
this.initializeLater() | |
} | |
}, | |
initializeLater: function() { | |
this.viewLoaded = b.Deferred(); | |
var c = this; | |
var d = wui.usher.loadScript("googlemaps"); | |
d.done(function() { | |
c.continueInit() | |
}) | |
}, | |
continueInit: function() { | |
var e = { | |
zoom: this.models.wundermap.get("zoom"), | |
minZoom: this.models.wundermap.get("minZoom"), | |
maxZoom: this.models.wundermap.get("maxZoom"), | |
center: this.models.wundermap.get("center"), | |
mapTypeId: google.maps.MapTypeId.ROADMAP, | |
mapTypeControl: this.models.wundermap.get("mapTypeControl") | |
}; | |
var h = ["RADAR", "SAT", "WEBCAM"]; | |
var d = this.options.layer; | |
this.tabindex = _.indexOf(h, d[0]); | |
if (this.tabindex < 0) { | |
this.tabindex = 0 | |
} | |
e.layer = h[this.tabindex]; | |
this.template = _.template(b("script#wundermap_template").html(), null, { | |
variable: "data" | |
}); | |
this.templateWebcam = _.template(b("script#webcam_modal_template").html()); | |
var c = this.template(e); | |
this.$el.find(".map-ui").html(c); | |
this.initGoogleMap(); | |
var f = this; | |
var g = wui.usher.loadScript("wundermap"); | |
g.done(function() { | |
f.finishInit() | |
}) | |
}, | |
finishInit: function() { | |
this.render(); | |
wundermap.layers.Webcams.onClick = b.proxy(this.openWebcamModal, this); | |
wundermap.getLinkToThisPage = function(e) { | |
var d = "/wundermap/?" + this.toQueryString(e); | |
return d | |
} | |
; | |
var c = this.$tabs = this.$el.find("#wundermap_module_header"); | |
c.tabs({ | |
active: this.tabindex | |
}); | |
google.maps.event.addListener(wundermap, "layertoggled", b.proxy(this.onLayerToggled, this)); | |
this.viewLoaded.resolve() | |
}, | |
openWebcamModal: function(g, f) { | |
var c = g.ICONS[0]; | |
var e = { | |
city: c.city, | |
state: c.state, | |
country: c.country, | |
neighborhood: c.neighborhood, | |
image_url: "//icons.wxug.com/" + c.image, | |
handle: c.handle, | |
camindex: c.camindex, | |
link: "/webcams/" + c.handle + "/" + c.camindex + "/show.html" | |
}; | |
var d = this.templateWebcam({ | |
webcam: e | |
}); | |
b("#webcamModal").html(d); | |
b("#webcamModal").foundation("reveal", "open") | |
}, | |
checkEnticements: function() { | |
var c = this.activeTab(); | |
if (this.last_tab_with_enticement == c) { | |
return | |
} | |
var f = this.models.wundermap.get("enticement"); | |
var e = this.$el.find(".enticements"); | |
var d = this.$enticements.filter(".enticement-" + f); | |
if (d[0]) { | |
this.$enticements.hide(); | |
d.show(); | |
e.slideDown(); | |
this.last_tab_with_enticement = c | |
} else { | |
e.hide() | |
} | |
}, | |
initEnticements: function() { | |
var g = this; | |
var f = this.models.wundermap.get("gmap"); | |
this.$enticements = this.$el.find(".enticements .enticement"); | |
this.checkEnticements(); | |
this.$enticements.find("a").attr("target", "_blank"); | |
this.listenTo(this.models.wundermap, "change:enticement", this.onChangeEnticement); | |
var e = 0; | |
google.maps.event.addListener(f, "idle", function() { | |
e++; | |
if (e <= 1) { | |
return | |
} | |
g.showEnticement("panzoom") | |
}); | |
google.maps.event.addListener(wundermap, "layertoggled", function(k, j) { | |
g.showEnticement("layers") | |
}); | |
var c = wundermap.layers.Radar; | |
var d = wundermap.layers.Satellite; | |
var i = c.getPrefs().num; | |
var h = d.getPrefs().num; | |
google.maps.event.addListener(c, "settings_changed", function() { | |
var j = c.getPrefs().num; | |
if (i !== j) { | |
i = j; | |
g.showEnticement("animation") | |
} | |
}); | |
google.maps.event.addListener(d, "settings_changed", function() { | |
var j = d.getPrefs().num; | |
if (h !== j) { | |
h = j; | |
g.showEnticement("animation") | |
} | |
}) | |
}, | |
initGoogleMap: function() { | |
var f = this.models.wundermap.get("lat"); | |
var h = this.models.wundermap.get("lon"); | |
var g = this.models.wundermap.get("gMapType"); | |
var e = this.models.wundermap.get("gMapUnits"); | |
var c = true; | |
if (b(window).width() <= 640) { | |
c = false | |
} | |
var d = new google.maps.Map(this.$(".map")[0],{ | |
center: new google.maps.LatLng(f,h), | |
zoom: this.models.wundermap.get("zoom"), | |
mapTypeId: "lightmap", | |
mapTypeControl: false, | |
mapTypeControlOptions: { | |
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU | |
}, | |
disableDefaultUI: true, | |
draggable: c, | |
scrollwheel: false, | |
streetViewControl: false, | |
zoomControl: true, | |
zoomControlOptions: { | |
style: google.maps.ZoomControlStyle.SMALL | |
} | |
}); | |
this.models.wundermap.set("gmap", d) | |
}, | |
onChangeEnticement: function(c, d) { | |
this.checkEnticements() | |
}, | |
onLayerToggled: function(g, e) { | |
var c = wundermap.layers.Radar; | |
var f = wundermap.layers.Satellite; | |
b("#radar_animate_button").toggle(c.active_); | |
b("#sat_animate_button").toggle(f.active_); | |
var h = ""; | |
var d = { | |
Radar: "RADAR", | |
Satellite: "SAT", | |
Webcams: "WEBCAM" | |
}; | |
h = d[g]; | |
if (e) { | |
if (h === "WEBCAM") { | |
wui.prefs.set("RADARBOX_WEBCAM", h) | |
} else { | |
wui.prefs.set("RADARBOX", h) | |
} | |
} else { | |
if (h === "WEBCAM") { | |
wui.prefs.set("RADARBOX_WEBCAM", "") | |
} | |
} | |
}, | |
recenter: function() { | |
var c = this.models.wundermap.get("gmap"); | |
if (!google) { | |
console.log("nooo google"); | |
return | |
} | |
google.maps.event.addDomListener(window, "resize", function() { | |
var d = c.getCenter(); | |
google.maps.event.trigger(c, "resize"); | |
c.setCenter(d) | |
}) | |
}, | |
render: function() { | |
this.setLayers(); | |
wundermap.initialize(); | |
this.recenter(); | |
return this | |
}, | |
setLayers: function() { | |
var g = this.models.wundermap.get("gMapUnits"); | |
var c = this.models.wundermap.get("gmap"); | |
var e = this.options.layer || "RADAR"; | |
var d = null; | |
var f; | |
if (wui.bootstrapped.citypage) { | |
d = wui.bootstrapped.citypage.storm ? 1 : 0; | |
f = wui.bootstrapped.citypage.tzname | |
} | |
if (c && wundermap) { | |
wundermap.date = new Date(); | |
wundermap.setOptions({ | |
map: c, | |
refreshPeriod: 60000, | |
customMapTypes: true, | |
units: g, | |
layers: [{ | |
layer: "Radar", | |
active: (e[0] === "RADAR"), | |
timelabel: 1, | |
timelabelX_offset: 163, | |
timelabelY_offset: 22, | |
tzname: f, | |
defaultUI: 0, | |
opacity: 75, | |
useTiles: false, | |
type: "00Q", | |
type2: "", | |
smooth: 1, | |
animation: { | |
num: 10, | |
delay: 50 | |
} | |
}, { | |
layer: "Satellite", | |
active: (e[0] === "SAT"), | |
timelabel: 1, | |
timelabelX_offset: 176, | |
timelabelY_offset: 22, | |
tzname: f, | |
opacity: 60, | |
animation: { | |
num: 4, | |
delay: 50 | |
} | |
}, { | |
layer: "Webcams", | |
active: (e[1] === "WEBCAM") | |
}, { | |
layer: "Hurricane", | |
active: d | |
}], | |
linkToThisPage: { | |
rawlink: this.$el.find("A.wundermap-link") | |
} | |
}) | |
} | |
}, | |
activeTab: function() { | |
return wundermap.layers.Radar.active_ ? "radar" : (wundermap.layers.Satellite.active_ ? "satellite" : "webcams") | |
}, | |
showEnticement: function(c) { | |
this.models.wundermap.set("enticement", c + "-" + this.activeTab()) | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Models.Survey = Backbone.Model.extend({ | |
initialize: function(b, c) { | |
this.cookie_name = "wu-survey-campaign-" + b.campaign + "-is-available"; | |
this.cookie_promise = wui.usher.loadScript("jquery-cookie") | |
}, | |
close: function() { | |
var b = this; | |
this.cookie_promise.done(function() { | |
a.cookie(b.cookie_name, "false", { | |
expires: 7, | |
path: "/" | |
}) | |
}); | |
return this | |
}, | |
when_available: function(d) { | |
var b = this | |
, c = function() { | |
return a.cookie(b.cookie_name) != "false" | |
}; | |
this.cookie_promise.done(function() { | |
if (c()) { | |
d.apply() | |
} | |
}); | |
return this | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Views.SurveyPrompt = Backbone.View.extend({ | |
events: { | |
"click .alert-box-close": "onSurveyPromptClose" | |
}, | |
initialize: function(b) { | |
this.survey = b.survey; | |
this.template = _.template('<p class="alert-box-prompt"><%= prompt %></p><a class="alert-box-close-button modal-close alert-box-close">×</a>'); | |
this.constructTemplate() | |
}, | |
constructTemplate: function() { | |
var b = this.template({ | |
prompt: this.survey.get("prompt") | |
}); | |
this.$el.html(b) | |
}, | |
render: function() { | |
this.constructTemplate(); | |
return this | |
}, | |
onSurveyPromptClose: function(b) { | |
this.survey.close() | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Views.AlertBar = Backbone.View.extend({ | |
events: { | |
"click .alert-box-close": "onClose" | |
}, | |
id: "header-alert", | |
initialize: function(b) { | |
this.alert_view = b.alert; | |
this.$el.append(this.alert_view.el); | |
a("body").prepend(this.$el).addClass("header-alert-visible") | |
}, | |
onClose: function(b) { | |
a(this.alert_view.el).remove(); | |
this.alert_view = null; | |
a("body").removeClass("header-alert-visible"); | |
this.$el.detach() | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
var b = "https://www.wunderground.com"; | |
if (window.location.host && window.location.host.indexOf("www") === -1) { | |
b = "" | |
} | |
if (!window.Backbone) { | |
return | |
} | |
wui.Views.UpgradeMembershipView = Backbone.View.extend({ | |
events: { | |
"submit .upgrade-wrap": "upgradeMembership", | |
"submit #send-gift": "sendGiftCode" | |
}, | |
initialize: function() {}, | |
render: function() { | |
return this | |
}, | |
sendGiftCode: function(f) { | |
var c = a(f.target); | |
var d = b + c.attr("action") + "?" + c.serialize(); | |
a("#send-loading").addClass("loading"); | |
a("#send-status").removeClass("error"); | |
a.ajax(d, { | |
type: "post", | |
dataType: "json" | |
}).done(function(e) { | |
if (e.status === "success") { | |
if (e.giftcode && e.giftcode.errors && e.giftcode.errors.length) { | |
a("#send-status").text(e.giftcode.errors[0].error_string).addClass("error") | |
} else { | |
a("#send-status").html("You sent <strong>" + c.find('input[name="toemail"]').val() + "</strong> a message with details on how to get three months of Premium Membership!") | |
} | |
} else { | |
if (e.errors && e.errors.length) { | |
a("#send-status").text(e.errors[0].error_string).addClass("error") | |
} | |
} | |
}).fail(function() { | |
a("#send-status").text("Something went wrong...Please try again later.") | |
}).complete(function() { | |
a("#send-loading").removeClass("loading") | |
}); | |
return false | |
}, | |
redeemGiftCode: function(c, d) { | |
var e = this; | |
a.ajax(b + "/member/redeemcode", { | |
data: { | |
giftcode: c, | |
toemail: d | |
}, | |
dataType: "json" | |
}).done(function(f) { | |
if (f.status === "success") { | |
if (f.giftcode && f.giftcode.errors && f.giftcode.errors.length) { | |
e.$el.find(".upgrade-status").removeClass("hide").text(f.giftcode.errors[0].error_string) | |
} else { | |
e.$el.find(".upgrade-status").text("Your giftcode has been applied successfully!").removeClass("error hide") | |
} | |
} | |
}).fail(function() { | |
e.$el.find(".upgrade-status").removeClass("hide").text("Something went wrong...Please try again later.") | |
}).complete(function() { | |
e.$el.find(".upgrade-loading").removeClass("loading") | |
}) | |
}, | |
upgradeMembership: function() { | |
var d = this.$el.find(".upgrade-code"); | |
var e = d.val(); | |
var c = this.$el.find('input[name="gift-only"]').val() == 1 || false; | |
if (e || c) { | |
this.$el.find(".upgrade-loading").addClass("loading"); | |
this.redeemGiftCode(e, d.data("email")) | |
} else { | |
a(".payment-form").submit() | |
} | |
return false | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Views.CondsCard = Backbone.View.extend({ | |
initialize: function(b) { | |
this.options = b || {}; | |
this.models = this.options.models || {}; | |
this.models.weather = this.createWeatherModel(); | |
this.models.weather.fetch(); | |
this.listenToOnce(this.models.weather, "sync", this.render) | |
}, | |
createWeatherModel: function() { | |
var c = wui.bootstrapped.prefs; | |
var d = this.options.geoip_lat + "," + this.options.geoip_lon; | |
if (this.options.geoip_lat == "0.00" && this.options.geoip_lon == "0.00") { | |
d = "94101.1.99999" | |
} | |
if (this.options.home_zmw.length > 0 && this.options.home_zmw != "") { | |
d = this.options.home_zmw | |
} | |
var b = new wui.Models.Weather({},{ | |
apikey: "8dee7a0127c63e7f", | |
lang: c.LangCode, | |
query: d, | |
features: ["forecast10day", "conditions"], | |
units: c.Units, | |
version: "2.0" | |
}); | |
return b | |
}, | |
render: function() { | |
this.template = _.template(a("script#conditions-card-template").html()); | |
var c = { | |
weather: this.models.weather.attributes | |
}; | |
var b = this.template(c); | |
this.$el.removeClass("placeholder"); | |
this.$el.find(".react-wrapper").html(b); | |
return this | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Views.UstreamTDUView = Backbone.View.extend({ | |
events: { | |
"click .close": "onClose" | |
}, | |
initialize: function() { | |
if (typeof (UstreamEmbed) != "undefined") { | |
this.viewer = UstreamEmbed(this.$el.find("iframe").attr("id")); | |
this.islive = false; | |
var b = this; | |
this.viewer.addListener("live", function() { | |
b.itsAlive() | |
}); | |
this.viewer.addListener("playing", function() { | |
b.itsAlive() | |
}); | |
this.viewer.addListener("offline", function() { | |
b.hesDeadJim() | |
}) | |
} | |
}, | |
itsAlive: function() { | |
if (!this.islive) { | |
this.islive = true; | |
this.viewer.removeListener("live"); | |
this.viewer.removeListener("playing"); | |
this.viewer.removeListener("offline"); | |
this.$el.remove(); | |
wui.page.headerTDU = a("#header-alert-bar").addClass("downpour-tdu").removeClass("not-found"); | |
var b = '<div class="tdu-wrap"><a href="/live-forecasts" target="_blank" class="white-text non-bold">' + wui.bootstrapped.dailyDownpourText + '</a><span class="close">x</span></div>'; | |
wui.page.headerTDU.html(b); | |
wui.page.headerTDU.on("click", ".close", this.onClose); | |
a(".new-badge-text-only.twiw").show(); | |
a(window).trigger("resize") | |
} | |
}, | |
hesDeadJim: function() {}, | |
onClose: function(b) { | |
if (this.viewer) { | |
this.viewer.removeListener("live"); | |
this.viewer.removeListener("playing"); | |
this.viewer.removeListener("offline") | |
} | |
wui.page.headerTDU.removeClass("active downpour-tdu") | |
} | |
}) | |
})(jQuery); | |
(function(a) { | |
if (!window.Backbone) { | |
return | |
} | |
wui.Views.AlertModule = Backbone.View.extend({ | |
events: { | |
"submit #alert-form": "onSubscribe" | |
}, | |
initialize: function(c) { | |
this.options = c || {}; | |
this.model = c.model; | |
this.type = c.type; | |
this.typeData = {}; | |
this.$alerts = a("#alerts-location"); | |
if (this.$alerts[0]) { | |
var b = new wui.autocomplete({ | |
autosubmit: false, | |
autoFocus: true, | |
data: { | |
ski: 1, | |
features: 0 | |
}, | |
includeFavorites: false, | |
includePWS: false, | |
includeHeaderGeoLocate: false, | |
includeRecents: true, | |
includePopular: true, | |
includeOnlyCities: true, | |
includeOnlyUS: false, | |
input: "#alerts-location", | |
maxResults: 10, | |
minLength: 0, | |
showConditions: false, | |
showFavoriteStars: false, | |
appendTo: "#autocomplete-wrap" | |
}) | |
} | |
if (this.model) { | |
this.listenTo(this.model, "change:success", this.checkReady); | |
this.checkReady() | |
} | |
}, | |
checkReady: function() { | |
if (typeof this.model.get("forecast") !== "undefined") { | |
this.typeData = this.model.get(this.type); | |
this.render() | |
} | |
}, | |
render: function() { | |
var b = this.typeData.activeCity; | |
if (!b) { | |
a("#alerts-hook").show() | |
} | |
}, | |
onSubscribe: function(h) { | |
h.preventDefault(); | |
var f = this; | |
var g = this.$alerts.val(); | |
var c = "//api.wunderground.com/api/260773b24515a709/geolookup/alerts/q/" + g + ".json"; | |
var j = a(".alert-error"); | |
var d = a(".alert-email-error"); | |
var l = a("#alerts-location"); | |
var k = a("#alerts-email"); | |
var i = k.val(); | |
j.html("").hide(); | |
d.html("").hide(); | |
l.removeClass("has-error"); | |
k.removeClass("has-error"); | |
var m = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; | |
var b = m.test(i); | |
if (!b) { | |
d.html("Please enter a valid email address.").show(); | |
k.addClass("has-error"); | |
return false | |
} | |
a.ajax({ | |
url: c, | |
dataType: "json", | |
complete: function(q) { | |
var o = JSON.parse(q.responseText); | |
if (o.response.error) { | |
j.html("Location not found"); | |
j.show(); | |
l.addClass("has-error") | |
} else { | |
if (o.response.results) { | |
if (o.response.results.length > 1) { | |
j.html("Location not found"); | |
j.show(); | |
l.addClass("has-error") | |
} | |
} else { | |
if (o.location) { | |
var s = o.location; | |
var r = {}; | |
var n = a("#alerts-hook").hasClass("alert-severe"); | |
if (a.inArray(p, f.model.get("cities")) > -1) { | |
j.html("You've already signed up for this city."); | |
l.addClass("has-error"); | |
return | |
} | |
var p = s.city; | |
var t = s.state; | |
var e = s.country_name; | |
var u = t + o.query_zone; | |
var v = "periods=ALL&SVR=0"; | |
if (s.type !== "INTLCITY") { | |
if (s.state) { | |
p += ", " + s.state | |
} else { | |
if (s.country) { | |
p += ", " + s.country | |
} | |
} | |
} | |
if (s.country_name === "USA") { | |
e = "United States" | |
} | |
if (n) { | |
v = "periods=NON&SVR=1" | |
} | |
a.ajax({ | |
url: "/member/sendemailvalidationcode?altemail=" + i + "&zip=" + s.zip + "&magic=" + s.magic + "&zone=" + u + "&country=" + e + "&cityname=" + p + "&" + v + "&lat=" + s.lat + "&lon=" + s.lon, | |
dataType: "json", | |
complete: function(A) { | |
var z = JSON.parse(A.responseText); | |
var y = false; | |
var w = z.status === "error" && z.errors; | |
if (w) { | |
for (var x = 0; x < z.errors.length; x++) { | |
if (z.errors[x].error_code === "already_valid") { | |
y = true | |
} | |
} | |
} | |
if (y) { | |
a("#default-message").hide() | |
} else { | |
a("#alt-message").hide() | |
} | |
a("#alert-form").hide(); | |
a("#alert-thank-you").addClass("email-validated").show() | |
} | |
}) | |
} | |
} | |
} | |
} | |
}); | |
return false | |
} | |
}) | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment