Commit 803524907b223eb5b0d95820072b26c1f2d47f6b

Authored by Goutte
1 parent 5a6d4498

Multi model support and lots of refacto and fixes.

config.yml
... ... @@ -64,7 +64,8 @@ targets:
64 64 name: 'Mercury'
65 65 title: 'Mercury (coming soon)'
66 66 orbit:
67   - model: 'mercury_orb_all'
  67 + models:
  68 + - slug: 'mercury_orb_all'
68 69 models:
69 70 - slug: 'tao_mercury_sw'
70 71 started_at: "1990-01-01T01:30:00"
... ... @@ -76,7 +77,8 @@ targets:
76 77 name: 'Venus'
77 78 title: 'Venus'
78 79 orbit:
79   - model: 'venus_orb_all'
  80 + models:
  81 + - slug: 'venus_orb_all'
80 82 semimajor: 0.72333199
81 83 semiminor: 0.7233154
82 84 models:
... ... @@ -90,7 +92,8 @@ targets:
90 92 name: 'Earth'
91 93 title: 'Earth (coming soon)'
92 94 orbit:
93   - model: 'earth_orb_all'
  95 + models:
  96 + - slug: 'earth_orb_all'
94 97 #model: 'tao_earth_sw'
95 98 locked: true
96 99 default: true
... ... @@ -103,7 +106,8 @@ targets:
103 106 started_at: "1990-01-01T01:30:00"
104 107 stopped_at: "2017-02-19T00:00:00"
105 108 orbit:
106   - model: 'mars_orb_all'
  109 + models:
  110 + - slug: 'mars_orb_all'
107 111 semimajor: 1.52366231
108 112 semiminor: 1.51700011
109 113 locked: false
... ... @@ -116,10 +120,14 @@ targets:
116 120 - slug: 'tao_jup_sw'
117 121 started_at: "1990-01-01T01:30:00"
118 122 stopped_at: "2017-02-19T00:00:00"
  123 + - slug: 'tao_jup_swrt'
  124 + started_at: "2017-01-01T00:00:00"
  125 + stopped_at: ~
119 126 # started_at: "1990-01-01T01:30:00"
120 127 # stopped_at: "2017-02-19T00:00:00"
121 128 orbit:
122   - model: 'jupiter_orb_all'
  129 + models:
  130 + - slug: 'jupiter_orb_all'
123 131 semimajor: 5.45516759
124 132 semiminor: 4.95155843
125 133 locked: false
... ... @@ -129,7 +137,8 @@ targets:
129 137 name: 'Saturn'
130 138 title: 'Saturn'
131 139 orbit:
132   - model: 'saturn_orb_all'
  140 + models:
  141 + - slug: 'saturn_orb_all'
133 142 semimajor: 9.53707032
134 143 semiminor: 9.5230773
135 144 models:
... ... @@ -143,7 +152,8 @@ targets:
143 152 name: 'Rosetta'
144 153 title: 'Rosetta (coming soon)'
145 154 orbit:
146   - model: 'ros_orb_cruise'
  155 + models:
  156 + - slug: 'ros_orb_cruise'
147 157 models:
148 158 - slug: 'tao_ros_sw'
149 159 started_at: "1990-01-01T01:30:00"
... ... @@ -155,7 +165,8 @@ targets:
155 165 name: 'Juno'
156 166 title: 'Juno (coming soon)'
157 167 orbit:
158   - model: 'juno_cruise_all'
  168 + models:
  169 + - slug: 'juno_cruise_all'
159 170 models:
160 171 - slug: 'tao_juno_sw'
161 172 started_at: "1990-01-01T01:30:00"
... ... @@ -164,10 +175,11 @@ targets:
164 175 default: false
165 176 - type: 'comet'
166 177 slug: 'tchouri'
167   - name: 'Tchouri'
168   - title: 'Tchouri (coming soon)'
  178 + name: 'Churyumov-Gerasimenko'
  179 + title: 'Churyumov-Gerasimenko (coming soon)'
169 180 orbit:
170   - model: 'p67_orb_all'
  181 + models:
  182 + - slug: 'p67_orb_all'
171 183 locked: true
172 184 default: false
173 185  
... ...
web/run.py
... ... @@ -169,7 +169,8 @@ def is_list_in_list(needle, haystack):
169 169 def datetime_from_list(time_list):
170 170 """
171 171 Datetimes in retrieved CDFs are stored as lists of numbers,
172   - with DayOfYear starting at 0. We want it starting at 1 for default parsers.
  172 + with DayOfYear starting at 0. We want it starting at 1 because it's what
  173 + vendor parsers use, both in python and javascript.
173 174 """
174 175 # Day Of Year starts at 0, but for our datetime parser it starts at 1
175 176 doy = '{:03d}'.format(int(''.join(time_list[4:7])) + 1)
... ... @@ -222,7 +223,8 @@ def retrieve_amda_netcdf(orbiter, what, started_at, stopped_at):
222 223 if remote_gzip_files == 'ERROR':
223 224 raise Exception("API returned an error at '%s'." % url)
224 225 if remote_gzip_files == ['OUTOFTIME']: # it happens
225   - raise Exception("API says it's out of time at '%s'." % url)
  226 + return []
  227 + # raise Exception("API says it's out of time at '%s'." % url)
226 228 success = True
227 229 except Exception as e:
228 230 log.warn("Failed (%d/3) '%s' : %s" % (retries+1, url, e.message))
... ... @@ -244,7 +246,7 @@ def retrieve_amda_netcdf(orbiter, what, started_at, stopped_at):
244 246 if remote_gzip_file in ['OUTOFTIME', 'ERROR']:
245 247 continue # sometimes half the response is okay, the other not
246 248 if remote_gzip_file.endswith('/.gz'):
247   - continue
  249 + continue # this is just a plain bug
248 250 remote_gzip_file = remote_gzip_file.replace('cdpp1', 'cdpp', 1)
249 251 ################################################
250 252 filename = "%s_%s" % (orbiter, str(remote_gzip_file).split('/')[-1])
... ... @@ -276,14 +278,15 @@ def retrieve_amda_netcdf(orbiter, what, started_at, stopped_at):
276 278 return local_netc_files
277 279  
278 280  
279   -# The available parameters in the generated CSV and NetCDF files.
  281 +# The available parameters in the generated CSV files.
280 282 # The order matters. If you change this you also need to change the
281 283 # innermost loop of `get_data_for_target`.
282 284 # The javascript knows the targets' properties under these names.
283   -# DEPRECATED, use PARAMETERS instead
284 285 PROPERTIES = ('time', 'vrad', 'vtan', 'vlen', 'magn', 'temp', 'pdyn', 'dens',
285 286 'angl', 'xhci', 'yhci')
286 287  
  288 +# The parameters that the users can handle.
  289 +# The slug must be one of the properties above.
287 290 PARAMETERS = {
288 291 'pdyn': {
289 292 'slug': 'pdyn',
... ... @@ -299,7 +302,7 @@ PARAMETERS = {
299 302 },
300 303 'magn': {
301 304 'slug': 'magn',
302   - 'name': 'Magnetism',
  305 + 'name': 'B Tangential',
303 306 'title': 'B Tangential.',
304 307 'units': 'nT',
305 308 },
... ... @@ -329,27 +332,39 @@ def get_data_for_target(target_config, started_at, stopped_at):
329 332 :return: dict whose keys are datetime as str, values tuples of data
330 333 """
331 334 log.debug("Grabbing data for '%s'..." % target_config['slug'])
332   - # @todo iterate on models when there are many
  335 +
333 336 try:
334   - model_slug = target_config['models'][0]['slug']
  337 + models = target_config['models']
335 338 except Exception as e:
336 339 abort(500, "Invalid model configuration for '%s' : %s"
337 340 % (target_config['slug'], str(e)))
338 341 try:
339   - orbit_slug = target_config['orbit']['model']
  342 + orbits = target_config['orbit']['models']
340 343 except Exception as e:
341 344 abort(500, "Invalid orbit configuration for '%s' : %s"
342 345 % (target_config['slug'], str(e)))
343 346  
344 347 # Grab the list of netCDF files from Myriam's API
345   - # http://cdpp.irap.omp.eu/BASE/DDService/getDataUrl.php?dataSet=jupiter_orb_all&StartTime=2014-02-23T10:00:10&StopTime=2017-02-24T23:59:00
346   - # http://cdpp.irap.omp.eu/BASE/DATA/TAO/JUPITER/SW/sw_2014.nc.gz
347   - model_files = retrieve_amda_netcdf(target_config['slug'], model_slug,
348   - started_at, stopped_at)
349   - orbit_files = retrieve_amda_netcdf(target_config['slug'], orbit_slug,
350   - started_at, stopped_at)
351   -
352   - precision = "%Y-%m-%dT%H" # model and orbits times are equal-ish
  348 + model_files = []
  349 + orbit_files = []
  350 + for model in models:
  351 + model_files = model_files + retrieve_amda_netcdf(
  352 + target_config['slug'], model['slug'], started_at, stopped_at
  353 + )
  354 + for orbit in orbits:
  355 + orbit_files = orbit_files + retrieve_amda_netcdf(
  356 + target_config['slug'], orbit['slug'], started_at, stopped_at
  357 + )
  358 + # Remove possible duplicates
  359 + model_files = set(model_files)
  360 + orbit_files = set(orbit_files)
  361 +
  362 + # if not len(model_files):
  363 + # abort(500, "No model files found for '%s'." % target_config['slug'])
  364 + # if not len(orbit_files):
  365 + # abort(500, "No orbit files found for '%s'." % target_config['slug'])
  366 +
  367 + precision = "%Y-%m-%dT%H" # model and orbits times are only equal-ish
353 368 orbit_data = {} # keys are datetime as str, values arrays of XY
354 369 for orbit_file in orbit_files:
355 370 log.debug("%s: opening orbit NETCDF4 '%s'..." %
... ... @@ -424,7 +439,19 @@ def generate_csv_file_if_needed(target_slug, started_at, stopped_at):
424 439 started_at.strftime(FILE_DATE_FMT),
425 440 stopped_at.strftime(FILE_DATE_FMT))
426 441 local_csv_file = get_path("../cache/%s" % filename)
427   - if not isfile(local_csv_file):
  442 +
  443 + generate = True
  444 + if isfile(local_csv_file):
  445 + # It need to have more than one line to not be empty (headers)
  446 + with open(local_csv_file) as f:
  447 + cnt = 0
  448 + for _ in f:
  449 + cnt += 1
  450 + if cnt > 1:
  451 + generate = False
  452 + break
  453 +
  454 + if generate:
428 455 log.info("Generating CSV '%s'..." % local_csv_file)
429 456 try:
430 457 with open(local_csv_file, mode="w+") as f:
... ...
web/static/css/main.css
... ... @@ -279,11 +279,17 @@ ul li {
279 279  
280 280 /** MEDIA QUERIES ************************************************************/
281 281  
282   -@media all and (max-width: 980px) {
283   - #page-container{
284   - width: 100%;
285   - }
286   -}
  282 +/*@media all and (max-width: 980px) {*/
  283 + /*#page-container{*/
  284 + /*width: 100%;*/
  285 + /*}*/
  286 +/*}*/
  287 +
  288 +/*@media all and (max-width: 1024px) {*/
  289 + /*.mdl-layout__drawer {*/
  290 + /*transform: translateX(0px);*/
  291 + /*}*/
  292 +/*}*/
287 293  
288 294 @media all and (max-width: 515px) {
289 295 dt { width: 130px; }
... ...
web/static/img/target/empty_128.png 0 โ†’ 100644

1.95 KB

web/static/js/swapp.js
... ... @@ -37,7 +37,7 @@
37 37 return this$.parameters[p['id']] = p;
38 38 });
39 39 this.orbiter = null;
40   - this.timeSeries = [];
  40 + this.time_series = [];
41 41 }
42 42 SpaceWeather.prototype.init = function(){
43 43 "This is called by the inline bootstrap javascript code.\nThis ain't in the constructor because it might return a Promise later on.\n(for the loader, for example)";
... ... @@ -82,7 +82,7 @@
82 82 };
83 83 SpaceWeather.prototype.enableTarget = function(target_slug){
84 84 var this$ = this;
85   - this.timeSeries.forEach(function(ts){
  85 + this.time_series.forEach(function(ts){
86 86 if (ts.target.slug === target_slug && this$.parameters[ts.parameter].active) {
87 87 return ts.show();
88 88 }
... ... @@ -91,7 +91,7 @@
91 91 return this;
92 92 };
93 93 SpaceWeather.prototype.disableTarget = function(target_slug){
94   - this.timeSeries.forEach(function(ts){
  94 + this.time_series.forEach(function(ts){
95 95 if (ts.target.slug === target_slug) {
96 96 return ts.hide();
97 97 }
... ... @@ -104,7 +104,7 @@
104 104 if ((ref$ = this.orbits) != null) {
105 105 ref$.resize();
106 106 }
107   - return this.timeSeries.forEach(function(ts){
  107 + return this.time_series.forEach(function(ts){
108 108 return ts.resize();
109 109 });
110 110 };
... ... @@ -132,10 +132,10 @@
132 132 return data[parameter['id']] = [];
133 133 });
134 134 if (!csv) {
135   - reject("CSV is empty or nonexistent at URL '" + url + "'.");
  135 + reject('invalid');
136 136 }
137 137 if (!csv.length) {
138   - reject("CSV is empty at '" + url + "'.");
  138 + reject('empty');
139 139 }
140 140 csv.forEach(function(d){
141 141 var dtime;
... ... @@ -161,7 +161,7 @@
161 161 });
162 162 };
163 163 SpaceWeather.prototype.loadAndCreatePlots = function(started_at, stopped_at){
164   - "started_at: moment(.js) object\nstopped_at: moment(.js) object";
  164 + "started_at: moment(.js) datetime object\nstopped_at: moment(.js) datetime object";
165 165 var k, this$ = this;
166 166 this.showLoader();
167 167 this.started_at = started_at;
... ... @@ -181,6 +181,7 @@
181 181 targetButton = $(".targets-filters .target." + target.slug);
182 182 targetButton.addClass('loading');
183 183 targetButton.removeClass('failed');
  184 + targetButton.removeClass('empty');
184 185 return this$.loadData(target.slug, started_at, stopped_at).then(function(data){
185 186 console.info("Loaded CSV data of " + target.name + ".", data);
186 187 this$.createTimeSeries(target, data);
... ... @@ -192,8 +193,19 @@
192 193 return this$.disableTarget(target.slug);
193 194 }
194 195 }, function(error){
195   - console.error("Failed loading CSV data of " + target.name + ".", error);
196   - alert("There was an error with " + target.name + ".\nPlease retry.");
  196 + var msg;
  197 + switch (error) {
  198 + case 'invalid':
  199 + console.error("Failed loading CSV data of " + target.name + ".");
  200 + alert("There was an error with " + target.name + ".\nPlease retry in a few moments.");
  201 + this$.is_invalid = true;
  202 + break;
  203 + case 'empty':
  204 + msg = "No data for " + target.name + "\n during interval from \n" + started_at + " to " + stopped_at + ".";
  205 + console.warn(msg);
  206 + targetButton.addClass('empty');
  207 + break;
  208 + }
197 209 targetButton.addClass('failed');
198 210 targetButton.removeClass('loading');
199 211 return this$.hideLoader();
... ... @@ -202,11 +214,11 @@
202 214 };
203 215 SpaceWeather.prototype.clearPlots = function(){
204 216 this.orbits.clear();
205   - this.timeSeries.forEach(function(ts){
  217 + this.time_series.forEach(function(ts){
206 218 return ts.clear();
207 219 });
208 220 this.orbits = null;
209   - this.timeSeries = [];
  221 + this.time_series = [];
210 222 return this;
211 223 };
212 224 SpaceWeather.prototype.createTimeSeries = function(target, data){
... ... @@ -219,24 +231,24 @@
219 231 if (!(id in data)) {
220 232 console.error("No data for id '" + id + "'.", data);
221 233 }
222   - return this$.timeSeries.push(new TimeSeries(id, title, target, data[id], this$.parameters[id].active, container));
  234 + return this$.time_series.push(new TimeSeries(id, title, target, data[id], this$.parameters[id].active, container));
223 235 });
224   - this.timeSeries.forEach(function(ts){
  236 + this.time_series.forEach(function(ts){
225 237 ts.options['onMouseOver'] = function(){
226   - this$.timeSeries.forEach(function(ts2){
  238 + this$.time_series.forEach(function(ts2){
227 239 return ts2.showCursor();
228 240 });
229 241 return true;
230 242 };
231 243 ts.options['onMouseOut'] = function(){
232   - this$.timeSeries.forEach(function(ts2){
  244 + this$.time_series.forEach(function(ts2){
233 245 return ts2.hideCursor();
234 246 });
235 247 return true;
236 248 };
237 249 ts.options['onMouseMove'] = function(t){
238 250 var ref$;
239   - this$.timeSeries.forEach(function(ts2){
  251 + this$.time_series.forEach(function(ts2){
240 252 return ts2.moveCursor(t);
241 253 });
242 254 if ((ref$ = this$.orbits) != null) {
... ... @@ -257,7 +269,7 @@
257 269 return true;
258 270 };
259 271 });
260   - return this.timeSeries;
  272 + return this.time_series;
261 273 };
262 274 SpaceWeather.prototype.enableParameter = function(parameter_slug){
263 275 var this$ = this;
... ... @@ -265,7 +277,7 @@
265 277 console.error("Unknown parameter " + parameter_slug + ".");
266 278 }
267 279 this.parameters[parameter_slug].active = true;
268   - this.timeSeries.forEach(function(ts){
  280 + this.time_series.forEach(function(ts){
269 281 if (ts.parameter === parameter_slug && this$.targets[ts.target.slug].active) {
270 282 return ts.show();
271 283 }
... ... @@ -277,7 +289,7 @@
277 289 console.error("Unknown parameter " + parameter_slug + ".");
278 290 }
279 291 this.parameters[parameter_slug].active = false;
280   - this.timeSeries.forEach(function(ts){
  292 + this.time_series.forEach(function(ts){
281 293 if (ts.parameter === parameter_slug) {
282 294 return ts.hide();
283 295 }
... ... @@ -307,20 +319,21 @@
307 319 this.setStartAndStop(started_at, stopped_at);
308 320 formatted_started_at = started_at.format();
309 321 formatted_stopped_at = stopped_at.format();
310   - if ((this.started_at <= started_at && started_at <= this.stopped_at) && (this.started_at <= stopped_at && stopped_at <= this.stopped_at)) {
  322 + if (!this.is_invalid && (this.started_at <= started_at && started_at <= this.stopped_at) && (this.started_at <= stopped_at && stopped_at <= this.stopped_at)) {
311 323 console.info("Resizing the temporal domain from " + formatted_started_at + " to " + formatted_stopped_at + " without fetching new dataโ€ฆ");
312   - this.timeSeries.forEach(function(ts){
  324 + this.time_series.forEach(function(ts){
313 325 if (!ts.visible) {
314 326 return ts.zoomIn(started_at, stopped_at);
315 327 }
316 328 });
317   - this.timeSeries.forEach(function(ts){
  329 + this.time_series.forEach(function(ts){
318 330 if (ts.visible) {
319 331 return ts.zoomIn(started_at, stopped_at);
320 332 }
321 333 });
322 334 this.orbits.resizeDomain(started_at, stopped_at);
323 335 } else {
  336 + this.is_invalid = false;
324 337 console.info("Resizing the temporal domain from " + formatted_started_at + " to " + formatted_stopped_at + " and fetching new dataโ€ฆ");
325 338 console.warn("This might take a whileโ€ฆ Why not see what else we're up to on http://cdpp.eu while you're waiting?");
326 339 this.clearPlots();
... ... @@ -329,7 +342,7 @@
329 342 return this;
330 343 };
331 344 SpaceWeather.prototype.resetZoom = function(){
332   - this.timeSeries.forEach(function(ts){
  345 + this.time_series.forEach(function(ts){
333 346 return ts.resetZoom();
334 347 });
335 348 this.orbits.resetZoom();
... ...
web/static/js/swapp.ls
... ... @@ -63,8 +63,8 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE
63 63 @configuration['parameters'].forEach((p) ~>
64 64 @parameters[p['id']] = p
65 65 )
66   - @orbiter = null # our Orbiter
67   - @timeSeries = [] # a List of TimeSeries objects
  66 + @orbiter = null # our Orbiter defined below
  67 + @time_series = [] # a List of TimeSeries objects
68 68  
69 69 init: ->
70 70 """
... ... @@ -107,18 +107,18 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE
107 107 # this
108 108  
109 109 enableTarget: (target_slug) ->
110   - @timeSeries.forEach((ts) ~> ts.show() if ts.target.slug == target_slug && @parameters[ts.parameter].active)
  110 + @time_series.forEach((ts) ~> ts.show() if ts.target.slug == target_slug && @parameters[ts.parameter].active)
111 111 @targets[target_slug].active = true
112 112 this
113 113  
114 114 disableTarget: (target_slug) ->
115   - @timeSeries.forEach((ts) -> ts.hide() if ts.target.slug == target_slug)
  115 + @time_series.forEach((ts) -> ts.hide() if ts.target.slug == target_slug)
116 116 @targets[target_slug].active = false
117 117 this
118 118  
119 119 resize: ->
120 120 @orbits?.resize();
121   - @timeSeries.forEach((ts) -> ts.resize())
  121 + @time_series.forEach((ts) -> ts.resize())
122 122  
123 123 showLoader: ->
124 124 $('#plots_loader').show();
... ... @@ -142,8 +142,8 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE
142 142 configuration['parameters'].forEach((parameter) ->
143 143 data[parameter['id']] = []
144 144 )
145   - unless csv then reject "CSV is empty or nonexistent at URL '#{url}'."
146   - unless csv.length then reject "CSV is empty at '#{url}'."
  145 + unless csv then reject 'invalid'
  146 + unless csv.length then reject 'empty'
147 147 csv.forEach((d) ->
148 148 dtime = timeFormat(d['time'])
149 149 configuration['parameters'].forEach((parameter) ->
... ... @@ -161,8 +161,8 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE
161 161  
162 162 loadAndCreatePlots: (started_at, stopped_at) ->
163 163 """
164   - started_at: moment(.js) object
165   - stopped_at: moment(.js) object
  164 + started_at: moment(.js) datetime object
  165 + stopped_at: moment(.js) datetime object
166 166 """
167 167 @showLoader()
168 168 @started_at = started_at
... ... @@ -176,6 +176,7 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE
176 176 targetButton = $(".targets-filters .target.#{target.slug}")
177 177 targetButton.addClass('loading')
178 178 targetButton.removeClass('failed')
  179 + targetButton.removeClass('empty') # fixme
179 180 @loadData(target.slug, started_at, stopped_at).then(
180 181 (data) ~>
181 182 console.info "Loaded CSV data of #{target.name}.", data
... ... @@ -185,21 +186,32 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE
185 186 if target.active then @hideLoader() else @disableTarget(target.slug)
186 187 ,
187 188 (error) ~>
188   - # Sometimes, AMDA's API returns garbage, so the CSV sometime fails
189   - # But when we re-generate it a second time, usually it's okay.
190   - console.error("Failed loading CSV data of #{target.name}.", error)
191   - alert("There was an error with #{target.name}.\nPlease retry.")
  189 + switch error
  190 + case 'invalid'
  191 + console.error("Failed loading CSV data of #{target.name}.")
  192 + # Sometimes, AMDA's API returns garbage, so the CSV sometime fails
  193 + # But when we re-generate it a second time, usually it's okay.
  194 + alert("There was an error with #{target.name}.\nPlease retry in a few moments.")
  195 + @is_invalid = true
  196 + break
  197 + case 'empty'
  198 + msg = "No data for #{target.name}\n during interval from \n#{started_at} to #{stopped_at}."
  199 + console.warn(msg)
  200 + targetButton.addClass('empty')
  201 +# alert(msg)
  202 + break
192 203 targetButton.addClass('failed')
193 204 targetButton.removeClass('loading')
194 205 @hideLoader()
  206 +
195 207 )
196 208 )
197 209  
198 210 clearPlots: ->
199 211 @orbits.clear()
200   - @timeSeries.forEach((ts) -> ts.clear())
  212 + @time_series.forEach((ts) -> ts.clear())
201 213 @orbits = null
202   - @timeSeries = [] # do we de-reference everything ? listeners ? #memleak?
  214 + @time_series = [] # do we de-reference everything ? listeners ? #memleak?
203 215 this
204 216  
205 217 createTimeSeries: (target, data) ->
... ... @@ -207,35 +219,35 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE
207 219 container = @configuration['time_series_container']
208 220 id = parameter['id'] ; title = parameter['title']
209 221 if id not of data then console.error("No data for id '#{id}'.", data)
210   - @timeSeries.push(new TimeSeries(
  222 + @time_series.push(new TimeSeries(
211 223 id, title, target, data[id], @parameters[id].active, container
212 224 ))
213 225 )
214   - @timeSeries.forEach((ts) ~> # returning true may be faster
  226 + @time_series.forEach((ts) ~> # returning true may be faster
215 227 ts.options['onMouseOver'] = ~>
216   - @timeSeries.forEach((ts2) -> ts2.showCursor()) ; true
  228 + @time_series.forEach((ts2) -> ts2.showCursor()) ; true
217 229 ts.options['onMouseOut'] = ~>
218   - @timeSeries.forEach((ts2) -> ts2.hideCursor()) ; true
  230 + @time_series.forEach((ts2) -> ts2.hideCursor()) ; true
219 231 ts.options['onMouseMove'] = (t) ~>
220   - @timeSeries.forEach((ts2) -> ts2.moveCursor(t))
  232 + @time_series.forEach((ts2) -> ts2.moveCursor(t))
221 233 @orbits?.moveToDate(t) ; true
222 234 ts.options['onBrushEnd'] = (sta, sto) ~>
223 235 @resizeDomain(moment(sta), moment(sto)) ; true
224 236 ts.options['onDblClick'] = ~>
225 237 @resetZoom() ; $("\#zoom_controls_help")?.remove() ; true
226 238 )
227   - @timeSeries
  239 + @time_series
228 240  
229 241 enableParameter: (parameter_slug) ->
230 242 if parameter_slug not of @parameters then console.error("Unknown parameter #{parameter_slug}.")
231 243 @parameters[parameter_slug].active = true
232   - @timeSeries.forEach((ts) ~> ts.show() if ts.parameter == parameter_slug && @targets[ts.target.slug].active)
  244 + @time_series.forEach((ts) ~> ts.show() if ts.parameter == parameter_slug && @targets[ts.target.slug].active)
233 245 this
234 246  
235 247 disableParameter: (parameter_slug) ->
236 248 if parameter_slug not of @parameters then console.error("Unknown parameter #{parameter_slug}.")
237 249 @parameters[parameter_slug].active = false
238   - @timeSeries.forEach((ts) -> ts.hide() if ts.parameter == parameter_slug)
  250 + @time_series.forEach((ts) -> ts.hide() if ts.parameter == parameter_slug)
239 251 this
240 252  
241 253 getDomain: ->
... ... @@ -258,15 +270,17 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE
258 270 formatted_started_at = started_at.format()
259 271 formatted_stopped_at = stopped_at.format()
260 272  
261   - if (@started_at <= started_at <= @stopped_at) and
  273 + if (not @is_invalid) and
  274 + (@started_at <= started_at <= @stopped_at) and
262 275 (@started_at <= stopped_at <= @stopped_at) then
263 276 console.info "Resizing the temporal domain from #{formatted_started_at} to #{formatted_stopped_at} without fetching new dataโ€ฆ"
264 277 # We first resize the hidden time series and only afterwards we resize
265 278 # the visible ones, for a smoother transition.
266   - @timeSeries.forEach((ts) -> if not ts.visible then ts.zoomIn(started_at, stopped_at))
267   - @timeSeries.forEach((ts) -> if ts.visible then ts.zoomIn(started_at, stopped_at))
  279 + @time_series.forEach((ts) -> if not ts.visible then ts.zoomIn(started_at, stopped_at))
  280 + @time_series.forEach((ts) -> if ts.visible then ts.zoomIn(started_at, stopped_at))
268 281 @orbits.resizeDomain started_at, stopped_at
269 282 else
  283 + @is_invalid = false
270 284 console.info "Resizing the temporal domain from #{formatted_started_at} to #{formatted_stopped_at} and fetching new dataโ€ฆ"
271 285 console.warn "This might take a whileโ€ฆ Why not see what else we're up to on http://cdpp.eu while you're waiting?"
272 286 # fetch new data and remake the plots
... ... @@ -276,7 +290,7 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE
276 290 this
277 291  
278 292 resetZoom: ->
279   - @timeSeries.forEach((ts) -> ts.resetZoom())
  293 + @time_series.forEach((ts) -> ts.resetZoom())
280 294 @orbits.resetZoom()
281 295 @setStartAndStop(@started_at, @stopped_at)
282 296 this
... ...
web/static/js/vendor/d3-custom.js
... ... @@ -4482,7 +4482,7 @@ function brush$1(dim) {
4482 4482 }
4483 4483 point = point1;
4484 4484 moving = true;
4485   - //noevent$1();
  4485 + //noevent$1(); // enable event bubbling
4486 4486 move();
4487 4487 }
4488 4488  
... ...
web/static/js/vendor/material.js renamed to web/static/js/vendor/material-custom.js
1 1 ;(function() {
2 2 "use strict";
3 3  
4   -/**
  4 +/** CHANGED LINE 3381, the container is such buggy voodoo
5 5 * @license
6 6 * Copyright 2015 Google Inc. All Rights Reserved.
7 7 *
... ... @@ -3378,7 +3378,7 @@ MaterialLayout.prototype[&#39;toggleDrawer&#39;] = MaterialLayout.prototype.toggleDrawer
3378 3378 MaterialLayout.prototype.init = function () {
3379 3379 if (this.element_) {
3380 3380 var container = document.createElement('div');
3381   - container.classList.add(this.CssClasses_.CONTAINER);
  3381 + container.classList.add(this.CssClasses_.CONTAINER + '-nobug'); // here
3382 3382 var focusedElement = this.element_.querySelector(':focus');
3383 3383 this.element_.parentElement.insertBefore(container, this.element_);
3384 3384 this.element_.parentElement.removeChild(this.element_);
... ...
web/static/js/vendor/material.min.js deleted
... ... @@ -1,10 +0,0 @@
1   -/**
2   - * material-design-lite - Material Design Components in CSS, JS and HTML
3   - * @version v1.3.0
4   - * @license Apache-2.0
5   - * @copyright 2015 Google, Inc.
6   - * @link https://github.com/google/material-design-lite
7   - */
8   -!function(){"use strict";function e(e,t){if(e){if(t.element_.classList.contains(t.CssClasses_.MDL_JS_RIPPLE_EFFECT)){var s=document.createElement("span");s.classList.add(t.CssClasses_.MDL_RIPPLE_CONTAINER),s.classList.add(t.CssClasses_.MDL_JS_RIPPLE_EFFECT);var i=document.createElement("span");i.classList.add(t.CssClasses_.MDL_RIPPLE),s.appendChild(i),e.appendChild(s)}e.addEventListener("click",function(s){if("#"===e.getAttribute("href").charAt(0)){s.preventDefault();var i=e.href.split("#")[1],n=t.element_.querySelector("#"+i);t.resetTabState_(),t.resetPanelState_(),e.classList.add(t.CssClasses_.ACTIVE_CLASS),n.classList.add(t.CssClasses_.ACTIVE_CLASS)}})}}function t(e,t,s,i){function n(){var n=e.href.split("#")[1],a=i.content_.querySelector("#"+n);i.resetTabState_(t),i.resetPanelState_(s),e.classList.add(i.CssClasses_.IS_ACTIVE),a.classList.add(i.CssClasses_.IS_ACTIVE)}if(i.tabBar_.classList.contains(i.CssClasses_.JS_RIPPLE_EFFECT)){var a=document.createElement("span");a.classList.add(i.CssClasses_.RIPPLE_CONTAINER),a.classList.add(i.CssClasses_.JS_RIPPLE_EFFECT);var l=document.createElement("span");l.classList.add(i.CssClasses_.RIPPLE),a.appendChild(l),e.appendChild(a)}i.tabBar_.classList.contains(i.CssClasses_.TAB_MANUAL_SWITCH)||e.addEventListener("click",function(t){"#"===e.getAttribute("href").charAt(0)&&(t.preventDefault(),n())}),e.show=n}var s={upgradeDom:function(e,t){},upgradeElement:function(e,t){},upgradeElements:function(e){},upgradeAllRegistered:function(){},registerUpgradedCallback:function(e,t){},register:function(e){},downgradeElements:function(e){}};s=function(){function e(e,t){for(var s=0;s<c.length;s++)if(c[s].className===e)return"undefined"!=typeof t&&(c[s]=t),c[s];return!1}function t(e){var t=e.getAttribute("data-upgraded");return null===t?[""]:t.split(",")}function s(e,s){var i=t(e);return i.indexOf(s)!==-1}function i(e,t,s){if("CustomEvent"in window&&"function"==typeof window.CustomEvent)return new CustomEvent(e,{bubbles:t,cancelable:s});var i=document.createEvent("Events");return i.initEvent(e,t,s),i}function n(t,s){if("undefined"==typeof t&&"undefined"==typeof s)for(var i=0;i<c.length;i++)n(c[i].className,c[i].cssClass);else{var l=t;if("undefined"==typeof s){var o=e(l);o&&(s=o.cssClass)}for(var r=document.querySelectorAll("."+s),_=0;_<r.length;_++)a(r[_],l)}}function a(n,a){if(!("object"==typeof n&&n instanceof Element))throw new Error("Invalid argument provided to upgrade MDL element.");var l=i("mdl-componentupgrading",!0,!0);if(n.dispatchEvent(l),!l.defaultPrevented){var o=t(n),r=[];if(a)s(n,a)||r.push(e(a));else{var _=n.classList;c.forEach(function(e){_.contains(e.cssClass)&&r.indexOf(e)===-1&&!s(n,e.className)&&r.push(e)})}for(var d,h=0,u=r.length;h<u;h++){if(d=r[h],!d)throw new Error("Unable to find a registered component for the given class.");o.push(d.className),n.setAttribute("data-upgraded",o.join(","));var E=new d.classConstructor(n);E[C]=d,p.push(E);for(var m=0,L=d.callbacks.length;m<L;m++)d.callbacks[m](n);d.widget&&(n[d.className]=E);var I=i("mdl-componentupgraded",!0,!1);n.dispatchEvent(I)}}}function l(e){Array.isArray(e)||(e=e instanceof Element?[e]:Array.prototype.slice.call(e));for(var t,s=0,i=e.length;s<i;s++)t=e[s],t instanceof HTMLElement&&(a(t),t.children.length>0&&l(t.children))}function o(t){var s="undefined"==typeof t.widget&&"undefined"==typeof t.widget,i=!0;s||(i=t.widget||t.widget);var n={classConstructor:t.constructor||t.constructor,className:t.classAsString||t.classAsString,cssClass:t.cssClass||t.cssClass,widget:i,callbacks:[]};if(c.forEach(function(e){if(e.cssClass===n.cssClass)throw new Error("The provided cssClass has already been registered: "+e.cssClass);if(e.className===n.className)throw new Error("The provided className has already been registered")}),t.constructor.prototype.hasOwnProperty(C))throw new Error("MDL component classes must not have "+C+" defined as a property.");var a=e(t.classAsString,n);a||c.push(n)}function r(t,s){var i=e(t);i&&i.callbacks.push(s)}function _(){for(var e=0;e<c.length;e++)n(c[e].className)}function d(e){if(e){var t=p.indexOf(e);p.splice(t,1);var s=e.element_.getAttribute("data-upgraded").split(","),n=s.indexOf(e[C].classAsString);s.splice(n,1),e.element_.setAttribute("data-upgraded",s.join(","));var a=i("mdl-componentdowngraded",!0,!1);e.element_.dispatchEvent(a)}}function h(e){var t=function(e){p.filter(function(t){return t.element_===e}).forEach(d)};if(e instanceof Array||e instanceof NodeList)for(var s=0;s<e.length;s++)t(e[s]);else{if(!(e instanceof Node))throw new Error("Invalid argument provided to downgrade MDL nodes.");t(e)}}var c=[],p=[],C="mdlComponentConfigInternal_";return{upgradeDom:n,upgradeElement:a,upgradeElements:l,upgradeAllRegistered:_,registerUpgradedCallback:r,register:o,downgradeElements:h}}(),s.ComponentConfigPublic,s.ComponentConfig,s.Component,s.upgradeDom=s.upgradeDom,s.upgradeElement=s.upgradeElement,s.upgradeElements=s.upgradeElements,s.upgradeAllRegistered=s.upgradeAllRegistered,s.registerUpgradedCallback=s.registerUpgradedCallback,s.register=s.register,s.downgradeElements=s.downgradeElements,window.componentHandler=s,window.componentHandler=s,window.addEventListener("load",function(){"classList"in document.createElement("div")&&"querySelector"in document&&"addEventListener"in window&&Array.prototype.forEach?(document.documentElement.classList.add("mdl-js"),s.upgradeAllRegistered()):(s.upgradeElement=function(){},s.register=function(){})}),Date.now||(Date.now=function(){return(new Date).getTime()},Date.now=Date.now);for(var i=["webkit","moz"],n=0;n<i.length&&!window.requestAnimationFrame;++n){var a=i[n];window.requestAnimationFrame=window[a+"RequestAnimationFrame"],window.cancelAnimationFrame=window[a+"CancelAnimationFrame"]||window[a+"CancelRequestAnimationFrame"],window.requestAnimationFrame=window.requestAnimationFrame,window.cancelAnimationFrame=window.cancelAnimationFrame}if(/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent)||!window.requestAnimationFrame||!window.cancelAnimationFrame){var l=0;window.requestAnimationFrame=function(e){var t=Date.now(),s=Math.max(l+16,t);return setTimeout(function(){e(l=s)},s-t)},window.cancelAnimationFrame=clearTimeout,window.requestAnimationFrame=window.requestAnimationFrame,window.cancelAnimationFrame=window.cancelAnimationFrame}var o=function(e){this.element_=e,this.init()};window.MaterialButton=o,o.prototype.Constant_={},o.prototype.CssClasses_={RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_CONTAINER:"mdl-button__ripple-container",RIPPLE:"mdl-ripple"},o.prototype.blurHandler_=function(e){e&&this.element_.blur()},o.prototype.disable=function(){this.element_.disabled=!0},o.prototype.disable=o.prototype.disable,o.prototype.enable=function(){this.element_.disabled=!1},o.prototype.enable=o.prototype.enable,o.prototype.init=function(){if(this.element_){if(this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)){var e=document.createElement("span");e.classList.add(this.CssClasses_.RIPPLE_CONTAINER),this.rippleElement_=document.createElement("span"),this.rippleElement_.classList.add(this.CssClasses_.RIPPLE),e.appendChild(this.rippleElement_),this.boundRippleBlurHandler=this.blurHandler_.bind(this),this.rippleElement_.addEventListener("mouseup",this.boundRippleBlurHandler),this.element_.appendChild(e)}this.boundButtonBlurHandler=this.blurHandler_.bind(this),this.element_.addEventListener("mouseup",this.boundButtonBlurHandler),this.element_.addEventListener("mouseleave",this.boundButtonBlurHandler)}},s.register({constructor:o,classAsString:"MaterialButton",cssClass:"mdl-js-button",widget:!0});var r=function(e){this.element_=e,this.init()};window.MaterialCheckbox=r,r.prototype.Constant_={TINY_TIMEOUT:.001},r.prototype.CssClasses_={INPUT:"mdl-checkbox__input",BOX_OUTLINE:"mdl-checkbox__box-outline",FOCUS_HELPER:"mdl-checkbox__focus-helper",TICK_OUTLINE:"mdl-checkbox__tick-outline",RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",RIPPLE_CONTAINER:"mdl-checkbox__ripple-container",RIPPLE_CENTER:"mdl-ripple--center",RIPPLE:"mdl-ripple",IS_FOCUSED:"is-focused",IS_DISABLED:"is-disabled",IS_CHECKED:"is-checked",IS_UPGRADED:"is-upgraded"},r.prototype.onChange_=function(e){this.updateClasses_()},r.prototype.onFocus_=function(e){this.element_.classList.add(this.CssClasses_.IS_FOCUSED)},r.prototype.onBlur_=function(e){this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},r.prototype.onMouseUp_=function(e){this.blur_()},r.prototype.updateClasses_=function(){this.checkDisabled(),this.checkToggleState()},r.prototype.blur_=function(){window.setTimeout(function(){this.inputElement_.blur()}.bind(this),this.Constant_.TINY_TIMEOUT)},r.prototype.checkToggleState=function(){this.inputElement_.checked?this.element_.classList.add(this.CssClasses_.IS_CHECKED):this.element_.classList.remove(this.CssClasses_.IS_CHECKED)},r.prototype.checkToggleState=r.prototype.checkToggleState,r.prototype.checkDisabled=function(){this.inputElement_.disabled?this.element_.classList.add(this.CssClasses_.IS_DISABLED):this.element_.classList.remove(this.CssClasses_.IS_DISABLED)},r.prototype.checkDisabled=r.prototype.checkDisabled,r.prototype.disable=function(){this.inputElement_.disabled=!0,this.updateClasses_()},r.prototype.disable=r.prototype.disable,r.prototype.enable=function(){this.inputElement_.disabled=!1,this.updateClasses_()},r.prototype.enable=r.prototype.enable,r.prototype.check=function(){this.inputElement_.checked=!0,this.updateClasses_()},r.prototype.check=r.prototype.check,r.prototype.uncheck=function(){this.inputElement_.checked=!1,this.updateClasses_()},r.prototype.uncheck=r.prototype.uncheck,r.prototype.init=function(){if(this.element_){this.inputElement_=this.element_.querySelector("."+this.CssClasses_.INPUT);var e=document.createElement("span");e.classList.add(this.CssClasses_.BOX_OUTLINE);var t=document.createElement("span");t.classList.add(this.CssClasses_.FOCUS_HELPER);var s=document.createElement("span");if(s.classList.add(this.CssClasses_.TICK_OUTLINE),e.appendChild(s),this.element_.appendChild(t),this.element_.appendChild(e),this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)){this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS),this.rippleContainerElement_=document.createElement("span"),this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER),this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT),this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER),this.boundRippleMouseUp=this.onMouseUp_.bind(this),this.rippleContainerElement_.addEventListener("mouseup",this.boundRippleMouseUp);var i=document.createElement("span");i.classList.add(this.CssClasses_.RIPPLE),this.rippleContainerElement_.appendChild(i),this.element_.appendChild(this.rippleContainerElement_)}this.boundInputOnChange=this.onChange_.bind(this),this.boundInputOnFocus=this.onFocus_.bind(this),this.boundInputOnBlur=this.onBlur_.bind(this),this.boundElementMouseUp=this.onMouseUp_.bind(this),this.inputElement_.addEventListener("change",this.boundInputOnChange),this.inputElement_.addEventListener("focus",this.boundInputOnFocus),this.inputElement_.addEventListener("blur",this.boundInputOnBlur),this.element_.addEventListener("mouseup",this.boundElementMouseUp),this.updateClasses_(),this.element_.classList.add(this.CssClasses_.IS_UPGRADED)}},s.register({constructor:r,classAsString:"MaterialCheckbox",cssClass:"mdl-js-checkbox",widget:!0});var _=function(e){this.element_=e,this.init()};window.MaterialIconToggle=_,_.prototype.Constant_={TINY_TIMEOUT:.001},_.prototype.CssClasses_={INPUT:"mdl-icon-toggle__input",JS_RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",RIPPLE_CONTAINER:"mdl-icon-toggle__ripple-container",RIPPLE_CENTER:"mdl-ripple--center",RIPPLE:"mdl-ripple",IS_FOCUSED:"is-focused",IS_DISABLED:"is-disabled",IS_CHECKED:"is-checked"},_.prototype.onChange_=function(e){this.updateClasses_()},_.prototype.onFocus_=function(e){this.element_.classList.add(this.CssClasses_.IS_FOCUSED)},_.prototype.onBlur_=function(e){this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},_.prototype.onMouseUp_=function(e){this.blur_()},_.prototype.updateClasses_=function(){this.checkDisabled(),this.checkToggleState()},_.prototype.blur_=function(){window.setTimeout(function(){this.inputElement_.blur()}.bind(this),this.Constant_.TINY_TIMEOUT)},_.prototype.checkToggleState=function(){this.inputElement_.checked?this.element_.classList.add(this.CssClasses_.IS_CHECKED):this.element_.classList.remove(this.CssClasses_.IS_CHECKED)},_.prototype.checkToggleState=_.prototype.checkToggleState,_.prototype.checkDisabled=function(){this.inputElement_.disabled?this.element_.classList.add(this.CssClasses_.IS_DISABLED):this.element_.classList.remove(this.CssClasses_.IS_DISABLED)},_.prototype.checkDisabled=_.prototype.checkDisabled,_.prototype.disable=function(){this.inputElement_.disabled=!0,this.updateClasses_()},_.prototype.disable=_.prototype.disable,_.prototype.enable=function(){this.inputElement_.disabled=!1,this.updateClasses_()},_.prototype.enable=_.prototype.enable,_.prototype.check=function(){this.inputElement_.checked=!0,this.updateClasses_()},_.prototype.check=_.prototype.check,_.prototype.uncheck=function(){this.inputElement_.checked=!1,this.updateClasses_()},_.prototype.uncheck=_.prototype.uncheck,_.prototype.init=function(){if(this.element_){if(this.inputElement_=this.element_.querySelector("."+this.CssClasses_.INPUT),this.element_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)){this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS),this.rippleContainerElement_=document.createElement("span"),this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER),this.rippleContainerElement_.classList.add(this.CssClasses_.JS_RIPPLE_EFFECT),this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER),this.boundRippleMouseUp=this.onMouseUp_.bind(this),this.rippleContainerElement_.addEventListener("mouseup",this.boundRippleMouseUp);var e=document.createElement("span");e.classList.add(this.CssClasses_.RIPPLE),this.rippleContainerElement_.appendChild(e),this.element_.appendChild(this.rippleContainerElement_)}this.boundInputOnChange=this.onChange_.bind(this),this.boundInputOnFocus=this.onFocus_.bind(this),this.boundInputOnBlur=this.onBlur_.bind(this),this.boundElementOnMouseUp=this.onMouseUp_.bind(this),this.inputElement_.addEventListener("change",this.boundInputOnChange),this.inputElement_.addEventListener("focus",this.boundInputOnFocus),this.inputElement_.addEventListener("blur",this.boundInputOnBlur),this.element_.addEventListener("mouseup",this.boundElementOnMouseUp),this.updateClasses_(),this.element_.classList.add("is-upgraded")}},s.register({constructor:_,classAsString:"MaterialIconToggle",cssClass:"mdl-js-icon-toggle",widget:!0});var d=function(e){this.element_=e,this.init()};window.MaterialMenu=d,d.prototype.Constant_={TRANSITION_DURATION_SECONDS:.3,TRANSITION_DURATION_FRACTION:.8,CLOSE_TIMEOUT:150},d.prototype.Keycodes_={ENTER:13,ESCAPE:27,SPACE:32,UP_ARROW:38,DOWN_ARROW:40},d.prototype.CssClasses_={CONTAINER:"mdl-menu__container",OUTLINE:"mdl-menu__outline",ITEM:"mdl-menu__item",ITEM_RIPPLE_CONTAINER:"mdl-menu__item-ripple-container",RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",RIPPLE:"mdl-ripple",IS_UPGRADED:"is-upgraded",IS_VISIBLE:"is-visible",IS_ANIMATING:"is-animating",BOTTOM_LEFT:"mdl-menu--bottom-left",BOTTOM_RIGHT:"mdl-menu--bottom-right",TOP_LEFT:"mdl-menu--top-left",TOP_RIGHT:"mdl-menu--top-right",UNALIGNED:"mdl-menu--unaligned"},d.prototype.init=function(){if(this.element_){var e=document.createElement("div");e.classList.add(this.CssClasses_.CONTAINER),this.element_.parentElement.insertBefore(e,this.element_),this.element_.parentElement.removeChild(this.element_),e.appendChild(this.element_),this.container_=e;var t=document.createElement("div");t.classList.add(this.CssClasses_.OUTLINE),this.outline_=t,e.insertBefore(t,this.element_);var s=this.element_.getAttribute("for")||this.element_.getAttribute("data-mdl-for"),i=null;s&&(i=document.getElementById(s),i&&(this.forElement_=i,i.addEventListener("click",this.handleForClick_.bind(this)),i.addEventListener("keydown",this.handleForKeyboardEvent_.bind(this))));var n=this.element_.querySelectorAll("."+this.CssClasses_.ITEM);this.boundItemKeydown_=this.handleItemKeyboardEvent_.bind(this),this.boundItemClick_=this.handleItemClick_.bind(this);for(var a=0;a<n.length;a++)n[a].addEventListener("click",this.boundItemClick_),n[a].tabIndex="-1",n[a].addEventListener("keydown",this.boundItemKeydown_);if(this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT))for(this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS),a=0;a<n.length;a++){var l=n[a],o=document.createElement("span");o.classList.add(this.CssClasses_.ITEM_RIPPLE_CONTAINER);var r=document.createElement("span");r.classList.add(this.CssClasses_.RIPPLE),o.appendChild(r),l.appendChild(o),l.classList.add(this.CssClasses_.RIPPLE_EFFECT)}this.element_.classList.contains(this.CssClasses_.BOTTOM_LEFT)&&this.outline_.classList.add(this.CssClasses_.BOTTOM_LEFT),this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)&&this.outline_.classList.add(this.CssClasses_.BOTTOM_RIGHT),this.element_.classList.contains(this.CssClasses_.TOP_LEFT)&&this.outline_.classList.add(this.CssClasses_.TOP_LEFT),this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)&&this.outline_.classList.add(this.CssClasses_.TOP_RIGHT),this.element_.classList.contains(this.CssClasses_.UNALIGNED)&&this.outline_.classList.add(this.CssClasses_.UNALIGNED),e.classList.add(this.CssClasses_.IS_UPGRADED)}},d.prototype.handleForClick_=function(e){if(this.element_&&this.forElement_){var t=this.forElement_.getBoundingClientRect(),s=this.forElement_.parentElement.getBoundingClientRect();this.element_.classList.contains(this.CssClasses_.UNALIGNED)||(this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)?(this.container_.style.right=s.right-t.right+"px",this.container_.style.top=this.forElement_.offsetTop+this.forElement_.offsetHeight+"px"):this.element_.classList.contains(this.CssClasses_.TOP_LEFT)?(this.container_.style.left=this.forElement_.offsetLeft+"px",this.container_.style.bottom=s.bottom-t.top+"px"):this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)?(this.container_.style.right=s.right-t.right+"px",this.container_.style.bottom=s.bottom-t.top+"px"):(this.container_.style.left=this.forElement_.offsetLeft+"px",this.container_.style.top=this.forElement_.offsetTop+this.forElement_.offsetHeight+"px"))}this.toggle(e)},d.prototype.handleForKeyboardEvent_=function(e){if(this.element_&&this.container_&&this.forElement_){var t=this.element_.querySelectorAll("."+this.CssClasses_.ITEM+":not([disabled])");t&&t.length>0&&this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)&&(e.keyCode===this.Keycodes_.UP_ARROW?(e.preventDefault(),t[t.length-1].focus()):e.keyCode===this.Keycodes_.DOWN_ARROW&&(e.preventDefault(),t[0].focus()))}},d.prototype.handleItemKeyboardEvent_=function(e){if(this.element_&&this.container_){var t=this.element_.querySelectorAll("."+this.CssClasses_.ITEM+":not([disabled])");if(t&&t.length>0&&this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)){var s=Array.prototype.slice.call(t).indexOf(e.target);if(e.keyCode===this.Keycodes_.UP_ARROW)e.preventDefault(),s>0?t[s-1].focus():t[t.length-1].focus();else if(e.keyCode===this.Keycodes_.DOWN_ARROW)e.preventDefault(),t.length>s+1?t[s+1].focus():t[0].focus();else if(e.keyCode===this.Keycodes_.SPACE||e.keyCode===this.Keycodes_.ENTER){e.preventDefault();var i=new MouseEvent("mousedown");e.target.dispatchEvent(i),i=new MouseEvent("mouseup"),e.target.dispatchEvent(i),e.target.click()}else e.keyCode===this.Keycodes_.ESCAPE&&(e.preventDefault(),this.hide())}}},d.prototype.handleItemClick_=function(e){e.target.hasAttribute("disabled")?e.stopPropagation():(this.closing_=!0,window.setTimeout(function(e){this.hide(),this.closing_=!1}.bind(this),this.Constant_.CLOSE_TIMEOUT))},d.prototype.applyClip_=function(e,t){this.element_.classList.contains(this.CssClasses_.UNALIGNED)?this.element_.style.clip="":this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)?this.element_.style.clip="rect(0 "+t+"px 0 "+t+"px)":this.element_.classList.contains(this.CssClasses_.TOP_LEFT)?this.element_.style.clip="rect("+e+"px 0 "+e+"px 0)":this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)?this.element_.style.clip="rect("+e+"px "+t+"px "+e+"px "+t+"px)":this.element_.style.clip=""},d.prototype.removeAnimationEndListener_=function(e){e.target.classList.remove(d.prototype.CssClasses_.IS_ANIMATING)},d.prototype.addAnimationEndListener_=function(){this.element_.addEventListener("transitionend",this.removeAnimationEndListener_),this.element_.addEventListener("webkitTransitionEnd",this.removeAnimationEndListener_)},d.prototype.show=function(e){if(this.element_&&this.container_&&this.outline_){var t=this.element_.getBoundingClientRect().height,s=this.element_.getBoundingClientRect().width;this.container_.style.width=s+"px",this.container_.style.height=t+"px",this.outline_.style.width=s+"px",this.outline_.style.height=t+"px";for(var i=this.Constant_.TRANSITION_DURATION_SECONDS*this.Constant_.TRANSITION_DURATION_FRACTION,n=this.element_.querySelectorAll("."+this.CssClasses_.ITEM),a=0;a<n.length;a++){var l=null;l=this.element_.classList.contains(this.CssClasses_.TOP_LEFT)||this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)?(t-n[a].offsetTop-n[a].offsetHeight)/t*i+"s":n[a].offsetTop/t*i+"s",n[a].style.transitionDelay=l}this.applyClip_(t,s),window.requestAnimationFrame(function(){this.element_.classList.add(this.CssClasses_.IS_ANIMATING),this.element_.style.clip="rect(0 "+s+"px "+t+"px 0)",this.container_.classList.add(this.CssClasses_.IS_VISIBLE)}.bind(this)),this.addAnimationEndListener_();var o=function(t){t===e||this.closing_||t.target.parentNode===this.element_||(document.removeEventListener("click",o),this.hide())}.bind(this);document.addEventListener("click",o)}},d.prototype.show=d.prototype.show,d.prototype.hide=function(){if(this.element_&&this.container_&&this.outline_){for(var e=this.element_.querySelectorAll("."+this.CssClasses_.ITEM),t=0;t<e.length;t++)e[t].style.removeProperty("transition-delay");var s=this.element_.getBoundingClientRect(),i=s.height,n=s.width;this.element_.classList.add(this.CssClasses_.IS_ANIMATING),this.applyClip_(i,n),this.container_.classList.remove(this.CssClasses_.IS_VISIBLE),this.addAnimationEndListener_()}},d.prototype.hide=d.prototype.hide,d.prototype.toggle=function(e){this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)?this.hide():this.show(e)},d.prototype.toggle=d.prototype.toggle,s.register({constructor:d,classAsString:"MaterialMenu",cssClass:"mdl-js-menu",widget:!0});var h=function(e){this.element_=e,this.init()};window.MaterialProgress=h,h.prototype.Constant_={},h.prototype.CssClasses_={INDETERMINATE_CLASS:"mdl-progress__indeterminate"},h.prototype.setProgress=function(e){this.element_.classList.contains(this.CssClasses_.INDETERMINATE_CLASS)||(this.progressbar_.style.width=e+"%")},h.prototype.setProgress=h.prototype.setProgress,h.prototype.setBuffer=function(e){this.bufferbar_.style.width=e+"%",this.auxbar_.style.width=100-e+"%"},h.prototype.setBuffer=h.prototype.setBuffer,h.prototype.init=function(){if(this.element_){var e=document.createElement("div");e.className="progressbar bar bar1",this.element_.appendChild(e),this.progressbar_=e,e=document.createElement("div"),e.className="bufferbar bar bar2",this.element_.appendChild(e),this.bufferbar_=e,e=document.createElement("div"),e.className="auxbar bar bar3",this.element_.appendChild(e),this.auxbar_=e,this.progressbar_.style.width="0%",this.bufferbar_.style.width="100%",this.auxbar_.style.width="0%",this.element_.classList.add("is-upgraded")}},s.register({constructor:h,classAsString:"MaterialProgress",cssClass:"mdl-js-progress",widget:!0});var c=function(e){this.element_=e,this.init()};window.MaterialRadio=c,c.prototype.Constant_={TINY_TIMEOUT:.001},c.prototype.CssClasses_={IS_FOCUSED:"is-focused",IS_DISABLED:"is-disabled",IS_CHECKED:"is-checked",IS_UPGRADED:"is-upgraded",JS_RADIO:"mdl-js-radio",RADIO_BTN:"mdl-radio__button",RADIO_OUTER_CIRCLE:"mdl-radio__outer-circle",RADIO_INNER_CIRCLE:"mdl-radio__inner-circle",RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",RIPPLE_CONTAINER:"mdl-radio__ripple-container",RIPPLE_CENTER:"mdl-ripple--center",RIPPLE:"mdl-ripple"},c.prototype.onChange_=function(e){for(var t=document.getElementsByClassName(this.CssClasses_.JS_RADIO),s=0;s<t.length;s++){var i=t[s].querySelector("."+this.CssClasses_.RADIO_BTN);i.getAttribute("name")===this.btnElement_.getAttribute("name")&&"undefined"!=typeof t[s].MaterialRadio&&t[s].MaterialRadio.updateClasses_()}},c.prototype.onFocus_=function(e){this.element_.classList.add(this.CssClasses_.IS_FOCUSED)},c.prototype.onBlur_=function(e){this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},c.prototype.onMouseup_=function(e){this.blur_()},c.prototype.updateClasses_=function(){this.checkDisabled(),this.checkToggleState()},c.prototype.blur_=function(){window.setTimeout(function(){this.btnElement_.blur()}.bind(this),this.Constant_.TINY_TIMEOUT)},c.prototype.checkDisabled=function(){this.btnElement_.disabled?this.element_.classList.add(this.CssClasses_.IS_DISABLED):this.element_.classList.remove(this.CssClasses_.IS_DISABLED)},c.prototype.checkDisabled=c.prototype.checkDisabled,c.prototype.checkToggleState=function(){this.btnElement_.checked?this.element_.classList.add(this.CssClasses_.IS_CHECKED):this.element_.classList.remove(this.CssClasses_.IS_CHECKED)},c.prototype.checkToggleState=c.prototype.checkToggleState,c.prototype.disable=function(){this.btnElement_.disabled=!0,this.updateClasses_()},c.prototype.disable=c.prototype.disable,c.prototype.enable=function(){this.btnElement_.disabled=!1,this.updateClasses_()},c.prototype.enable=c.prototype.enable,c.prototype.check=function(){this.btnElement_.checked=!0,this.onChange_(null)},c.prototype.check=c.prototype.check,c.prototype.uncheck=function(){this.btnElement_.checked=!1,this.onChange_(null)},c.prototype.uncheck=c.prototype.uncheck,c.prototype.init=function(){if(this.element_){this.btnElement_=this.element_.querySelector("."+this.CssClasses_.RADIO_BTN),this.boundChangeHandler_=this.onChange_.bind(this),this.boundFocusHandler_=this.onChange_.bind(this),this.boundBlurHandler_=this.onBlur_.bind(this),this.boundMouseUpHandler_=this.onMouseup_.bind(this);var e=document.createElement("span");e.classList.add(this.CssClasses_.RADIO_OUTER_CIRCLE);var t=document.createElement("span");t.classList.add(this.CssClasses_.RADIO_INNER_CIRCLE),this.element_.appendChild(e),this.element_.appendChild(t);var s;if(this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)){this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS),s=document.createElement("span"),s.classList.add(this.CssClasses_.RIPPLE_CONTAINER),s.classList.add(this.CssClasses_.RIPPLE_EFFECT),s.classList.add(this.CssClasses_.RIPPLE_CENTER),s.addEventListener("mouseup",this.boundMouseUpHandler_);var i=document.createElement("span");i.classList.add(this.CssClasses_.RIPPLE),s.appendChild(i),this.element_.appendChild(s)}this.btnElement_.addEventListener("change",this.boundChangeHandler_),this.btnElement_.addEventListener("focus",this.boundFocusHandler_),this.btnElement_.addEventListener("blur",this.boundBlurHandler_),this.element_.addEventListener("mouseup",this.boundMouseUpHandler_),this.updateClasses_(),this.element_.classList.add(this.CssClasses_.IS_UPGRADED)}},s.register({constructor:c,classAsString:"MaterialRadio",cssClass:"mdl-js-radio",widget:!0});var p=function(e){this.element_=e,this.isIE_=window.navigator.msPointerEnabled,this.init()};window.MaterialSlider=p,p.prototype.Constant_={},p.prototype.CssClasses_={IE_CONTAINER:"mdl-slider__ie-container",SLIDER_CONTAINER:"mdl-slider__container",BACKGROUND_FLEX:"mdl-slider__background-flex",BACKGROUND_LOWER:"mdl-slider__background-lower",BACKGROUND_UPPER:"mdl-slider__background-upper",IS_LOWEST_VALUE:"is-lowest-value",IS_UPGRADED:"is-upgraded"},p.prototype.onInput_=function(e){this.updateValueStyles_()},p.prototype.onChange_=function(e){this.updateValueStyles_()},p.prototype.onMouseUp_=function(e){e.target.blur()},p.prototype.onContainerMouseDown_=function(e){if(e.target===this.element_.parentElement){e.preventDefault();var t=new MouseEvent("mousedown",{target:e.target,buttons:e.buttons,clientX:e.clientX,clientY:this.element_.getBoundingClientRect().y});this.element_.dispatchEvent(t)}},p.prototype.updateValueStyles_=function(){var e=(this.element_.value-this.element_.min)/(this.element_.max-this.element_.min);0===e?this.element_.classList.add(this.CssClasses_.IS_LOWEST_VALUE):this.element_.classList.remove(this.CssClasses_.IS_LOWEST_VALUE),this.isIE_||(this.backgroundLower_.style.flex=e,this.backgroundLower_.style.webkitFlex=e,this.backgroundUpper_.style.flex=1-e,this.backgroundUpper_.style.webkitFlex=1-e)},p.prototype.disable=function(){this.element_.disabled=!0},p.prototype.disable=p.prototype.disable,p.prototype.enable=function(){this.element_.disabled=!1},p.prototype.enable=p.prototype.enable,p.prototype.change=function(e){"undefined"!=typeof e&&(this.element_.value=e),this.updateValueStyles_()},p.prototype.change=p.prototype.change,p.prototype.init=function(){if(this.element_){if(this.isIE_){var e=document.createElement("div");e.classList.add(this.CssClasses_.IE_CONTAINER),this.element_.parentElement.insertBefore(e,this.element_),this.element_.parentElement.removeChild(this.element_),e.appendChild(this.element_)}else{var t=document.createElement("div");t.classList.add(this.CssClasses_.SLIDER_CONTAINER),this.element_.parentElement.insertBefore(t,this.element_),this.element_.parentElement.removeChild(this.element_),t.appendChild(this.element_);var s=document.createElement("div");s.classList.add(this.CssClasses_.BACKGROUND_FLEX),t.appendChild(s),this.backgroundLower_=document.createElement("div"),this.backgroundLower_.classList.add(this.CssClasses_.BACKGROUND_LOWER),s.appendChild(this.backgroundLower_),this.backgroundUpper_=document.createElement("div"),this.backgroundUpper_.classList.add(this.CssClasses_.BACKGROUND_UPPER),s.appendChild(this.backgroundUpper_)}this.boundInputHandler=this.onInput_.bind(this),this.boundChangeHandler=this.onChange_.bind(this),this.boundMouseUpHandler=this.onMouseUp_.bind(this),this.boundContainerMouseDownHandler=this.onContainerMouseDown_.bind(this),this.element_.addEventListener("input",this.boundInputHandler),this.element_.addEventListener("change",this.boundChangeHandler),this.element_.addEventListener("mouseup",this.boundMouseUpHandler),this.element_.parentElement.addEventListener("mousedown",this.boundContainerMouseDownHandler),this.updateValueStyles_(),this.element_.classList.add(this.CssClasses_.IS_UPGRADED)}},s.register({constructor:p,classAsString:"MaterialSlider",cssClass:"mdl-js-slider",widget:!0});var C=function(e){if(this.element_=e,this.textElement_=this.element_.querySelector("."+this.cssClasses_.MESSAGE),this.actionElement_=this.element_.querySelector("."+this.cssClasses_.ACTION),!this.textElement_)throw new Error("There must be a message element for a snackbar.");if(!this.actionElement_)throw new Error("There must be an action element for a snackbar.");this.active=!1,this.actionHandler_=void 0,this.message_=void 0,this.actionText_=void 0,this.queuedNotifications_=[],this.setActionHidden_(!0)};window.MaterialSnackbar=C,C.prototype.Constant_={ANIMATION_LENGTH:250},C.prototype.cssClasses_={SNACKBAR:"mdl-snackbar",MESSAGE:"mdl-snackbar__text",ACTION:"mdl-snackbar__action",ACTIVE:"mdl-snackbar--active"},C.prototype.displaySnackbar_=function(){this.element_.setAttribute("aria-hidden","true"),
9   -this.actionHandler_&&(this.actionElement_.textContent=this.actionText_,this.actionElement_.addEventListener("click",this.actionHandler_),this.setActionHidden_(!1)),this.textElement_.textContent=this.message_,this.element_.classList.add(this.cssClasses_.ACTIVE),this.element_.setAttribute("aria-hidden","false"),setTimeout(this.cleanup_.bind(this),this.timeout_)},C.prototype.showSnackbar=function(e){if(void 0===e)throw new Error("Please provide a data object with at least a message to display.");if(void 0===e.message)throw new Error("Please provide a message to be displayed.");if(e.actionHandler&&!e.actionText)throw new Error("Please provide action text with the handler.");this.active?this.queuedNotifications_.push(e):(this.active=!0,this.message_=e.message,e.timeout?this.timeout_=e.timeout:this.timeout_=2750,e.actionHandler&&(this.actionHandler_=e.actionHandler),e.actionText&&(this.actionText_=e.actionText),this.displaySnackbar_())},C.prototype.showSnackbar=C.prototype.showSnackbar,C.prototype.checkQueue_=function(){this.queuedNotifications_.length>0&&this.showSnackbar(this.queuedNotifications_.shift())},C.prototype.cleanup_=function(){this.element_.classList.remove(this.cssClasses_.ACTIVE),setTimeout(function(){this.element_.setAttribute("aria-hidden","true"),this.textElement_.textContent="",Boolean(this.actionElement_.getAttribute("aria-hidden"))||(this.setActionHidden_(!0),this.actionElement_.textContent="",this.actionElement_.removeEventListener("click",this.actionHandler_)),this.actionHandler_=void 0,this.message_=void 0,this.actionText_=void 0,this.active=!1,this.checkQueue_()}.bind(this),this.Constant_.ANIMATION_LENGTH)},C.prototype.setActionHidden_=function(e){e?this.actionElement_.setAttribute("aria-hidden","true"):this.actionElement_.removeAttribute("aria-hidden")},s.register({constructor:C,classAsString:"MaterialSnackbar",cssClass:"mdl-js-snackbar",widget:!0});var u=function(e){this.element_=e,this.init()};window.MaterialSpinner=u,u.prototype.Constant_={MDL_SPINNER_LAYER_COUNT:4},u.prototype.CssClasses_={MDL_SPINNER_LAYER:"mdl-spinner__layer",MDL_SPINNER_CIRCLE_CLIPPER:"mdl-spinner__circle-clipper",MDL_SPINNER_CIRCLE:"mdl-spinner__circle",MDL_SPINNER_GAP_PATCH:"mdl-spinner__gap-patch",MDL_SPINNER_LEFT:"mdl-spinner__left",MDL_SPINNER_RIGHT:"mdl-spinner__right"},u.prototype.createLayer=function(e){var t=document.createElement("div");t.classList.add(this.CssClasses_.MDL_SPINNER_LAYER),t.classList.add(this.CssClasses_.MDL_SPINNER_LAYER+"-"+e);var s=document.createElement("div");s.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER),s.classList.add(this.CssClasses_.MDL_SPINNER_LEFT);var i=document.createElement("div");i.classList.add(this.CssClasses_.MDL_SPINNER_GAP_PATCH);var n=document.createElement("div");n.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER),n.classList.add(this.CssClasses_.MDL_SPINNER_RIGHT);for(var a=[s,i,n],l=0;l<a.length;l++){var o=document.createElement("div");o.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE),a[l].appendChild(o)}t.appendChild(s),t.appendChild(i),t.appendChild(n),this.element_.appendChild(t)},u.prototype.createLayer=u.prototype.createLayer,u.prototype.stop=function(){this.element_.classList.remove("is-active")},u.prototype.stop=u.prototype.stop,u.prototype.start=function(){this.element_.classList.add("is-active")},u.prototype.start=u.prototype.start,u.prototype.init=function(){if(this.element_){for(var e=1;e<=this.Constant_.MDL_SPINNER_LAYER_COUNT;e++)this.createLayer(e);this.element_.classList.add("is-upgraded")}},s.register({constructor:u,classAsString:"MaterialSpinner",cssClass:"mdl-js-spinner",widget:!0});var E=function(e){this.element_=e,this.init()};window.MaterialSwitch=E,E.prototype.Constant_={TINY_TIMEOUT:.001},E.prototype.CssClasses_={INPUT:"mdl-switch__input",TRACK:"mdl-switch__track",THUMB:"mdl-switch__thumb",FOCUS_HELPER:"mdl-switch__focus-helper",RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",RIPPLE_CONTAINER:"mdl-switch__ripple-container",RIPPLE_CENTER:"mdl-ripple--center",RIPPLE:"mdl-ripple",IS_FOCUSED:"is-focused",IS_DISABLED:"is-disabled",IS_CHECKED:"is-checked"},E.prototype.onChange_=function(e){this.updateClasses_()},E.prototype.onFocus_=function(e){this.element_.classList.add(this.CssClasses_.IS_FOCUSED)},E.prototype.onBlur_=function(e){this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},E.prototype.onMouseUp_=function(e){this.blur_()},E.prototype.updateClasses_=function(){this.checkDisabled(),this.checkToggleState()},E.prototype.blur_=function(){window.setTimeout(function(){this.inputElement_.blur()}.bind(this),this.Constant_.TINY_TIMEOUT)},E.prototype.checkDisabled=function(){this.inputElement_.disabled?this.element_.classList.add(this.CssClasses_.IS_DISABLED):this.element_.classList.remove(this.CssClasses_.IS_DISABLED)},E.prototype.checkDisabled=E.prototype.checkDisabled,E.prototype.checkToggleState=function(){this.inputElement_.checked?this.element_.classList.add(this.CssClasses_.IS_CHECKED):this.element_.classList.remove(this.CssClasses_.IS_CHECKED)},E.prototype.checkToggleState=E.prototype.checkToggleState,E.prototype.disable=function(){this.inputElement_.disabled=!0,this.updateClasses_()},E.prototype.disable=E.prototype.disable,E.prototype.enable=function(){this.inputElement_.disabled=!1,this.updateClasses_()},E.prototype.enable=E.prototype.enable,E.prototype.on=function(){this.inputElement_.checked=!0,this.updateClasses_()},E.prototype.on=E.prototype.on,E.prototype.off=function(){this.inputElement_.checked=!1,this.updateClasses_()},E.prototype.off=E.prototype.off,E.prototype.init=function(){if(this.element_){this.inputElement_=this.element_.querySelector("."+this.CssClasses_.INPUT);var e=document.createElement("div");e.classList.add(this.CssClasses_.TRACK);var t=document.createElement("div");t.classList.add(this.CssClasses_.THUMB);var s=document.createElement("span");if(s.classList.add(this.CssClasses_.FOCUS_HELPER),t.appendChild(s),this.element_.appendChild(e),this.element_.appendChild(t),this.boundMouseUpHandler=this.onMouseUp_.bind(this),this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)){this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS),this.rippleContainerElement_=document.createElement("span"),this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER),this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT),this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER),this.rippleContainerElement_.addEventListener("mouseup",this.boundMouseUpHandler);var i=document.createElement("span");i.classList.add(this.CssClasses_.RIPPLE),this.rippleContainerElement_.appendChild(i),this.element_.appendChild(this.rippleContainerElement_)}this.boundChangeHandler=this.onChange_.bind(this),this.boundFocusHandler=this.onFocus_.bind(this),this.boundBlurHandler=this.onBlur_.bind(this),this.inputElement_.addEventListener("change",this.boundChangeHandler),this.inputElement_.addEventListener("focus",this.boundFocusHandler),this.inputElement_.addEventListener("blur",this.boundBlurHandler),this.element_.addEventListener("mouseup",this.boundMouseUpHandler),this.updateClasses_(),this.element_.classList.add("is-upgraded")}},s.register({constructor:E,classAsString:"MaterialSwitch",cssClass:"mdl-js-switch",widget:!0});var m=function(e){this.element_=e,this.init()};window.MaterialTabs=m,m.prototype.Constant_={},m.prototype.CssClasses_={TAB_CLASS:"mdl-tabs__tab",PANEL_CLASS:"mdl-tabs__panel",ACTIVE_CLASS:"is-active",UPGRADED_CLASS:"is-upgraded",MDL_JS_RIPPLE_EFFECT:"mdl-js-ripple-effect",MDL_RIPPLE_CONTAINER:"mdl-tabs__ripple-container",MDL_RIPPLE:"mdl-ripple",MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events"},m.prototype.initTabs_=function(){this.element_.classList.contains(this.CssClasses_.MDL_JS_RIPPLE_EFFECT)&&this.element_.classList.add(this.CssClasses_.MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS),this.tabs_=this.element_.querySelectorAll("."+this.CssClasses_.TAB_CLASS),this.panels_=this.element_.querySelectorAll("."+this.CssClasses_.PANEL_CLASS);for(var t=0;t<this.tabs_.length;t++)new e(this.tabs_[t],this);this.element_.classList.add(this.CssClasses_.UPGRADED_CLASS)},m.prototype.resetTabState_=function(){for(var e=0;e<this.tabs_.length;e++)this.tabs_[e].classList.remove(this.CssClasses_.ACTIVE_CLASS)},m.prototype.resetPanelState_=function(){for(var e=0;e<this.panels_.length;e++)this.panels_[e].classList.remove(this.CssClasses_.ACTIVE_CLASS)},m.prototype.init=function(){this.element_&&this.initTabs_()},s.register({constructor:m,classAsString:"MaterialTabs",cssClass:"mdl-js-tabs"});var L=function(e){this.element_=e,this.maxRows=this.Constant_.NO_MAX_ROWS,this.init()};window.MaterialTextfield=L,L.prototype.Constant_={NO_MAX_ROWS:-1,MAX_ROWS_ATTRIBUTE:"maxrows"},L.prototype.CssClasses_={LABEL:"mdl-textfield__label",INPUT:"mdl-textfield__input",IS_DIRTY:"is-dirty",IS_FOCUSED:"is-focused",IS_DISABLED:"is-disabled",IS_INVALID:"is-invalid",IS_UPGRADED:"is-upgraded",HAS_PLACEHOLDER:"has-placeholder"},L.prototype.onKeyDown_=function(e){var t=e.target.value.split("\n").length;13===e.keyCode&&t>=this.maxRows&&e.preventDefault()},L.prototype.onFocus_=function(e){this.element_.classList.add(this.CssClasses_.IS_FOCUSED)},L.prototype.onBlur_=function(e){this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},L.prototype.onReset_=function(e){this.updateClasses_()},L.prototype.updateClasses_=function(){this.checkDisabled(),this.checkValidity(),this.checkDirty(),this.checkFocus()},L.prototype.checkDisabled=function(){this.input_.disabled?this.element_.classList.add(this.CssClasses_.IS_DISABLED):this.element_.classList.remove(this.CssClasses_.IS_DISABLED)},L.prototype.checkDisabled=L.prototype.checkDisabled,L.prototype.checkFocus=function(){Boolean(this.element_.querySelector(":focus"))?this.element_.classList.add(this.CssClasses_.IS_FOCUSED):this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},L.prototype.checkFocus=L.prototype.checkFocus,L.prototype.checkValidity=function(){this.input_.validity&&(this.input_.validity.valid?this.element_.classList.remove(this.CssClasses_.IS_INVALID):this.element_.classList.add(this.CssClasses_.IS_INVALID))},L.prototype.checkValidity=L.prototype.checkValidity,L.prototype.checkDirty=function(){this.input_.value&&this.input_.value.length>0?this.element_.classList.add(this.CssClasses_.IS_DIRTY):this.element_.classList.remove(this.CssClasses_.IS_DIRTY)},L.prototype.checkDirty=L.prototype.checkDirty,L.prototype.disable=function(){this.input_.disabled=!0,this.updateClasses_()},L.prototype.disable=L.prototype.disable,L.prototype.enable=function(){this.input_.disabled=!1,this.updateClasses_()},L.prototype.enable=L.prototype.enable,L.prototype.change=function(e){this.input_.value=e||"",this.updateClasses_()},L.prototype.change=L.prototype.change,L.prototype.init=function(){if(this.element_&&(this.label_=this.element_.querySelector("."+this.CssClasses_.LABEL),this.input_=this.element_.querySelector("."+this.CssClasses_.INPUT),this.input_)){this.input_.hasAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE)&&(this.maxRows=parseInt(this.input_.getAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE),10),isNaN(this.maxRows)&&(this.maxRows=this.Constant_.NO_MAX_ROWS)),this.input_.hasAttribute("placeholder")&&this.element_.classList.add(this.CssClasses_.HAS_PLACEHOLDER),this.boundUpdateClassesHandler=this.updateClasses_.bind(this),this.boundFocusHandler=this.onFocus_.bind(this),this.boundBlurHandler=this.onBlur_.bind(this),this.boundResetHandler=this.onReset_.bind(this),this.input_.addEventListener("input",this.boundUpdateClassesHandler),this.input_.addEventListener("focus",this.boundFocusHandler),this.input_.addEventListener("blur",this.boundBlurHandler),this.input_.addEventListener("reset",this.boundResetHandler),this.maxRows!==this.Constant_.NO_MAX_ROWS&&(this.boundKeyDownHandler=this.onKeyDown_.bind(this),this.input_.addEventListener("keydown",this.boundKeyDownHandler));var e=this.element_.classList.contains(this.CssClasses_.IS_INVALID);this.updateClasses_(),this.element_.classList.add(this.CssClasses_.IS_UPGRADED),e&&this.element_.classList.add(this.CssClasses_.IS_INVALID),this.input_.hasAttribute("autofocus")&&(this.element_.focus(),this.checkFocus())}},s.register({constructor:L,classAsString:"MaterialTextfield",cssClass:"mdl-js-textfield",widget:!0});var I=function(e){this.element_=e,this.init()};window.MaterialTooltip=I,I.prototype.Constant_={},I.prototype.CssClasses_={IS_ACTIVE:"is-active",BOTTOM:"mdl-tooltip--bottom",LEFT:"mdl-tooltip--left",RIGHT:"mdl-tooltip--right",TOP:"mdl-tooltip--top"},I.prototype.handleMouseEnter_=function(e){var t=e.target.getBoundingClientRect(),s=t.left+t.width/2,i=t.top+t.height/2,n=-1*(this.element_.offsetWidth/2),a=-1*(this.element_.offsetHeight/2);this.element_.classList.contains(this.CssClasses_.LEFT)||this.element_.classList.contains(this.CssClasses_.RIGHT)?(s=t.width/2,i+a<0?(this.element_.style.top="0",this.element_.style.marginTop="0"):(this.element_.style.top=i+"px",this.element_.style.marginTop=a+"px")):s+n<0?(this.element_.style.left="0",this.element_.style.marginLeft="0"):(this.element_.style.left=s+"px",this.element_.style.marginLeft=n+"px"),this.element_.classList.contains(this.CssClasses_.TOP)?this.element_.style.top=t.top-this.element_.offsetHeight-10+"px":this.element_.classList.contains(this.CssClasses_.RIGHT)?this.element_.style.left=t.left+t.width+10+"px":this.element_.classList.contains(this.CssClasses_.LEFT)?this.element_.style.left=t.left-this.element_.offsetWidth-10+"px":this.element_.style.top=t.top+t.height+10+"px",this.element_.classList.add(this.CssClasses_.IS_ACTIVE)},I.prototype.hideTooltip_=function(){this.element_.classList.remove(this.CssClasses_.IS_ACTIVE)},I.prototype.init=function(){if(this.element_){var e=this.element_.getAttribute("for")||this.element_.getAttribute("data-mdl-for");e&&(this.forElement_=document.getElementById(e)),this.forElement_&&(this.forElement_.hasAttribute("tabindex")||this.forElement_.setAttribute("tabindex","0"),this.boundMouseEnterHandler=this.handleMouseEnter_.bind(this),this.boundMouseLeaveAndScrollHandler=this.hideTooltip_.bind(this),this.forElement_.addEventListener("mouseenter",this.boundMouseEnterHandler,!1),this.forElement_.addEventListener("touchend",this.boundMouseEnterHandler,!1),this.forElement_.addEventListener("mouseleave",this.boundMouseLeaveAndScrollHandler,!1),window.addEventListener("scroll",this.boundMouseLeaveAndScrollHandler,!0),window.addEventListener("touchstart",this.boundMouseLeaveAndScrollHandler))}},s.register({constructor:I,classAsString:"MaterialTooltip",cssClass:"mdl-tooltip"});var f=function(e){this.element_=e,this.init()};window.MaterialLayout=f,f.prototype.Constant_={MAX_WIDTH:"(max-width: 1024px)",TAB_SCROLL_PIXELS:100,RESIZE_TIMEOUT:100,MENU_ICON:"&#xE5D2;",CHEVRON_LEFT:"chevron_left",CHEVRON_RIGHT:"chevron_right"},f.prototype.Keycodes_={ENTER:13,ESCAPE:27,SPACE:32},f.prototype.Mode_={STANDARD:0,SEAMED:1,WATERFALL:2,SCROLL:3},f.prototype.CssClasses_={CONTAINER:"mdl-layout__container",HEADER:"mdl-layout__header",DRAWER:"mdl-layout__drawer",CONTENT:"mdl-layout__content",DRAWER_BTN:"mdl-layout__drawer-button",ICON:"material-icons",JS_RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_CONTAINER:"mdl-layout__tab-ripple-container",RIPPLE:"mdl-ripple",RIPPLE_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",HEADER_SEAMED:"mdl-layout__header--seamed",HEADER_WATERFALL:"mdl-layout__header--waterfall",HEADER_SCROLL:"mdl-layout__header--scroll",FIXED_HEADER:"mdl-layout--fixed-header",OBFUSCATOR:"mdl-layout__obfuscator",TAB_BAR:"mdl-layout__tab-bar",TAB_CONTAINER:"mdl-layout__tab-bar-container",TAB:"mdl-layout__tab",TAB_BAR_BUTTON:"mdl-layout__tab-bar-button",TAB_BAR_LEFT_BUTTON:"mdl-layout__tab-bar-left-button",TAB_BAR_RIGHT_BUTTON:"mdl-layout__tab-bar-right-button",TAB_MANUAL_SWITCH:"mdl-layout__tab-manual-switch",PANEL:"mdl-layout__tab-panel",HAS_DRAWER:"has-drawer",HAS_TABS:"has-tabs",HAS_SCROLLING_HEADER:"has-scrolling-header",CASTING_SHADOW:"is-casting-shadow",IS_COMPACT:"is-compact",IS_SMALL_SCREEN:"is-small-screen",IS_DRAWER_OPEN:"is-visible",IS_ACTIVE:"is-active",IS_UPGRADED:"is-upgraded",IS_ANIMATING:"is-animating",ON_LARGE_SCREEN:"mdl-layout--large-screen-only",ON_SMALL_SCREEN:"mdl-layout--small-screen-only"},f.prototype.contentScrollHandler_=function(){if(!this.header_.classList.contains(this.CssClasses_.IS_ANIMATING)){var e=!this.element_.classList.contains(this.CssClasses_.IS_SMALL_SCREEN)||this.element_.classList.contains(this.CssClasses_.FIXED_HEADER);this.content_.scrollTop>0&&!this.header_.classList.contains(this.CssClasses_.IS_COMPACT)?(this.header_.classList.add(this.CssClasses_.CASTING_SHADOW),this.header_.classList.add(this.CssClasses_.IS_COMPACT),e&&this.header_.classList.add(this.CssClasses_.IS_ANIMATING)):this.content_.scrollTop<=0&&this.header_.classList.contains(this.CssClasses_.IS_COMPACT)&&(this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW),this.header_.classList.remove(this.CssClasses_.IS_COMPACT),e&&this.header_.classList.add(this.CssClasses_.IS_ANIMATING))}},f.prototype.keyboardEventHandler_=function(e){e.keyCode===this.Keycodes_.ESCAPE&&this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)&&this.toggleDrawer()},f.prototype.screenSizeHandler_=function(){this.screenSizeMediaQuery_.matches?this.element_.classList.add(this.CssClasses_.IS_SMALL_SCREEN):(this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN),this.drawer_&&(this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN),this.obfuscator_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN)))},f.prototype.drawerToggleHandler_=function(e){if(e&&"keydown"===e.type){if(e.keyCode!==this.Keycodes_.SPACE&&e.keyCode!==this.Keycodes_.ENTER)return;e.preventDefault()}this.toggleDrawer()},f.prototype.headerTransitionEndHandler_=function(){this.header_.classList.remove(this.CssClasses_.IS_ANIMATING)},f.prototype.headerClickHandler_=function(){this.header_.classList.contains(this.CssClasses_.IS_COMPACT)&&(this.header_.classList.remove(this.CssClasses_.IS_COMPACT),this.header_.classList.add(this.CssClasses_.IS_ANIMATING))},f.prototype.resetTabState_=function(e){for(var t=0;t<e.length;t++)e[t].classList.remove(this.CssClasses_.IS_ACTIVE)},f.prototype.resetPanelState_=function(e){for(var t=0;t<e.length;t++)e[t].classList.remove(this.CssClasses_.IS_ACTIVE)},f.prototype.toggleDrawer=function(){var e=this.element_.querySelector("."+this.CssClasses_.DRAWER_BTN);this.drawer_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN),this.obfuscator_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN),this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)?(this.drawer_.setAttribute("aria-hidden","false"),e.setAttribute("aria-expanded","true")):(this.drawer_.setAttribute("aria-hidden","true"),e.setAttribute("aria-expanded","false"))},f.prototype.toggleDrawer=f.prototype.toggleDrawer,f.prototype.init=function(){if(this.element_){var e=document.createElement("div");e.classList.add(this.CssClasses_.CONTAINER);var s=this.element_.querySelector(":focus");this.element_.parentElement.insertBefore(e,this.element_),this.element_.parentElement.removeChild(this.element_),e.appendChild(this.element_),s&&s.focus();for(var i=this.element_.childNodes,n=i.length,a=0;a<n;a++){var l=i[a];l.classList&&l.classList.contains(this.CssClasses_.HEADER)&&(this.header_=l),l.classList&&l.classList.contains(this.CssClasses_.DRAWER)&&(this.drawer_=l),l.classList&&l.classList.contains(this.CssClasses_.CONTENT)&&(this.content_=l)}window.addEventListener("pageshow",function(e){e.persisted&&(this.element_.style.overflowY="hidden",requestAnimationFrame(function(){this.element_.style.overflowY=""}.bind(this)))}.bind(this),!1),this.header_&&(this.tabBar_=this.header_.querySelector("."+this.CssClasses_.TAB_BAR));var o=this.Mode_.STANDARD;if(this.header_&&(this.header_.classList.contains(this.CssClasses_.HEADER_SEAMED)?o=this.Mode_.SEAMED:this.header_.classList.contains(this.CssClasses_.HEADER_WATERFALL)?(o=this.Mode_.WATERFALL,this.header_.addEventListener("transitionend",this.headerTransitionEndHandler_.bind(this)),this.header_.addEventListener("click",this.headerClickHandler_.bind(this))):this.header_.classList.contains(this.CssClasses_.HEADER_SCROLL)&&(o=this.Mode_.SCROLL,e.classList.add(this.CssClasses_.HAS_SCROLLING_HEADER)),o===this.Mode_.STANDARD?(this.header_.classList.add(this.CssClasses_.CASTING_SHADOW),this.tabBar_&&this.tabBar_.classList.add(this.CssClasses_.CASTING_SHADOW)):o===this.Mode_.SEAMED||o===this.Mode_.SCROLL?(this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW),this.tabBar_&&this.tabBar_.classList.remove(this.CssClasses_.CASTING_SHADOW)):o===this.Mode_.WATERFALL&&(this.content_.addEventListener("scroll",this.contentScrollHandler_.bind(this)),this.contentScrollHandler_())),this.drawer_){var r=this.element_.querySelector("."+this.CssClasses_.DRAWER_BTN);if(!r){r=document.createElement("div"),r.setAttribute("aria-expanded","false"),r.setAttribute("role","button"),r.setAttribute("tabindex","0"),r.classList.add(this.CssClasses_.DRAWER_BTN);var _=document.createElement("i");_.classList.add(this.CssClasses_.ICON),_.innerHTML=this.Constant_.MENU_ICON,r.appendChild(_)}this.drawer_.classList.contains(this.CssClasses_.ON_LARGE_SCREEN)?r.classList.add(this.CssClasses_.ON_LARGE_SCREEN):this.drawer_.classList.contains(this.CssClasses_.ON_SMALL_SCREEN)&&r.classList.add(this.CssClasses_.ON_SMALL_SCREEN),r.addEventListener("click",this.drawerToggleHandler_.bind(this)),r.addEventListener("keydown",this.drawerToggleHandler_.bind(this)),this.element_.classList.add(this.CssClasses_.HAS_DRAWER),this.element_.classList.contains(this.CssClasses_.FIXED_HEADER)?this.header_.insertBefore(r,this.header_.firstChild):this.element_.insertBefore(r,this.content_);var d=document.createElement("div");d.classList.add(this.CssClasses_.OBFUSCATOR),this.element_.appendChild(d),d.addEventListener("click",this.drawerToggleHandler_.bind(this)),this.obfuscator_=d,this.drawer_.addEventListener("keydown",this.keyboardEventHandler_.bind(this)),this.drawer_.setAttribute("aria-hidden","true")}if(this.screenSizeMediaQuery_=window.matchMedia(this.Constant_.MAX_WIDTH),this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this)),this.screenSizeHandler_(),this.header_&&this.tabBar_){this.element_.classList.add(this.CssClasses_.HAS_TABS);var h=document.createElement("div");h.classList.add(this.CssClasses_.TAB_CONTAINER),this.header_.insertBefore(h,this.tabBar_),this.header_.removeChild(this.tabBar_);var c=document.createElement("div");c.classList.add(this.CssClasses_.TAB_BAR_BUTTON),c.classList.add(this.CssClasses_.TAB_BAR_LEFT_BUTTON);var p=document.createElement("i");p.classList.add(this.CssClasses_.ICON),p.textContent=this.Constant_.CHEVRON_LEFT,c.appendChild(p),c.addEventListener("click",function(){this.tabBar_.scrollLeft-=this.Constant_.TAB_SCROLL_PIXELS}.bind(this));var C=document.createElement("div");C.classList.add(this.CssClasses_.TAB_BAR_BUTTON),C.classList.add(this.CssClasses_.TAB_BAR_RIGHT_BUTTON);var u=document.createElement("i");u.classList.add(this.CssClasses_.ICON),u.textContent=this.Constant_.CHEVRON_RIGHT,C.appendChild(u),C.addEventListener("click",function(){this.tabBar_.scrollLeft+=this.Constant_.TAB_SCROLL_PIXELS}.bind(this)),h.appendChild(c),h.appendChild(this.tabBar_),h.appendChild(C);var E=function(){this.tabBar_.scrollLeft>0?c.classList.add(this.CssClasses_.IS_ACTIVE):c.classList.remove(this.CssClasses_.IS_ACTIVE),this.tabBar_.scrollLeft<this.tabBar_.scrollWidth-this.tabBar_.offsetWidth?C.classList.add(this.CssClasses_.IS_ACTIVE):C.classList.remove(this.CssClasses_.IS_ACTIVE)}.bind(this);this.tabBar_.addEventListener("scroll",E),E();var m=function(){this.resizeTimeoutId_&&clearTimeout(this.resizeTimeoutId_),this.resizeTimeoutId_=setTimeout(function(){E(),this.resizeTimeoutId_=null}.bind(this),this.Constant_.RESIZE_TIMEOUT)}.bind(this);window.addEventListener("resize",m),this.tabBar_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)&&this.tabBar_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);for(var L=this.tabBar_.querySelectorAll("."+this.CssClasses_.TAB),I=this.content_.querySelectorAll("."+this.CssClasses_.PANEL),f=0;f<L.length;f++)new t(L[f],L,I,this)}this.element_.classList.add(this.CssClasses_.IS_UPGRADED)}},window.MaterialLayoutTab=t,s.register({constructor:f,classAsString:"MaterialLayout",cssClass:"mdl-js-layout"});var b=function(e){this.element_=e,this.init()};window.MaterialDataTable=b,b.prototype.Constant_={},b.prototype.CssClasses_={DATA_TABLE:"mdl-data-table",SELECTABLE:"mdl-data-table--selectable",SELECT_ELEMENT:"mdl-data-table__select",IS_SELECTED:"is-selected",IS_UPGRADED:"is-upgraded"},b.prototype.selectRow_=function(e,t,s){return t?function(){e.checked?t.classList.add(this.CssClasses_.IS_SELECTED):t.classList.remove(this.CssClasses_.IS_SELECTED)}.bind(this):s?function(){var t,i;if(e.checked)for(t=0;t<s.length;t++)i=s[t].querySelector("td").querySelector(".mdl-checkbox"),i.MaterialCheckbox.check(),s[t].classList.add(this.CssClasses_.IS_SELECTED);else for(t=0;t<s.length;t++)i=s[t].querySelector("td").querySelector(".mdl-checkbox"),i.MaterialCheckbox.uncheck(),s[t].classList.remove(this.CssClasses_.IS_SELECTED)}.bind(this):void 0},b.prototype.createCheckbox_=function(e,t){var i=document.createElement("label"),n=["mdl-checkbox","mdl-js-checkbox","mdl-js-ripple-effect",this.CssClasses_.SELECT_ELEMENT];i.className=n.join(" ");var a=document.createElement("input");return a.type="checkbox",a.classList.add("mdl-checkbox__input"),e?(a.checked=e.classList.contains(this.CssClasses_.IS_SELECTED),a.addEventListener("change",this.selectRow_(a,e))):t&&a.addEventListener("change",this.selectRow_(a,null,t)),i.appendChild(a),s.upgradeElement(i,"MaterialCheckbox"),i},b.prototype.init=function(){if(this.element_){var e=this.element_.querySelector("th"),t=Array.prototype.slice.call(this.element_.querySelectorAll("tbody tr")),s=Array.prototype.slice.call(this.element_.querySelectorAll("tfoot tr")),i=t.concat(s);if(this.element_.classList.contains(this.CssClasses_.SELECTABLE)){var n=document.createElement("th"),a=this.createCheckbox_(null,i);n.appendChild(a),e.parentElement.insertBefore(n,e);for(var l=0;l<i.length;l++){var o=i[l].querySelector("td");if(o){var r=document.createElement("td");if("TBODY"===i[l].parentNode.nodeName.toUpperCase()){var _=this.createCheckbox_(i[l]);r.appendChild(_)}i[l].insertBefore(r,o)}}this.element_.classList.add(this.CssClasses_.IS_UPGRADED)}}},s.register({constructor:b,classAsString:"MaterialDataTable",cssClass:"mdl-js-data-table"});var S=function(e){this.element_=e,this.init()};window.MaterialRipple=S,S.prototype.Constant_={INITIAL_SCALE:"scale(0.0001, 0.0001)",INITIAL_SIZE:"1px",INITIAL_OPACITY:"0.4",FINAL_OPACITY:"0",FINAL_SCALE:""},S.prototype.CssClasses_={RIPPLE_CENTER:"mdl-ripple--center",RIPPLE_EFFECT_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",RIPPLE:"mdl-ripple",IS_ANIMATING:"is-animating",IS_VISIBLE:"is-visible"},S.prototype.downHandler_=function(e){if(!this.rippleElement_.style.width&&!this.rippleElement_.style.height){var t=this.element_.getBoundingClientRect();this.boundHeight=t.height,this.boundWidth=t.width,this.rippleSize_=2*Math.sqrt(t.width*t.width+t.height*t.height)+2,this.rippleElement_.style.width=this.rippleSize_+"px",this.rippleElement_.style.height=this.rippleSize_+"px"}if(this.rippleElement_.classList.add(this.CssClasses_.IS_VISIBLE),"mousedown"===e.type&&this.ignoringMouseDown_)this.ignoringMouseDown_=!1;else{"touchstart"===e.type&&(this.ignoringMouseDown_=!0);var s=this.getFrameCount();if(s>0)return;this.setFrameCount(1);var i,n,a=e.currentTarget.getBoundingClientRect();if(0===e.clientX&&0===e.clientY)i=Math.round(a.width/2),n=Math.round(a.height/2);else{var l=void 0!==e.clientX?e.clientX:e.touches[0].clientX,o=void 0!==e.clientY?e.clientY:e.touches[0].clientY;i=Math.round(l-a.left),n=Math.round(o-a.top)}this.setRippleXY(i,n),this.setRippleStyles(!0),window.requestAnimationFrame(this.animFrameHandler.bind(this))}},S.prototype.upHandler_=function(e){e&&2!==e.detail&&window.setTimeout(function(){this.rippleElement_.classList.remove(this.CssClasses_.IS_VISIBLE)}.bind(this),0)},S.prototype.init=function(){if(this.element_){var e=this.element_.classList.contains(this.CssClasses_.RIPPLE_CENTER);this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT_IGNORE_EVENTS)||(this.rippleElement_=this.element_.querySelector("."+this.CssClasses_.RIPPLE),this.frameCount_=0,this.rippleSize_=0,this.x_=0,this.y_=0,this.ignoringMouseDown_=!1,this.boundDownHandler=this.downHandler_.bind(this),this.element_.addEventListener("mousedown",this.boundDownHandler),this.element_.addEventListener("touchstart",this.boundDownHandler),this.boundUpHandler=this.upHandler_.bind(this),this.element_.addEventListener("mouseup",this.boundUpHandler),this.element_.addEventListener("mouseleave",this.boundUpHandler),this.element_.addEventListener("touchend",this.boundUpHandler),this.element_.addEventListener("blur",this.boundUpHandler),this.getFrameCount=function(){return this.frameCount_},this.setFrameCount=function(e){this.frameCount_=e},this.getRippleElement=function(){return this.rippleElement_},this.setRippleXY=function(e,t){this.x_=e,this.y_=t},this.setRippleStyles=function(t){if(null!==this.rippleElement_){var s,i,n,a="translate("+this.x_+"px, "+this.y_+"px)";t?(i=this.Constant_.INITIAL_SCALE,n=this.Constant_.INITIAL_SIZE):(i=this.Constant_.FINAL_SCALE,n=this.rippleSize_+"px",e&&(a="translate("+this.boundWidth/2+"px, "+this.boundHeight/2+"px)")),s="translate(-50%, -50%) "+a+i,this.rippleElement_.style.webkitTransform=s,this.rippleElement_.style.msTransform=s,this.rippleElement_.style.transform=s,t?this.rippleElement_.classList.remove(this.CssClasses_.IS_ANIMATING):this.rippleElement_.classList.add(this.CssClasses_.IS_ANIMATING)}},this.animFrameHandler=function(){this.frameCount_-- >0?window.requestAnimationFrame(this.animFrameHandler.bind(this)):this.setRippleStyles(!1)})}},s.register({constructor:S,classAsString:"MaterialRipple",cssClass:"mdl-js-ripple-effect",widget:!1})}();
10   -//# sourceMappingURL=material.min.js.map
web/static/js/vendor/material.min.js.map deleted
... ... @@ -1 +0,0 @@
1   -{"version":3,"sources":["tabs.js","layout.js","mdlComponentHandler.js","rAF.js","button.js","checkbox.js","icon-toggle.js","menu.js","progress.js","radio.js","slider.js","snackbar.js","spinner.js","switch.js","textfield.js","tooltip.js","data-table.js","ripple.js"],"names":["MaterialTab","tab","ctx","element_","classList","contains","CssClasses_","MDL_JS_RIPPLE_EFFECT","rippleContainer","document","createElement","add","MDL_RIPPLE_CONTAINER","ripple","MDL_RIPPLE","appendChild","addEventListener","e","getAttribute","charAt","preventDefault","href","split","panel","querySelector","resetTabState_","resetPanelState_","ACTIVE_CLASS","MaterialLayoutTab","tabs","panels","layout","selectTab","content_","IS_ACTIVE","tabBar_","JS_RIPPLE_EFFECT","RIPPLE_CONTAINER","RIPPLE","TAB_MANUAL_SWITCH","show","componentHandler","upgradeDom","optJsClass","optCssClass","upgradeElement","element","upgradeElements","elements","upgradeAllRegistered","registerUpgradedCallback","jsClass","callback","register","config","downgradeElements","nodes","findRegisteredClass_","name","optReplace","i","registeredComponents_","length","className","getUpgradedListOfElement_","dataUpgraded","isElementUpgraded_","upgradedList","indexOf","createEvent_","eventType","bubbles","cancelable","window","CustomEvent","ev","createEvent","initEvent","upgradeDomInternal","cssClass","registeredClass","querySelectorAll","n","upgradeElementInternal","Element","Error","upgradingEv","dispatchEvent","defaultPrevented","classesToUpgrade","push","forEach","component","setAttribute","join","instance","classConstructor","componentConfigProperty_","createdComponents_","j","m","callbacks","widget","upgradedEv","upgradeElementsInternal","Array","isArray","prototype","slice","call","HTMLElement","children","registerInternal","widgetMissing","newConfig","constructor","classAsString","item","hasOwnProperty","found","registerUpgradedCallbackInternal","regClass","upgradeAllRegisteredInternal","deconstructComponentInternal","componentIndex","splice","upgrades","componentPlace","downgradeNodesInternal","downgradeNode","node","filter","NodeList","Node","ComponentConfigPublic","ComponentConfig","Component","documentElement","Date","now","getTime","vendors","requestAnimationFrame","vp","cancelAnimationFrame","test","navigator","userAgent","lastTime","nextTime","Math","max","setTimeout","clearTimeout","MaterialButton","this","init","Constant_","RIPPLE_EFFECT","blurHandler_","event","blur","disable","disabled","enable","rippleElement_","boundRippleBlurHandler","bind","boundButtonBlurHandler","MaterialCheckbox","TINY_TIMEOUT","INPUT","BOX_OUTLINE","FOCUS_HELPER","TICK_OUTLINE","RIPPLE_IGNORE_EVENTS","RIPPLE_CENTER","IS_FOCUSED","IS_DISABLED","IS_CHECKED","IS_UPGRADED","onChange_","updateClasses_","onFocus_","onBlur_","remove","onMouseUp_","blur_","checkDisabled","checkToggleState","inputElement_","checked","check","uncheck","boxOutline","tickContainer","tickOutline","rippleContainerElement_","boundRippleMouseUp","boundInputOnChange","boundInputOnFocus","boundInputOnBlur","boundElementMouseUp","MaterialIconToggle","boundElementOnMouseUp","MaterialMenu","TRANSITION_DURATION_SECONDS","TRANSITION_DURATION_FRACTION","CLOSE_TIMEOUT","Keycodes_","ENTER","ESCAPE","SPACE","UP_ARROW","DOWN_ARROW","CONTAINER","OUTLINE","ITEM","ITEM_RIPPLE_CONTAINER","IS_VISIBLE","IS_ANIMATING","BOTTOM_LEFT","BOTTOM_RIGHT","TOP_LEFT","TOP_RIGHT","UNALIGNED","container","parentElement","insertBefore","removeChild","container_","outline","outline_","forElId","forEl","getElementById","forElement_","handleForClick_","handleForKeyboardEvent_","items","boundItemKeydown_","handleItemKeyboardEvent_","boundItemClick_","handleItemClick_","tabIndex","evt","rect","getBoundingClientRect","forRect","style","right","top","offsetTop","offsetHeight","left","offsetLeft","bottom","toggle","keyCode","focus","currentIndex","target","MouseEvent","click","hide","hasAttribute","stopPropagation","closing_","applyClip_","height","width","clip","removeAnimationEndListener_","addAnimationEndListener_","transitionDuration","itemDelay","transitionDelay","parentNode","removeEventListener","removeProperty","MaterialProgress","INDETERMINATE_CLASS","setProgress","p","progressbar_","setBuffer","bufferbar_","auxbar_","el","MaterialRadio","JS_RADIO","RADIO_BTN","RADIO_OUTER_CIRCLE","RADIO_INNER_CIRCLE","radios","getElementsByClassName","button","btnElement_","onMouseup_","boundChangeHandler_","boundFocusHandler_","boundBlurHandler_","boundMouseUpHandler_","outerCircle","innerCircle","MaterialSlider","isIE_","msPointerEnabled","IE_CONTAINER","SLIDER_CONTAINER","BACKGROUND_FLEX","BACKGROUND_LOWER","BACKGROUND_UPPER","IS_LOWEST_VALUE","onInput_","updateValueStyles_","onContainerMouseDown_","newEvent","buttons","clientX","clientY","y","fraction","value","min","backgroundLower_","flex","webkitFlex","backgroundUpper_","change","containerIE","backgroundFlex","boundInputHandler","boundChangeHandler","boundMouseUpHandler","boundContainerMouseDownHandler","MaterialSnackbar","textElement_","cssClasses_","MESSAGE","actionElement_","ACTION","active","actionHandler_","undefined","message_","actionText_","queuedNotifications_","setActionHidden_","ANIMATION_LENGTH","SNACKBAR","ACTIVE","displaySnackbar_","textContent","cleanup_","timeout_","showSnackbar","data","checkQueue_","shift","Boolean","removeAttribute","MaterialSpinner","MDL_SPINNER_LAYER_COUNT","MDL_SPINNER_LAYER","MDL_SPINNER_CIRCLE_CLIPPER","MDL_SPINNER_CIRCLE","MDL_SPINNER_GAP_PATCH","MDL_SPINNER_LEFT","MDL_SPINNER_RIGHT","createLayer","index","layer","leftClipper","gapPatch","rightClipper","circleOwners","circle","stop","start","MaterialSwitch","TRACK","THUMB","on","off","track","thumb","focusHelper","boundFocusHandler","boundBlurHandler","MaterialTabs","TAB_CLASS","PANEL_CLASS","UPGRADED_CLASS","MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS","initTabs_","tabs_","panels_","k","MaterialTextfield","maxRows","NO_MAX_ROWS","MAX_ROWS_ATTRIBUTE","LABEL","IS_DIRTY","IS_INVALID","HAS_PLACEHOLDER","onKeyDown_","currentRowCount","onReset_","checkValidity","checkDirty","checkFocus","input_","validity","valid","label_","parseInt","isNaN","boundUpdateClassesHandler","boundResetHandler","boundKeyDownHandler","invalid","MaterialTooltip","BOTTOM","LEFT","RIGHT","TOP","handleMouseEnter_","props","marginLeft","offsetWidth","marginTop","hideTooltip_","boundMouseEnterHandler","boundMouseLeaveAndScrollHandler","MaterialLayout","MAX_WIDTH","TAB_SCROLL_PIXELS","RESIZE_TIMEOUT","MENU_ICON","CHEVRON_LEFT","CHEVRON_RIGHT","Mode_","STANDARD","SEAMED","WATERFALL","SCROLL","HEADER","DRAWER","CONTENT","DRAWER_BTN","ICON","HEADER_SEAMED","HEADER_WATERFALL","HEADER_SCROLL","FIXED_HEADER","OBFUSCATOR","TAB_BAR","TAB_CONTAINER","TAB","TAB_BAR_BUTTON","TAB_BAR_LEFT_BUTTON","TAB_BAR_RIGHT_BUTTON","PANEL","HAS_DRAWER","HAS_TABS","HAS_SCROLLING_HEADER","CASTING_SHADOW","IS_COMPACT","IS_SMALL_SCREEN","IS_DRAWER_OPEN","ON_LARGE_SCREEN","ON_SMALL_SCREEN","contentScrollHandler_","header_","headerVisible","scrollTop","keyboardEventHandler_","drawer_","toggleDrawer","screenSizeHandler_","screenSizeMediaQuery_","matches","obfuscator_","drawerToggleHandler_","type","headerTransitionEndHandler_","headerClickHandler_","tabBar","drawerButton","focusedElement","directChildren","childNodes","numChildren","c","child","persisted","overflowY","mode","drawerButtonIcon","innerHTML","firstChild","obfuscator","matchMedia","addListener","tabContainer","leftButton","leftButtonIcon","scrollLeft","rightButton","rightButtonIcon","tabUpdateHandler","scrollWidth","windowResizeHandler","resizeTimeoutId_","MaterialDataTable","DATA_TABLE","SELECTABLE","SELECT_ELEMENT","IS_SELECTED","selectRow_","checkbox","row","opt_rows","createCheckbox_","label","labelClasses","firstHeader","bodyRows","footRows","rows","concat","th","headerCheckbox","firstCell","td","nodeName","toUpperCase","rowCheckbox","MaterialRipple","INITIAL_SCALE","INITIAL_SIZE","INITIAL_OPACITY","FINAL_OPACITY","FINAL_SCALE","RIPPLE_EFFECT_IGNORE_EVENTS","downHandler_","boundHeight","boundWidth","rippleSize_","sqrt","ignoringMouseDown_","frameCount","getFrameCount","setFrameCount","x","bound","currentTarget","round","touches","setRippleXY","setRippleStyles","animFrameHandler","upHandler_","detail","recentering","frameCount_","x_","y_","boundDownHandler","boundUpHandler","fC","getRippleElement","newX","newY","transformString","scale","size","offset","webkitTransform","msTransform","transform"],"mappings":"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","file":"material.min.js","sourcesContent":["/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Tabs MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {Element} element The element that will be upgraded.\n */\nvar MaterialTabs = function MaterialTabs(element) {\n // Stores the HTML element.\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialTabs'] = MaterialTabs;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string}\n * @private\n */\nMaterialTabs.prototype.Constant_ = {};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialTabs.prototype.CssClasses_ = {\n TAB_CLASS: 'mdl-tabs__tab',\n PANEL_CLASS: 'mdl-tabs__panel',\n ACTIVE_CLASS: 'is-active',\n UPGRADED_CLASS: 'is-upgraded',\n MDL_JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',\n MDL_RIPPLE_CONTAINER: 'mdl-tabs__ripple-container',\n MDL_RIPPLE: 'mdl-ripple',\n MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events'\n};\n/**\n * Handle clicks to a tabs component\n *\n * @private\n */\nMaterialTabs.prototype.initTabs_ = function () {\n if (this.element_.classList.contains(this.CssClasses_.MDL_JS_RIPPLE_EFFECT)) {\n this.element_.classList.add(this.CssClasses_.MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS);\n }\n // Select element tabs, document panels\n this.tabs_ = this.element_.querySelectorAll('.' + this.CssClasses_.TAB_CLASS);\n this.panels_ = this.element_.querySelectorAll('.' + this.CssClasses_.PANEL_CLASS);\n // Create new tabs for each tab element\n for (var i = 0; i < this.tabs_.length; i++) {\n new MaterialTab(this.tabs_[i], this);\n }\n this.element_.classList.add(this.CssClasses_.UPGRADED_CLASS);\n};\n/**\n * Reset tab state, dropping active classes\n *\n * @private\n */\nMaterialTabs.prototype.resetTabState_ = function () {\n for (var k = 0; k < this.tabs_.length; k++) {\n this.tabs_[k].classList.remove(this.CssClasses_.ACTIVE_CLASS);\n }\n};\n/**\n * Reset panel state, droping active classes\n *\n * @private\n */\nMaterialTabs.prototype.resetPanelState_ = function () {\n for (var j = 0; j < this.panels_.length; j++) {\n this.panels_[j].classList.remove(this.CssClasses_.ACTIVE_CLASS);\n }\n};\n/**\n * Initialize element.\n */\nMaterialTabs.prototype.init = function () {\n if (this.element_) {\n this.initTabs_();\n }\n};\n/**\n * Constructor for an individual tab.\n *\n * @constructor\n * @param {Element} tab The HTML element for the tab.\n * @param {MaterialTabs} ctx The MaterialTabs object that owns the tab.\n */\nfunction MaterialTab(tab, ctx) {\n if (tab) {\n if (ctx.element_.classList.contains(ctx.CssClasses_.MDL_JS_RIPPLE_EFFECT)) {\n var rippleContainer = document.createElement('span');\n rippleContainer.classList.add(ctx.CssClasses_.MDL_RIPPLE_CONTAINER);\n rippleContainer.classList.add(ctx.CssClasses_.MDL_JS_RIPPLE_EFFECT);\n var ripple = document.createElement('span');\n ripple.classList.add(ctx.CssClasses_.MDL_RIPPLE);\n rippleContainer.appendChild(ripple);\n tab.appendChild(rippleContainer);\n }\n tab.addEventListener('click', function (e) {\n if (tab.getAttribute('href').charAt(0) === '#') {\n e.preventDefault();\n var href = tab.href.split('#')[1];\n var panel = ctx.element_.querySelector('#' + href);\n ctx.resetTabState_();\n ctx.resetPanelState_();\n tab.classList.add(ctx.CssClasses_.ACTIVE_CLASS);\n panel.classList.add(ctx.CssClasses_.ACTIVE_CLASS);\n }\n });\n }\n}\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialTabs,\n classAsString: 'MaterialTabs',\n cssClass: 'mdl-js-tabs'\n});","/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Layout MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialLayout = function MaterialLayout(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialLayout'] = MaterialLayout;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialLayout.prototype.Constant_ = {\n MAX_WIDTH: '(max-width: 1024px)',\n TAB_SCROLL_PIXELS: 100,\n RESIZE_TIMEOUT: 100,\n MENU_ICON: '&#xE5D2;',\n CHEVRON_LEFT: 'chevron_left',\n CHEVRON_RIGHT: 'chevron_right'\n};\n/**\n * Keycodes, for code readability.\n *\n * @enum {number}\n * @private\n */\nMaterialLayout.prototype.Keycodes_ = {\n ENTER: 13,\n ESCAPE: 27,\n SPACE: 32\n};\n/**\n * Modes.\n *\n * @enum {number}\n * @private\n */\nMaterialLayout.prototype.Mode_ = {\n STANDARD: 0,\n SEAMED: 1,\n WATERFALL: 2,\n SCROLL: 3\n};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialLayout.prototype.CssClasses_ = {\n CONTAINER: 'mdl-layout__container',\n HEADER: 'mdl-layout__header',\n DRAWER: 'mdl-layout__drawer',\n CONTENT: 'mdl-layout__content',\n DRAWER_BTN: 'mdl-layout__drawer-button',\n ICON: 'material-icons',\n JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',\n RIPPLE_CONTAINER: 'mdl-layout__tab-ripple-container',\n RIPPLE: 'mdl-ripple',\n RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',\n HEADER_SEAMED: 'mdl-layout__header--seamed',\n HEADER_WATERFALL: 'mdl-layout__header--waterfall',\n HEADER_SCROLL: 'mdl-layout__header--scroll',\n FIXED_HEADER: 'mdl-layout--fixed-header',\n OBFUSCATOR: 'mdl-layout__obfuscator',\n TAB_BAR: 'mdl-layout__tab-bar',\n TAB_CONTAINER: 'mdl-layout__tab-bar-container',\n TAB: 'mdl-layout__tab',\n TAB_BAR_BUTTON: 'mdl-layout__tab-bar-button',\n TAB_BAR_LEFT_BUTTON: 'mdl-layout__tab-bar-left-button',\n TAB_BAR_RIGHT_BUTTON: 'mdl-layout__tab-bar-right-button',\n TAB_MANUAL_SWITCH: 'mdl-layout__tab-manual-switch',\n PANEL: 'mdl-layout__tab-panel',\n HAS_DRAWER: 'has-drawer',\n HAS_TABS: 'has-tabs',\n HAS_SCROLLING_HEADER: 'has-scrolling-header',\n CASTING_SHADOW: 'is-casting-shadow',\n IS_COMPACT: 'is-compact',\n IS_SMALL_SCREEN: 'is-small-screen',\n IS_DRAWER_OPEN: 'is-visible',\n IS_ACTIVE: 'is-active',\n IS_UPGRADED: 'is-upgraded',\n IS_ANIMATING: 'is-animating',\n ON_LARGE_SCREEN: 'mdl-layout--large-screen-only',\n ON_SMALL_SCREEN: 'mdl-layout--small-screen-only'\n};\n/**\n * Handles scrolling on the content.\n *\n * @private\n */\nMaterialLayout.prototype.contentScrollHandler_ = function () {\n if (this.header_.classList.contains(this.CssClasses_.IS_ANIMATING)) {\n return;\n }\n var headerVisible = !this.element_.classList.contains(this.CssClasses_.IS_SMALL_SCREEN) || this.element_.classList.contains(this.CssClasses_.FIXED_HEADER);\n if (this.content_.scrollTop > 0 && !this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {\n this.header_.classList.add(this.CssClasses_.CASTING_SHADOW);\n this.header_.classList.add(this.CssClasses_.IS_COMPACT);\n if (headerVisible) {\n this.header_.classList.add(this.CssClasses_.IS_ANIMATING);\n }\n } else if (this.content_.scrollTop <= 0 && this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {\n this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW);\n this.header_.classList.remove(this.CssClasses_.IS_COMPACT);\n if (headerVisible) {\n this.header_.classList.add(this.CssClasses_.IS_ANIMATING);\n }\n }\n};\n/**\n * Handles a keyboard event on the drawer.\n *\n * @param {Event} evt The event that fired.\n * @private\n */\nMaterialLayout.prototype.keyboardEventHandler_ = function (evt) {\n // Only react when the drawer is open.\n if (evt.keyCode === this.Keycodes_.ESCAPE && this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) {\n this.toggleDrawer();\n }\n};\n/**\n * Handles changes in screen size.\n *\n * @private\n */\nMaterialLayout.prototype.screenSizeHandler_ = function () {\n if (this.screenSizeMediaQuery_.matches) {\n this.element_.classList.add(this.CssClasses_.IS_SMALL_SCREEN);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN);\n // Collapse drawer (if any) when moving to a large screen size.\n if (this.drawer_) {\n this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN);\n this.obfuscator_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN);\n }\n }\n};\n/**\n * Handles events of drawer button.\n *\n * @param {Event} evt The event that fired.\n * @private\n */\nMaterialLayout.prototype.drawerToggleHandler_ = function (evt) {\n if (evt && evt.type === 'keydown') {\n if (evt.keyCode === this.Keycodes_.SPACE || evt.keyCode === this.Keycodes_.ENTER) {\n // prevent scrolling in drawer nav\n evt.preventDefault();\n } else {\n // prevent other keys\n return;\n }\n }\n this.toggleDrawer();\n};\n/**\n * Handles (un)setting the `is-animating` class\n *\n * @private\n */\nMaterialLayout.prototype.headerTransitionEndHandler_ = function () {\n this.header_.classList.remove(this.CssClasses_.IS_ANIMATING);\n};\n/**\n * Handles expanding the header on click\n *\n * @private\n */\nMaterialLayout.prototype.headerClickHandler_ = function () {\n if (this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {\n this.header_.classList.remove(this.CssClasses_.IS_COMPACT);\n this.header_.classList.add(this.CssClasses_.IS_ANIMATING);\n }\n};\n/**\n * Reset tab state, dropping active classes\n *\n * @private\n */\nMaterialLayout.prototype.resetTabState_ = function (tabBar) {\n for (var k = 0; k < tabBar.length; k++) {\n tabBar[k].classList.remove(this.CssClasses_.IS_ACTIVE);\n }\n};\n/**\n * Reset panel state, droping active classes\n *\n * @private\n */\nMaterialLayout.prototype.resetPanelState_ = function (panels) {\n for (var j = 0; j < panels.length; j++) {\n panels[j].classList.remove(this.CssClasses_.IS_ACTIVE);\n }\n};\n/**\n * Toggle drawer state\n *\n * @public\n */\nMaterialLayout.prototype.toggleDrawer = function () {\n var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN);\n this.drawer_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN);\n this.obfuscator_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN);\n // Set accessibility properties.\n if (this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) {\n this.drawer_.setAttribute('aria-hidden', 'false');\n drawerButton.setAttribute('aria-expanded', 'true');\n } else {\n this.drawer_.setAttribute('aria-hidden', 'true');\n drawerButton.setAttribute('aria-expanded', 'false');\n }\n};\nMaterialLayout.prototype['toggleDrawer'] = MaterialLayout.prototype.toggleDrawer;\n/**\n * Initialize element.\n */\nMaterialLayout.prototype.init = function () {\n if (this.element_) {\n var container = document.createElement('div');\n container.classList.add(this.CssClasses_.CONTAINER);\n var focusedElement = this.element_.querySelector(':focus');\n this.element_.parentElement.insertBefore(container, this.element_);\n this.element_.parentElement.removeChild(this.element_);\n container.appendChild(this.element_);\n if (focusedElement) {\n focusedElement.focus();\n }\n var directChildren = this.element_.childNodes;\n var numChildren = directChildren.length;\n for (var c = 0; c < numChildren; c++) {\n var child = directChildren[c];\n if (child.classList && child.classList.contains(this.CssClasses_.HEADER)) {\n this.header_ = child;\n }\n if (child.classList && child.classList.contains(this.CssClasses_.DRAWER)) {\n this.drawer_ = child;\n }\n if (child.classList && child.classList.contains(this.CssClasses_.CONTENT)) {\n this.content_ = child;\n }\n }\n window.addEventListener('pageshow', function (e) {\n if (e.persisted) {\n // when page is loaded from back/forward cache\n // trigger repaint to let layout scroll in safari\n this.element_.style.overflowY = 'hidden';\n requestAnimationFrame(function () {\n this.element_.style.overflowY = '';\n }.bind(this));\n }\n }.bind(this), false);\n if (this.header_) {\n this.tabBar_ = this.header_.querySelector('.' + this.CssClasses_.TAB_BAR);\n }\n var mode = this.Mode_.STANDARD;\n if (this.header_) {\n if (this.header_.classList.contains(this.CssClasses_.HEADER_SEAMED)) {\n mode = this.Mode_.SEAMED;\n } else if (this.header_.classList.contains(this.CssClasses_.HEADER_WATERFALL)) {\n mode = this.Mode_.WATERFALL;\n this.header_.addEventListener('transitionend', this.headerTransitionEndHandler_.bind(this));\n this.header_.addEventListener('click', this.headerClickHandler_.bind(this));\n } else if (this.header_.classList.contains(this.CssClasses_.HEADER_SCROLL)) {\n mode = this.Mode_.SCROLL;\n container.classList.add(this.CssClasses_.HAS_SCROLLING_HEADER);\n }\n if (mode === this.Mode_.STANDARD) {\n this.header_.classList.add(this.CssClasses_.CASTING_SHADOW);\n if (this.tabBar_) {\n this.tabBar_.classList.add(this.CssClasses_.CASTING_SHADOW);\n }\n } else if (mode === this.Mode_.SEAMED || mode === this.Mode_.SCROLL) {\n this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW);\n if (this.tabBar_) {\n this.tabBar_.classList.remove(this.CssClasses_.CASTING_SHADOW);\n }\n } else if (mode === this.Mode_.WATERFALL) {\n // Add and remove shadows depending on scroll position.\n // Also add/remove auxiliary class for styling of the compact version of\n // the header.\n this.content_.addEventListener('scroll', this.contentScrollHandler_.bind(this));\n this.contentScrollHandler_();\n }\n }\n // Add drawer toggling button to our layout, if we have an openable drawer.\n if (this.drawer_) {\n var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN);\n if (!drawerButton) {\n drawerButton = document.createElement('div');\n drawerButton.setAttribute('aria-expanded', 'false');\n drawerButton.setAttribute('role', 'button');\n drawerButton.setAttribute('tabindex', '0');\n drawerButton.classList.add(this.CssClasses_.DRAWER_BTN);\n var drawerButtonIcon = document.createElement('i');\n drawerButtonIcon.classList.add(this.CssClasses_.ICON);\n drawerButtonIcon.innerHTML = this.Constant_.MENU_ICON;\n drawerButton.appendChild(drawerButtonIcon);\n }\n if (this.drawer_.classList.contains(this.CssClasses_.ON_LARGE_SCREEN)) {\n //If drawer has ON_LARGE_SCREEN class then add it to the drawer toggle button as well.\n drawerButton.classList.add(this.CssClasses_.ON_LARGE_SCREEN);\n } else if (this.drawer_.classList.contains(this.CssClasses_.ON_SMALL_SCREEN)) {\n //If drawer has ON_SMALL_SCREEN class then add it to the drawer toggle button as well.\n drawerButton.classList.add(this.CssClasses_.ON_SMALL_SCREEN);\n }\n drawerButton.addEventListener('click', this.drawerToggleHandler_.bind(this));\n drawerButton.addEventListener('keydown', this.drawerToggleHandler_.bind(this));\n // Add a class if the layout has a drawer, for altering the left padding.\n // Adds the HAS_DRAWER to the elements since this.header_ may or may\n // not be present.\n this.element_.classList.add(this.CssClasses_.HAS_DRAWER);\n // If we have a fixed header, add the button to the header rather than\n // the layout.\n if (this.element_.classList.contains(this.CssClasses_.FIXED_HEADER)) {\n this.header_.insertBefore(drawerButton, this.header_.firstChild);\n } else {\n this.element_.insertBefore(drawerButton, this.content_);\n }\n var obfuscator = document.createElement('div');\n obfuscator.classList.add(this.CssClasses_.OBFUSCATOR);\n this.element_.appendChild(obfuscator);\n obfuscator.addEventListener('click', this.drawerToggleHandler_.bind(this));\n this.obfuscator_ = obfuscator;\n this.drawer_.addEventListener('keydown', this.keyboardEventHandler_.bind(this));\n this.drawer_.setAttribute('aria-hidden', 'true');\n }\n // Keep an eye on screen size, and add/remove auxiliary class for styling\n // of small screens.\n this.screenSizeMediaQuery_ = window.matchMedia(this.Constant_.MAX_WIDTH);\n this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this));\n this.screenSizeHandler_();\n // Initialize tabs, if any.\n if (this.header_ && this.tabBar_) {\n this.element_.classList.add(this.CssClasses_.HAS_TABS);\n var tabContainer = document.createElement('div');\n tabContainer.classList.add(this.CssClasses_.TAB_CONTAINER);\n this.header_.insertBefore(tabContainer, this.tabBar_);\n this.header_.removeChild(this.tabBar_);\n var leftButton = document.createElement('div');\n leftButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON);\n leftButton.classList.add(this.CssClasses_.TAB_BAR_LEFT_BUTTON);\n var leftButtonIcon = document.createElement('i');\n leftButtonIcon.classList.add(this.CssClasses_.ICON);\n leftButtonIcon.textContent = this.Constant_.CHEVRON_LEFT;\n leftButton.appendChild(leftButtonIcon);\n leftButton.addEventListener('click', function () {\n this.tabBar_.scrollLeft -= this.Constant_.TAB_SCROLL_PIXELS;\n }.bind(this));\n var rightButton = document.createElement('div');\n rightButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON);\n rightButton.classList.add(this.CssClasses_.TAB_BAR_RIGHT_BUTTON);\n var rightButtonIcon = document.createElement('i');\n rightButtonIcon.classList.add(this.CssClasses_.ICON);\n rightButtonIcon.textContent = this.Constant_.CHEVRON_RIGHT;\n rightButton.appendChild(rightButtonIcon);\n rightButton.addEventListener('click', function () {\n this.tabBar_.scrollLeft += this.Constant_.TAB_SCROLL_PIXELS;\n }.bind(this));\n tabContainer.appendChild(leftButton);\n tabContainer.appendChild(this.tabBar_);\n tabContainer.appendChild(rightButton);\n // Add and remove tab buttons depending on scroll position and total\n // window size.\n var tabUpdateHandler = function () {\n if (this.tabBar_.scrollLeft > 0) {\n leftButton.classList.add(this.CssClasses_.IS_ACTIVE);\n } else {\n leftButton.classList.remove(this.CssClasses_.IS_ACTIVE);\n }\n if (this.tabBar_.scrollLeft < this.tabBar_.scrollWidth - this.tabBar_.offsetWidth) {\n rightButton.classList.add(this.CssClasses_.IS_ACTIVE);\n } else {\n rightButton.classList.remove(this.CssClasses_.IS_ACTIVE);\n }\n }.bind(this);\n this.tabBar_.addEventListener('scroll', tabUpdateHandler);\n tabUpdateHandler();\n // Update tabs when the window resizes.\n var windowResizeHandler = function () {\n // Use timeouts to make sure it doesn't happen too often.\n if (this.resizeTimeoutId_) {\n clearTimeout(this.resizeTimeoutId_);\n }\n this.resizeTimeoutId_ = setTimeout(function () {\n tabUpdateHandler();\n this.resizeTimeoutId_ = null;\n }.bind(this), this.Constant_.RESIZE_TIMEOUT);\n }.bind(this);\n window.addEventListener('resize', windowResizeHandler);\n if (this.tabBar_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) {\n this.tabBar_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);\n }\n // Select element tabs, document panels\n var tabs = this.tabBar_.querySelectorAll('.' + this.CssClasses_.TAB);\n var panels = this.content_.querySelectorAll('.' + this.CssClasses_.PANEL);\n // Create new tabs for each tab element\n for (var i = 0; i < tabs.length; i++) {\n new MaterialLayoutTab(tabs[i], tabs, panels, this);\n }\n }\n this.element_.classList.add(this.CssClasses_.IS_UPGRADED);\n }\n};\n/**\n * Constructor for an individual tab.\n *\n * @constructor\n * @param {HTMLElement} tab The HTML element for the tab.\n * @param {!Array<HTMLElement>} tabs Array with HTML elements for all tabs.\n * @param {!Array<HTMLElement>} panels Array with HTML elements for all panels.\n * @param {MaterialLayout} layout The MaterialLayout object that owns the tab.\n */\nfunction MaterialLayoutTab(tab, tabs, panels, layout) {\n /**\n * Auxiliary method to programmatically select a tab in the UI.\n */\n function selectTab() {\n var href = tab.href.split('#')[1];\n var panel = layout.content_.querySelector('#' + href);\n layout.resetTabState_(tabs);\n layout.resetPanelState_(panels);\n tab.classList.add(layout.CssClasses_.IS_ACTIVE);\n panel.classList.add(layout.CssClasses_.IS_ACTIVE);\n }\n if (layout.tabBar_.classList.contains(layout.CssClasses_.JS_RIPPLE_EFFECT)) {\n var rippleContainer = document.createElement('span');\n rippleContainer.classList.add(layout.CssClasses_.RIPPLE_CONTAINER);\n rippleContainer.classList.add(layout.CssClasses_.JS_RIPPLE_EFFECT);\n var ripple = document.createElement('span');\n ripple.classList.add(layout.CssClasses_.RIPPLE);\n rippleContainer.appendChild(ripple);\n tab.appendChild(rippleContainer);\n }\n if (!layout.tabBar_.classList.contains(layout.CssClasses_.TAB_MANUAL_SWITCH)) {\n tab.addEventListener('click', function (e) {\n if (tab.getAttribute('href').charAt(0) === '#') {\n e.preventDefault();\n selectTab();\n }\n });\n }\n tab.show = selectTab;\n}\nwindow['MaterialLayoutTab'] = MaterialLayoutTab;\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialLayout,\n classAsString: 'MaterialLayout',\n cssClass: 'mdl-js-layout'\n});","/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * A component handler interface using the revealing module design pattern.\n * More details on this design pattern here:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @author Jason Mayes.\n */\n/* exported componentHandler */\n\n// Pre-defining the componentHandler interface, for closure documentation and\n// static verification.\nvar componentHandler = {\n /**\n * Searches existing DOM for elements of our component type and upgrades them\n * if they have not already been upgraded.\n *\n * @param {string=} optJsClass the programatic name of the element class we\n * need to create a new instance of.\n * @param {string=} optCssClass the name of the CSS class elements of this\n * type will have.\n */\n upgradeDom: function(optJsClass, optCssClass) {},\n /**\n * Upgrades a specific element rather than all in the DOM.\n *\n * @param {!Element} element The element we wish to upgrade.\n * @param {string=} optJsClass Optional name of the class we want to upgrade\n * the element to.\n */\n upgradeElement: function(element, optJsClass) {},\n /**\n * Upgrades a specific list of elements rather than all in the DOM.\n *\n * @param {!Element|!Array<!Element>|!NodeList|!HTMLCollection} elements\n * The elements we wish to upgrade.\n */\n upgradeElements: function(elements) {},\n /**\n * Upgrades all registered components found in the current DOM. This is\n * automatically called on window load.\n */\n upgradeAllRegistered: function() {},\n /**\n * Allows user to be alerted to any upgrades that are performed for a given\n * component type\n *\n * @param {string} jsClass The class name of the MDL component we wish\n * to hook into for any upgrades performed.\n * @param {function(!HTMLElement)} callback The function to call upon an\n * upgrade. This function should expect 1 parameter - the HTMLElement which\n * got upgraded.\n */\n registerUpgradedCallback: function(jsClass, callback) {},\n /**\n * Registers a class for future use and attempts to upgrade existing DOM.\n *\n * @param {componentHandler.ComponentConfigPublic} config the registration configuration\n */\n register: function(config) {},\n /**\n * Downgrade either a given node, an array of nodes, or a NodeList.\n *\n * @param {!Node|!Array<!Node>|!NodeList} nodes\n */\n downgradeElements: function(nodes) {}\n};\n\ncomponentHandler = (function() {\n 'use strict';\n\n /** @type {!Array<componentHandler.ComponentConfig>} */\n var registeredComponents_ = [];\n\n /** @type {!Array<componentHandler.Component>} */\n var createdComponents_ = [];\n\n var componentConfigProperty_ = 'mdlComponentConfigInternal_';\n\n /**\n * Searches registered components for a class we are interested in using.\n * Optionally replaces a match with passed object if specified.\n *\n * @param {string} name The name of a class we want to use.\n * @param {componentHandler.ComponentConfig=} optReplace Optional object to replace match with.\n * @return {!Object|boolean}\n * @private\n */\n function findRegisteredClass_(name, optReplace) {\n for (var i = 0; i < registeredComponents_.length; i++) {\n if (registeredComponents_[i].className === name) {\n if (typeof optReplace !== 'undefined') {\n registeredComponents_[i] = optReplace;\n }\n return registeredComponents_[i];\n }\n }\n return false;\n }\n\n /**\n * Returns an array of the classNames of the upgraded classes on the element.\n *\n * @param {!Element} element The element to fetch data from.\n * @return {!Array<string>}\n * @private\n */\n function getUpgradedListOfElement_(element) {\n var dataUpgraded = element.getAttribute('data-upgraded');\n // Use `['']` as default value to conform the `,name,name...` style.\n return dataUpgraded === null ? [''] : dataUpgraded.split(',');\n }\n\n /**\n * Returns true if the given element has already been upgraded for the given\n * class.\n *\n * @param {!Element} element The element we want to check.\n * @param {string} jsClass The class to check for.\n * @returns {boolean}\n * @private\n */\n function isElementUpgraded_(element, jsClass) {\n var upgradedList = getUpgradedListOfElement_(element);\n return upgradedList.indexOf(jsClass) !== -1;\n }\n\n /**\n * Create an event object.\n *\n * @param {string} eventType The type name of the event.\n * @param {boolean} bubbles Whether the event should bubble up the DOM.\n * @param {boolean} cancelable Whether the event can be canceled.\n * @returns {!Event}\n */\n function createEvent_(eventType, bubbles, cancelable) {\n if ('CustomEvent' in window && typeof window.CustomEvent === 'function') {\n return new CustomEvent(eventType, {\n bubbles: bubbles,\n cancelable: cancelable\n });\n } else {\n var ev = document.createEvent('Events');\n ev.initEvent(eventType, bubbles, cancelable);\n return ev;\n }\n }\n\n /**\n * Searches existing DOM for elements of our component type and upgrades them\n * if they have not already been upgraded.\n *\n * @param {string=} optJsClass the programatic name of the element class we\n * need to create a new instance of.\n * @param {string=} optCssClass the name of the CSS class elements of this\n * type will have.\n */\n function upgradeDomInternal(optJsClass, optCssClass) {\n if (typeof optJsClass === 'undefined' &&\n typeof optCssClass === 'undefined') {\n for (var i = 0; i < registeredComponents_.length; i++) {\n upgradeDomInternal(registeredComponents_[i].className,\n registeredComponents_[i].cssClass);\n }\n } else {\n var jsClass = /** @type {string} */ (optJsClass);\n if (typeof optCssClass === 'undefined') {\n var registeredClass = findRegisteredClass_(jsClass);\n if (registeredClass) {\n optCssClass = registeredClass.cssClass;\n }\n }\n\n var elements = document.querySelectorAll('.' + optCssClass);\n for (var n = 0; n < elements.length; n++) {\n upgradeElementInternal(elements[n], jsClass);\n }\n }\n }\n\n /**\n * Upgrades a specific element rather than all in the DOM.\n *\n * @param {!Element} element The element we wish to upgrade.\n * @param {string=} optJsClass Optional name of the class we want to upgrade\n * the element to.\n */\n function upgradeElementInternal(element, optJsClass) {\n // Verify argument type.\n if (!(typeof element === 'object' && element instanceof Element)) {\n throw new Error('Invalid argument provided to upgrade MDL element.');\n }\n // Allow upgrade to be canceled by canceling emitted event.\n var upgradingEv = createEvent_('mdl-componentupgrading', true, true);\n element.dispatchEvent(upgradingEv);\n if (upgradingEv.defaultPrevented) {\n return;\n }\n\n var upgradedList = getUpgradedListOfElement_(element);\n var classesToUpgrade = [];\n // If jsClass is not provided scan the registered components to find the\n // ones matching the element's CSS classList.\n if (!optJsClass) {\n var classList = element.classList;\n registeredComponents_.forEach(function(component) {\n // Match CSS & Not to be upgraded & Not upgraded.\n if (classList.contains(component.cssClass) &&\n classesToUpgrade.indexOf(component) === -1 &&\n !isElementUpgraded_(element, component.className)) {\n classesToUpgrade.push(component);\n }\n });\n } else if (!isElementUpgraded_(element, optJsClass)) {\n classesToUpgrade.push(findRegisteredClass_(optJsClass));\n }\n\n // Upgrade the element for each classes.\n for (var i = 0, n = classesToUpgrade.length, registeredClass; i < n; i++) {\n registeredClass = classesToUpgrade[i];\n if (registeredClass) {\n // Mark element as upgraded.\n upgradedList.push(registeredClass.className);\n element.setAttribute('data-upgraded', upgradedList.join(','));\n var instance = new registeredClass.classConstructor(element);\n instance[componentConfigProperty_] = registeredClass;\n createdComponents_.push(instance);\n // Call any callbacks the user has registered with this component type.\n for (var j = 0, m = registeredClass.callbacks.length; j < m; j++) {\n registeredClass.callbacks[j](element);\n }\n\n if (registeredClass.widget) {\n // Assign per element instance for control over API\n element[registeredClass.className] = instance;\n }\n } else {\n throw new Error(\n 'Unable to find a registered component for the given class.');\n }\n\n var upgradedEv = createEvent_('mdl-componentupgraded', true, false);\n element.dispatchEvent(upgradedEv);\n }\n }\n\n /**\n * Upgrades a specific list of elements rather than all in the DOM.\n *\n * @param {!Element|!Array<!Element>|!NodeList|!HTMLCollection} elements\n * The elements we wish to upgrade.\n */\n function upgradeElementsInternal(elements) {\n if (!Array.isArray(elements)) {\n if (elements instanceof Element) {\n elements = [elements];\n } else {\n elements = Array.prototype.slice.call(elements);\n }\n }\n for (var i = 0, n = elements.length, element; i < n; i++) {\n element = elements[i];\n if (element instanceof HTMLElement) {\n upgradeElementInternal(element);\n if (element.children.length > 0) {\n upgradeElementsInternal(element.children);\n }\n }\n }\n }\n\n /**\n * Registers a class for future use and attempts to upgrade existing DOM.\n *\n * @param {componentHandler.ComponentConfigPublic} config\n */\n function registerInternal(config) {\n // In order to support both Closure-compiled and uncompiled code accessing\n // this method, we need to allow for both the dot and array syntax for\n // property access. You'll therefore see the `foo.bar || foo['bar']`\n // pattern repeated across this method.\n var widgetMissing = (typeof config.widget === 'undefined' &&\n typeof config['widget'] === 'undefined');\n var widget = true;\n\n if (!widgetMissing) {\n widget = config.widget || config['widget'];\n }\n\n var newConfig = /** @type {componentHandler.ComponentConfig} */ ({\n classConstructor: config.constructor || config['constructor'],\n className: config.classAsString || config['classAsString'],\n cssClass: config.cssClass || config['cssClass'],\n widget: widget,\n callbacks: []\n });\n\n registeredComponents_.forEach(function(item) {\n if (item.cssClass === newConfig.cssClass) {\n throw new Error('The provided cssClass has already been registered: ' + item.cssClass);\n }\n if (item.className === newConfig.className) {\n throw new Error('The provided className has already been registered');\n }\n });\n\n if (config.constructor.prototype\n .hasOwnProperty(componentConfigProperty_)) {\n throw new Error(\n 'MDL component classes must not have ' + componentConfigProperty_ +\n ' defined as a property.');\n }\n\n var found = findRegisteredClass_(config.classAsString, newConfig);\n\n if (!found) {\n registeredComponents_.push(newConfig);\n }\n }\n\n /**\n * Allows user to be alerted to any upgrades that are performed for a given\n * component type\n *\n * @param {string} jsClass The class name of the MDL component we wish\n * to hook into for any upgrades performed.\n * @param {function(!HTMLElement)} callback The function to call upon an\n * upgrade. This function should expect 1 parameter - the HTMLElement which\n * got upgraded.\n */\n function registerUpgradedCallbackInternal(jsClass, callback) {\n var regClass = findRegisteredClass_(jsClass);\n if (regClass) {\n regClass.callbacks.push(callback);\n }\n }\n\n /**\n * Upgrades all registered components found in the current DOM. This is\n * automatically called on window load.\n */\n function upgradeAllRegisteredInternal() {\n for (var n = 0; n < registeredComponents_.length; n++) {\n upgradeDomInternal(registeredComponents_[n].className);\n }\n }\n\n /**\n * Check the component for the downgrade method.\n * Execute if found.\n * Remove component from createdComponents list.\n *\n * @param {?componentHandler.Component} component\n */\n function deconstructComponentInternal(component) {\n if (component) {\n var componentIndex = createdComponents_.indexOf(component);\n createdComponents_.splice(componentIndex, 1);\n\n var upgrades = component.element_.getAttribute('data-upgraded').split(',');\n var componentPlace = upgrades.indexOf(component[componentConfigProperty_].classAsString);\n upgrades.splice(componentPlace, 1);\n component.element_.setAttribute('data-upgraded', upgrades.join(','));\n\n var ev = createEvent_('mdl-componentdowngraded', true, false);\n component.element_.dispatchEvent(ev);\n }\n }\n\n /**\n * Downgrade either a given node, an array of nodes, or a NodeList.\n *\n * @param {!Node|!Array<!Node>|!NodeList} nodes\n */\n function downgradeNodesInternal(nodes) {\n /**\n * Auxiliary function to downgrade a single node.\n * @param {!Node} node the node to be downgraded\n */\n var downgradeNode = function(node) {\n createdComponents_.filter(function(item) {\n return item.element_ === node;\n }).forEach(deconstructComponentInternal);\n };\n if (nodes instanceof Array || nodes instanceof NodeList) {\n for (var n = 0; n < nodes.length; n++) {\n downgradeNode(nodes[n]);\n }\n } else if (nodes instanceof Node) {\n downgradeNode(nodes);\n } else {\n throw new Error('Invalid argument provided to downgrade MDL nodes.');\n }\n }\n\n // Now return the functions that should be made public with their publicly\n // facing names...\n return {\n upgradeDom: upgradeDomInternal,\n upgradeElement: upgradeElementInternal,\n upgradeElements: upgradeElementsInternal,\n upgradeAllRegistered: upgradeAllRegisteredInternal,\n registerUpgradedCallback: registerUpgradedCallbackInternal,\n register: registerInternal,\n downgradeElements: downgradeNodesInternal\n };\n})();\n\n/**\n * Describes the type of a registered component type managed by\n * componentHandler. Provided for benefit of the Closure compiler.\n *\n * @typedef {{\n * constructor: Function,\n * classAsString: string,\n * cssClass: string,\n * widget: (string|boolean|undefined)\n * }}\n */\ncomponentHandler.ComponentConfigPublic; // jshint ignore:line\n\n/**\n * Describes the type of a registered component type managed by\n * componentHandler. Provided for benefit of the Closure compiler.\n *\n * @typedef {{\n * constructor: !Function,\n * className: string,\n * cssClass: string,\n * widget: (string|boolean),\n * callbacks: !Array<function(!HTMLElement)>\n * }}\n */\ncomponentHandler.ComponentConfig; // jshint ignore:line\n\n/**\n * Created component (i.e., upgraded element) type as managed by\n * componentHandler. Provided for benefit of the Closure compiler.\n *\n * @typedef {{\n * element_: !HTMLElement,\n * className: string,\n * classAsString: string,\n * cssClass: string,\n * widget: string\n * }}\n */\ncomponentHandler.Component; // jshint ignore:line\n\n// Export all symbols, for the benefit of Closure compiler.\n// No effect on uncompiled code.\ncomponentHandler['upgradeDom'] = componentHandler.upgradeDom;\ncomponentHandler['upgradeElement'] = componentHandler.upgradeElement;\ncomponentHandler['upgradeElements'] = componentHandler.upgradeElements;\ncomponentHandler['upgradeAllRegistered'] =\n componentHandler.upgradeAllRegistered;\ncomponentHandler['registerUpgradedCallback'] =\n componentHandler.registerUpgradedCallback;\ncomponentHandler['register'] = componentHandler.register;\ncomponentHandler['downgradeElements'] = componentHandler.downgradeElements;\nwindow.componentHandler = componentHandler;\nwindow['componentHandler'] = componentHandler;\n\nwindow.addEventListener('load', function() {\n 'use strict';\n\n /**\n * Performs a \"Cutting the mustard\" test. If the browser supports the features\n * tested, adds a mdl-js class to the <html> element. It then upgrades all MDL\n * components requiring JavaScript.\n */\n if ('classList' in document.createElement('div') &&\n 'querySelector' in document &&\n 'addEventListener' in window && Array.prototype.forEach) {\n document.documentElement.classList.add('mdl-js');\n componentHandler.upgradeAllRegistered();\n } else {\n /**\n * Dummy function to avoid JS errors.\n */\n componentHandler.upgradeElement = function() {};\n /**\n * Dummy function to avoid JS errors.\n */\n componentHandler.register = function() {};\n }\n});\n","// Source: https://github.com/darius/requestAnimationFrame/blob/master/requestAnimationFrame.js\n// Adapted from https://gist.github.com/paulirish/1579671 which derived from\n// http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating\n// requestAnimationFrame polyfill by Erik Mรถller.\n// Fixes from Paul Irish, Tino Zijdel, Andrew Mao, Klemen Slaviฤ, Darius Bacon\n// MIT license\nif (!Date.now) {\n /**\n * Date.now polyfill.\n * @return {number} the current Date\n */\n Date.now = function () {\n return new Date().getTime();\n };\n Date['now'] = Date.now;\n}\nvar vendors = [\n 'webkit',\n 'moz'\n];\nfor (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {\n var vp = vendors[i];\n window.requestAnimationFrame = window[vp + 'RequestAnimationFrame'];\n window.cancelAnimationFrame = window[vp + 'CancelAnimationFrame'] || window[vp + 'CancelRequestAnimationFrame'];\n window['requestAnimationFrame'] = window.requestAnimationFrame;\n window['cancelAnimationFrame'] = window.cancelAnimationFrame;\n}\nif (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame) {\n var lastTime = 0;\n /**\n * requestAnimationFrame polyfill.\n * @param {!Function} callback the callback function.\n */\n window.requestAnimationFrame = function (callback) {\n var now = Date.now();\n var nextTime = Math.max(lastTime + 16, now);\n return setTimeout(function () {\n callback(lastTime = nextTime);\n }, nextTime - now);\n };\n window.cancelAnimationFrame = clearTimeout;\n window['requestAnimationFrame'] = window.requestAnimationFrame;\n window['cancelAnimationFrame'] = window.cancelAnimationFrame;\n}","/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Button MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialButton = function MaterialButton(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialButton'] = MaterialButton;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialButton.prototype.Constant_ = {};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialButton.prototype.CssClasses_ = {\n RIPPLE_EFFECT: 'mdl-js-ripple-effect',\n RIPPLE_CONTAINER: 'mdl-button__ripple-container',\n RIPPLE: 'mdl-ripple'\n};\n/**\n * Handle blur of element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialButton.prototype.blurHandler_ = function (event) {\n if (event) {\n this.element_.blur();\n }\n};\n// Public methods.\n/**\n * Disable button.\n *\n * @public\n */\nMaterialButton.prototype.disable = function () {\n this.element_.disabled = true;\n};\nMaterialButton.prototype['disable'] = MaterialButton.prototype.disable;\n/**\n * Enable button.\n *\n * @public\n */\nMaterialButton.prototype.enable = function () {\n this.element_.disabled = false;\n};\nMaterialButton.prototype['enable'] = MaterialButton.prototype.enable;\n/**\n * Initialize element.\n */\nMaterialButton.prototype.init = function () {\n if (this.element_) {\n if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {\n var rippleContainer = document.createElement('span');\n rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER);\n this.rippleElement_ = document.createElement('span');\n this.rippleElement_.classList.add(this.CssClasses_.RIPPLE);\n rippleContainer.appendChild(this.rippleElement_);\n this.boundRippleBlurHandler = this.blurHandler_.bind(this);\n this.rippleElement_.addEventListener('mouseup', this.boundRippleBlurHandler);\n this.element_.appendChild(rippleContainer);\n }\n this.boundButtonBlurHandler = this.blurHandler_.bind(this);\n this.element_.addEventListener('mouseup', this.boundButtonBlurHandler);\n this.element_.addEventListener('mouseleave', this.boundButtonBlurHandler);\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialButton,\n classAsString: 'MaterialButton',\n cssClass: 'mdl-js-button',\n widget: true\n});","/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Checkbox MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialCheckbox = function MaterialCheckbox(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialCheckbox'] = MaterialCheckbox;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialCheckbox.prototype.Constant_ = { TINY_TIMEOUT: 0.001 };\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialCheckbox.prototype.CssClasses_ = {\n INPUT: 'mdl-checkbox__input',\n BOX_OUTLINE: 'mdl-checkbox__box-outline',\n FOCUS_HELPER: 'mdl-checkbox__focus-helper',\n TICK_OUTLINE: 'mdl-checkbox__tick-outline',\n RIPPLE_EFFECT: 'mdl-js-ripple-effect',\n RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',\n RIPPLE_CONTAINER: 'mdl-checkbox__ripple-container',\n RIPPLE_CENTER: 'mdl-ripple--center',\n RIPPLE: 'mdl-ripple',\n IS_FOCUSED: 'is-focused',\n IS_DISABLED: 'is-disabled',\n IS_CHECKED: 'is-checked',\n IS_UPGRADED: 'is-upgraded'\n};\n/**\n * Handle change of state.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialCheckbox.prototype.onChange_ = function (event) {\n this.updateClasses_();\n};\n/**\n * Handle focus of element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialCheckbox.prototype.onFocus_ = function (event) {\n this.element_.classList.add(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle lost focus of element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialCheckbox.prototype.onBlur_ = function (event) {\n this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle mouseup.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialCheckbox.prototype.onMouseUp_ = function (event) {\n this.blur_();\n};\n/**\n * Handle class updates.\n *\n * @private\n */\nMaterialCheckbox.prototype.updateClasses_ = function () {\n this.checkDisabled();\n this.checkToggleState();\n};\n/**\n * Add blur.\n *\n * @private\n */\nMaterialCheckbox.prototype.blur_ = function () {\n // TODO: figure out why there's a focus event being fired after our blur,\n // so that we can avoid this hack.\n window.setTimeout(function () {\n this.inputElement_.blur();\n }.bind(this), this.Constant_.TINY_TIMEOUT);\n};\n// Public methods.\n/**\n * Check the inputs toggle state and update display.\n *\n * @public\n */\nMaterialCheckbox.prototype.checkToggleState = function () {\n if (this.inputElement_.checked) {\n this.element_.classList.add(this.CssClasses_.IS_CHECKED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_CHECKED);\n }\n};\nMaterialCheckbox.prototype['checkToggleState'] = MaterialCheckbox.prototype.checkToggleState;\n/**\n * Check the inputs disabled state and update display.\n *\n * @public\n */\nMaterialCheckbox.prototype.checkDisabled = function () {\n if (this.inputElement_.disabled) {\n this.element_.classList.add(this.CssClasses_.IS_DISABLED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_DISABLED);\n }\n};\nMaterialCheckbox.prototype['checkDisabled'] = MaterialCheckbox.prototype.checkDisabled;\n/**\n * Disable checkbox.\n *\n * @public\n */\nMaterialCheckbox.prototype.disable = function () {\n this.inputElement_.disabled = true;\n this.updateClasses_();\n};\nMaterialCheckbox.prototype['disable'] = MaterialCheckbox.prototype.disable;\n/**\n * Enable checkbox.\n *\n * @public\n */\nMaterialCheckbox.prototype.enable = function () {\n this.inputElement_.disabled = false;\n this.updateClasses_();\n};\nMaterialCheckbox.prototype['enable'] = MaterialCheckbox.prototype.enable;\n/**\n * Check checkbox.\n *\n * @public\n */\nMaterialCheckbox.prototype.check = function () {\n this.inputElement_.checked = true;\n this.updateClasses_();\n};\nMaterialCheckbox.prototype['check'] = MaterialCheckbox.prototype.check;\n/**\n * Uncheck checkbox.\n *\n * @public\n */\nMaterialCheckbox.prototype.uncheck = function () {\n this.inputElement_.checked = false;\n this.updateClasses_();\n};\nMaterialCheckbox.prototype['uncheck'] = MaterialCheckbox.prototype.uncheck;\n/**\n * Initialize element.\n */\nMaterialCheckbox.prototype.init = function () {\n if (this.element_) {\n this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);\n var boxOutline = document.createElement('span');\n boxOutline.classList.add(this.CssClasses_.BOX_OUTLINE);\n var tickContainer = document.createElement('span');\n tickContainer.classList.add(this.CssClasses_.FOCUS_HELPER);\n var tickOutline = document.createElement('span');\n tickOutline.classList.add(this.CssClasses_.TICK_OUTLINE);\n boxOutline.appendChild(tickOutline);\n this.element_.appendChild(tickContainer);\n this.element_.appendChild(boxOutline);\n if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {\n this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);\n this.rippleContainerElement_ = document.createElement('span');\n this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);\n this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT);\n this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);\n this.boundRippleMouseUp = this.onMouseUp_.bind(this);\n this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp);\n var ripple = document.createElement('span');\n ripple.classList.add(this.CssClasses_.RIPPLE);\n this.rippleContainerElement_.appendChild(ripple);\n this.element_.appendChild(this.rippleContainerElement_);\n }\n this.boundInputOnChange = this.onChange_.bind(this);\n this.boundInputOnFocus = this.onFocus_.bind(this);\n this.boundInputOnBlur = this.onBlur_.bind(this);\n this.boundElementMouseUp = this.onMouseUp_.bind(this);\n this.inputElement_.addEventListener('change', this.boundInputOnChange);\n this.inputElement_.addEventListener('focus', this.boundInputOnFocus);\n this.inputElement_.addEventListener('blur', this.boundInputOnBlur);\n this.element_.addEventListener('mouseup', this.boundElementMouseUp);\n this.updateClasses_();\n this.element_.classList.add(this.CssClasses_.IS_UPGRADED);\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialCheckbox,\n classAsString: 'MaterialCheckbox',\n cssClass: 'mdl-js-checkbox',\n widget: true\n});","/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for icon toggle MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialIconToggle = function MaterialIconToggle(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialIconToggle'] = MaterialIconToggle;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialIconToggle.prototype.Constant_ = { TINY_TIMEOUT: 0.001 };\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialIconToggle.prototype.CssClasses_ = {\n INPUT: 'mdl-icon-toggle__input',\n JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',\n RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',\n RIPPLE_CONTAINER: 'mdl-icon-toggle__ripple-container',\n RIPPLE_CENTER: 'mdl-ripple--center',\n RIPPLE: 'mdl-ripple',\n IS_FOCUSED: 'is-focused',\n IS_DISABLED: 'is-disabled',\n IS_CHECKED: 'is-checked'\n};\n/**\n * Handle change of state.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialIconToggle.prototype.onChange_ = function (event) {\n this.updateClasses_();\n};\n/**\n * Handle focus of element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialIconToggle.prototype.onFocus_ = function (event) {\n this.element_.classList.add(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle lost focus of element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialIconToggle.prototype.onBlur_ = function (event) {\n this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle mouseup.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialIconToggle.prototype.onMouseUp_ = function (event) {\n this.blur_();\n};\n/**\n * Handle class updates.\n *\n * @private\n */\nMaterialIconToggle.prototype.updateClasses_ = function () {\n this.checkDisabled();\n this.checkToggleState();\n};\n/**\n * Add blur.\n *\n * @private\n */\nMaterialIconToggle.prototype.blur_ = function () {\n // TODO: figure out why there's a focus event being fired after our blur,\n // so that we can avoid this hack.\n window.setTimeout(function () {\n this.inputElement_.blur();\n }.bind(this), this.Constant_.TINY_TIMEOUT);\n};\n// Public methods.\n/**\n * Check the inputs toggle state and update display.\n *\n * @public\n */\nMaterialIconToggle.prototype.checkToggleState = function () {\n if (this.inputElement_.checked) {\n this.element_.classList.add(this.CssClasses_.IS_CHECKED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_CHECKED);\n }\n};\nMaterialIconToggle.prototype['checkToggleState'] = MaterialIconToggle.prototype.checkToggleState;\n/**\n * Check the inputs disabled state and update display.\n *\n * @public\n */\nMaterialIconToggle.prototype.checkDisabled = function () {\n if (this.inputElement_.disabled) {\n this.element_.classList.add(this.CssClasses_.IS_DISABLED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_DISABLED);\n }\n};\nMaterialIconToggle.prototype['checkDisabled'] = MaterialIconToggle.prototype.checkDisabled;\n/**\n * Disable icon toggle.\n *\n * @public\n */\nMaterialIconToggle.prototype.disable = function () {\n this.inputElement_.disabled = true;\n this.updateClasses_();\n};\nMaterialIconToggle.prototype['disable'] = MaterialIconToggle.prototype.disable;\n/**\n * Enable icon toggle.\n *\n * @public\n */\nMaterialIconToggle.prototype.enable = function () {\n this.inputElement_.disabled = false;\n this.updateClasses_();\n};\nMaterialIconToggle.prototype['enable'] = MaterialIconToggle.prototype.enable;\n/**\n * Check icon toggle.\n *\n * @public\n */\nMaterialIconToggle.prototype.check = function () {\n this.inputElement_.checked = true;\n this.updateClasses_();\n};\nMaterialIconToggle.prototype['check'] = MaterialIconToggle.prototype.check;\n/**\n * Uncheck icon toggle.\n *\n * @public\n */\nMaterialIconToggle.prototype.uncheck = function () {\n this.inputElement_.checked = false;\n this.updateClasses_();\n};\nMaterialIconToggle.prototype['uncheck'] = MaterialIconToggle.prototype.uncheck;\n/**\n * Initialize element.\n */\nMaterialIconToggle.prototype.init = function () {\n if (this.element_) {\n this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);\n if (this.element_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) {\n this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);\n this.rippleContainerElement_ = document.createElement('span');\n this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);\n this.rippleContainerElement_.classList.add(this.CssClasses_.JS_RIPPLE_EFFECT);\n this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);\n this.boundRippleMouseUp = this.onMouseUp_.bind(this);\n this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp);\n var ripple = document.createElement('span');\n ripple.classList.add(this.CssClasses_.RIPPLE);\n this.rippleContainerElement_.appendChild(ripple);\n this.element_.appendChild(this.rippleContainerElement_);\n }\n this.boundInputOnChange = this.onChange_.bind(this);\n this.boundInputOnFocus = this.onFocus_.bind(this);\n this.boundInputOnBlur = this.onBlur_.bind(this);\n this.boundElementOnMouseUp = this.onMouseUp_.bind(this);\n this.inputElement_.addEventListener('change', this.boundInputOnChange);\n this.inputElement_.addEventListener('focus', this.boundInputOnFocus);\n this.inputElement_.addEventListener('blur', this.boundInputOnBlur);\n this.element_.addEventListener('mouseup', this.boundElementOnMouseUp);\n this.updateClasses_();\n this.element_.classList.add('is-upgraded');\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialIconToggle,\n classAsString: 'MaterialIconToggle',\n cssClass: 'mdl-js-icon-toggle',\n widget: true\n});","/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for dropdown MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialMenu = function MaterialMenu(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialMenu'] = MaterialMenu;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialMenu.prototype.Constant_ = {\n // Total duration of the menu animation.\n TRANSITION_DURATION_SECONDS: 0.3,\n // The fraction of the total duration we want to use for menu item animations.\n TRANSITION_DURATION_FRACTION: 0.8,\n // How long the menu stays open after choosing an option (so the user can see\n // the ripple).\n CLOSE_TIMEOUT: 150\n};\n/**\n * Keycodes, for code readability.\n *\n * @enum {number}\n * @private\n */\nMaterialMenu.prototype.Keycodes_ = {\n ENTER: 13,\n ESCAPE: 27,\n SPACE: 32,\n UP_ARROW: 38,\n DOWN_ARROW: 40\n};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialMenu.prototype.CssClasses_ = {\n CONTAINER: 'mdl-menu__container',\n OUTLINE: 'mdl-menu__outline',\n ITEM: 'mdl-menu__item',\n ITEM_RIPPLE_CONTAINER: 'mdl-menu__item-ripple-container',\n RIPPLE_EFFECT: 'mdl-js-ripple-effect',\n RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',\n RIPPLE: 'mdl-ripple',\n // Statuses\n IS_UPGRADED: 'is-upgraded',\n IS_VISIBLE: 'is-visible',\n IS_ANIMATING: 'is-animating',\n // Alignment options\n BOTTOM_LEFT: 'mdl-menu--bottom-left',\n // This is the default.\n BOTTOM_RIGHT: 'mdl-menu--bottom-right',\n TOP_LEFT: 'mdl-menu--top-left',\n TOP_RIGHT: 'mdl-menu--top-right',\n UNALIGNED: 'mdl-menu--unaligned'\n};\n/**\n * Initialize element.\n */\nMaterialMenu.prototype.init = function () {\n if (this.element_) {\n // Create container for the menu.\n var container = document.createElement('div');\n container.classList.add(this.CssClasses_.CONTAINER);\n this.element_.parentElement.insertBefore(container, this.element_);\n this.element_.parentElement.removeChild(this.element_);\n container.appendChild(this.element_);\n this.container_ = container;\n // Create outline for the menu (shadow and background).\n var outline = document.createElement('div');\n outline.classList.add(this.CssClasses_.OUTLINE);\n this.outline_ = outline;\n container.insertBefore(outline, this.element_);\n // Find the \"for\" element and bind events to it.\n var forElId = this.element_.getAttribute('for') || this.element_.getAttribute('data-mdl-for');\n var forEl = null;\n if (forElId) {\n forEl = document.getElementById(forElId);\n if (forEl) {\n this.forElement_ = forEl;\n forEl.addEventListener('click', this.handleForClick_.bind(this));\n forEl.addEventListener('keydown', this.handleForKeyboardEvent_.bind(this));\n }\n }\n var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM);\n this.boundItemKeydown_ = this.handleItemKeyboardEvent_.bind(this);\n this.boundItemClick_ = this.handleItemClick_.bind(this);\n for (var i = 0; i < items.length; i++) {\n // Add a listener to each menu item.\n items[i].addEventListener('click', this.boundItemClick_);\n // Add a tab index to each menu item.\n items[i].tabIndex = '-1';\n // Add a keyboard listener to each menu item.\n items[i].addEventListener('keydown', this.boundItemKeydown_);\n }\n // Add ripple classes to each item, if the user has enabled ripples.\n if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {\n this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);\n for (i = 0; i < items.length; i++) {\n var item = items[i];\n var rippleContainer = document.createElement('span');\n rippleContainer.classList.add(this.CssClasses_.ITEM_RIPPLE_CONTAINER);\n var ripple = document.createElement('span');\n ripple.classList.add(this.CssClasses_.RIPPLE);\n rippleContainer.appendChild(ripple);\n item.appendChild(rippleContainer);\n item.classList.add(this.CssClasses_.RIPPLE_EFFECT);\n }\n }\n // Copy alignment classes to the container, so the outline can use them.\n if (this.element_.classList.contains(this.CssClasses_.BOTTOM_LEFT)) {\n this.outline_.classList.add(this.CssClasses_.BOTTOM_LEFT);\n }\n if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) {\n this.outline_.classList.add(this.CssClasses_.BOTTOM_RIGHT);\n }\n if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) {\n this.outline_.classList.add(this.CssClasses_.TOP_LEFT);\n }\n if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {\n this.outline_.classList.add(this.CssClasses_.TOP_RIGHT);\n }\n if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) {\n this.outline_.classList.add(this.CssClasses_.UNALIGNED);\n }\n container.classList.add(this.CssClasses_.IS_UPGRADED);\n }\n};\n/**\n * Handles a click on the \"for\" element, by positioning the menu and then\n * toggling it.\n *\n * @param {Event} evt The event that fired.\n * @private\n */\nMaterialMenu.prototype.handleForClick_ = function (evt) {\n if (this.element_ && this.forElement_) {\n var rect = this.forElement_.getBoundingClientRect();\n var forRect = this.forElement_.parentElement.getBoundingClientRect();\n if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) {\n } else if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) {\n // Position below the \"for\" element, aligned to its right.\n this.container_.style.right = forRect.right - rect.right + 'px';\n this.container_.style.top = this.forElement_.offsetTop + this.forElement_.offsetHeight + 'px';\n } else if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) {\n // Position above the \"for\" element, aligned to its left.\n this.container_.style.left = this.forElement_.offsetLeft + 'px';\n this.container_.style.bottom = forRect.bottom - rect.top + 'px';\n } else if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {\n // Position above the \"for\" element, aligned to its right.\n this.container_.style.right = forRect.right - rect.right + 'px';\n this.container_.style.bottom = forRect.bottom - rect.top + 'px';\n } else {\n // Default: position below the \"for\" element, aligned to its left.\n this.container_.style.left = this.forElement_.offsetLeft + 'px';\n this.container_.style.top = this.forElement_.offsetTop + this.forElement_.offsetHeight + 'px';\n }\n }\n this.toggle(evt);\n};\n/**\n * Handles a keyboard event on the \"for\" element.\n *\n * @param {Event} evt The event that fired.\n * @private\n */\nMaterialMenu.prototype.handleForKeyboardEvent_ = function (evt) {\n if (this.element_ && this.container_ && this.forElement_) {\n var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM + ':not([disabled])');\n if (items && items.length > 0 && this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) {\n if (evt.keyCode === this.Keycodes_.UP_ARROW) {\n evt.preventDefault();\n items[items.length - 1].focus();\n } else if (evt.keyCode === this.Keycodes_.DOWN_ARROW) {\n evt.preventDefault();\n items[0].focus();\n }\n }\n }\n};\n/**\n * Handles a keyboard event on an item.\n *\n * @param {Event} evt The event that fired.\n * @private\n */\nMaterialMenu.prototype.handleItemKeyboardEvent_ = function (evt) {\n if (this.element_ && this.container_) {\n var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM + ':not([disabled])');\n if (items && items.length > 0 && this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) {\n var currentIndex = Array.prototype.slice.call(items).indexOf(evt.target);\n if (evt.keyCode === this.Keycodes_.UP_ARROW) {\n evt.preventDefault();\n if (currentIndex > 0) {\n items[currentIndex - 1].focus();\n } else {\n items[items.length - 1].focus();\n }\n } else if (evt.keyCode === this.Keycodes_.DOWN_ARROW) {\n evt.preventDefault();\n if (items.length > currentIndex + 1) {\n items[currentIndex + 1].focus();\n } else {\n items[0].focus();\n }\n } else if (evt.keyCode === this.Keycodes_.SPACE || evt.keyCode === this.Keycodes_.ENTER) {\n evt.preventDefault();\n // Send mousedown and mouseup to trigger ripple.\n var e = new MouseEvent('mousedown');\n evt.target.dispatchEvent(e);\n e = new MouseEvent('mouseup');\n evt.target.dispatchEvent(e);\n // Send click.\n evt.target.click();\n } else if (evt.keyCode === this.Keycodes_.ESCAPE) {\n evt.preventDefault();\n this.hide();\n }\n }\n }\n};\n/**\n * Handles a click event on an item.\n *\n * @param {Event} evt The event that fired.\n * @private\n */\nMaterialMenu.prototype.handleItemClick_ = function (evt) {\n if (evt.target.hasAttribute('disabled')) {\n evt.stopPropagation();\n } else {\n // Wait some time before closing menu, so the user can see the ripple.\n this.closing_ = true;\n window.setTimeout(function (evt) {\n this.hide();\n this.closing_ = false;\n }.bind(this), this.Constant_.CLOSE_TIMEOUT);\n }\n};\n/**\n * Calculates the initial clip (for opening the menu) or final clip (for closing\n * it), and applies it. This allows us to animate from or to the correct point,\n * that is, the point it's aligned to in the \"for\" element.\n *\n * @param {number} height Height of the clip rectangle\n * @param {number} width Width of the clip rectangle\n * @private\n */\nMaterialMenu.prototype.applyClip_ = function (height, width) {\n if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) {\n // Do not clip.\n this.element_.style.clip = '';\n } else if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) {\n // Clip to the top right corner of the menu.\n this.element_.style.clip = 'rect(0 ' + width + 'px ' + '0 ' + width + 'px)';\n } else if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) {\n // Clip to the bottom left corner of the menu.\n this.element_.style.clip = 'rect(' + height + 'px 0 ' + height + 'px 0)';\n } else if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {\n // Clip to the bottom right corner of the menu.\n this.element_.style.clip = 'rect(' + height + 'px ' + width + 'px ' + height + 'px ' + width + 'px)';\n } else {\n // Default: do not clip (same as clipping to the top left corner).\n this.element_.style.clip = '';\n }\n};\n/**\n * Cleanup function to remove animation listeners.\n *\n * @param {Event} evt\n * @private\n */\nMaterialMenu.prototype.removeAnimationEndListener_ = function (evt) {\n evt.target.classList.remove(MaterialMenu.prototype.CssClasses_.IS_ANIMATING);\n};\n/**\n * Adds an event listener to clean up after the animation ends.\n *\n * @private\n */\nMaterialMenu.prototype.addAnimationEndListener_ = function () {\n this.element_.addEventListener('transitionend', this.removeAnimationEndListener_);\n this.element_.addEventListener('webkitTransitionEnd', this.removeAnimationEndListener_);\n};\n/**\n * Displays the menu.\n *\n * @public\n */\nMaterialMenu.prototype.show = function (evt) {\n if (this.element_ && this.container_ && this.outline_) {\n // Measure the inner element.\n var height = this.element_.getBoundingClientRect().height;\n var width = this.element_.getBoundingClientRect().width;\n // Apply the inner element's size to the container and outline.\n this.container_.style.width = width + 'px';\n this.container_.style.height = height + 'px';\n this.outline_.style.width = width + 'px';\n this.outline_.style.height = height + 'px';\n var transitionDuration = this.Constant_.TRANSITION_DURATION_SECONDS * this.Constant_.TRANSITION_DURATION_FRACTION;\n // Calculate transition delays for individual menu items, so that they fade\n // in one at a time.\n var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM);\n for (var i = 0; i < items.length; i++) {\n var itemDelay = null;\n if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT) || this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {\n itemDelay = (height - items[i].offsetTop - items[i].offsetHeight) / height * transitionDuration + 's';\n } else {\n itemDelay = items[i].offsetTop / height * transitionDuration + 's';\n }\n items[i].style.transitionDelay = itemDelay;\n }\n // Apply the initial clip to the text before we start animating.\n this.applyClip_(height, width);\n // Wait for the next frame, turn on animation, and apply the final clip.\n // Also make it visible. This triggers the transitions.\n window.requestAnimationFrame(function () {\n this.element_.classList.add(this.CssClasses_.IS_ANIMATING);\n this.element_.style.clip = 'rect(0 ' + width + 'px ' + height + 'px 0)';\n this.container_.classList.add(this.CssClasses_.IS_VISIBLE);\n }.bind(this));\n // Clean up after the animation is complete.\n this.addAnimationEndListener_();\n // Add a click listener to the document, to close the menu.\n var callback = function (e) {\n // Check to see if the document is processing the same event that\n // displayed the menu in the first place. If so, do nothing.\n // Also check to see if the menu is in the process of closing itself, and\n // do nothing in that case.\n // Also check if the clicked element is a menu item\n // if so, do nothing.\n if (e !== evt && !this.closing_ && e.target.parentNode !== this.element_) {\n document.removeEventListener('click', callback);\n this.hide();\n }\n }.bind(this);\n document.addEventListener('click', callback);\n }\n};\nMaterialMenu.prototype['show'] = MaterialMenu.prototype.show;\n/**\n * Hides the menu.\n *\n * @public\n */\nMaterialMenu.prototype.hide = function () {\n if (this.element_ && this.container_ && this.outline_) {\n var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM);\n // Remove all transition delays; menu items fade out concurrently.\n for (var i = 0; i < items.length; i++) {\n items[i].style.removeProperty('transition-delay');\n }\n // Measure the inner element.\n var rect = this.element_.getBoundingClientRect();\n var height = rect.height;\n var width = rect.width;\n // Turn on animation, and apply the final clip. Also make invisible.\n // This triggers the transitions.\n this.element_.classList.add(this.CssClasses_.IS_ANIMATING);\n this.applyClip_(height, width);\n this.container_.classList.remove(this.CssClasses_.IS_VISIBLE);\n // Clean up after the animation is complete.\n this.addAnimationEndListener_();\n }\n};\nMaterialMenu.prototype['hide'] = MaterialMenu.prototype.hide;\n/**\n * Displays or hides the menu, depending on current state.\n *\n * @public\n */\nMaterialMenu.prototype.toggle = function (evt) {\n if (this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) {\n this.hide();\n } else {\n this.show(evt);\n }\n};\nMaterialMenu.prototype['toggle'] = MaterialMenu.prototype.toggle;\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialMenu,\n classAsString: 'MaterialMenu',\n cssClass: 'mdl-js-menu',\n widget: true\n});","/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Progress MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialProgress = function MaterialProgress(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialProgress'] = MaterialProgress;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialProgress.prototype.Constant_ = {};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialProgress.prototype.CssClasses_ = { INDETERMINATE_CLASS: 'mdl-progress__indeterminate' };\n/**\n * Set the current progress of the progressbar.\n *\n * @param {number} p Percentage of the progress (0-100)\n * @public\n */\nMaterialProgress.prototype.setProgress = function (p) {\n if (this.element_.classList.contains(this.CssClasses_.INDETERMINATE_CLASS)) {\n return;\n }\n this.progressbar_.style.width = p + '%';\n};\nMaterialProgress.prototype['setProgress'] = MaterialProgress.prototype.setProgress;\n/**\n * Set the current progress of the buffer.\n *\n * @param {number} p Percentage of the buffer (0-100)\n * @public\n */\nMaterialProgress.prototype.setBuffer = function (p) {\n this.bufferbar_.style.width = p + '%';\n this.auxbar_.style.width = 100 - p + '%';\n};\nMaterialProgress.prototype['setBuffer'] = MaterialProgress.prototype.setBuffer;\n/**\n * Initialize element.\n */\nMaterialProgress.prototype.init = function () {\n if (this.element_) {\n var el = document.createElement('div');\n el.className = 'progressbar bar bar1';\n this.element_.appendChild(el);\n this.progressbar_ = el;\n el = document.createElement('div');\n el.className = 'bufferbar bar bar2';\n this.element_.appendChild(el);\n this.bufferbar_ = el;\n el = document.createElement('div');\n el.className = 'auxbar bar bar3';\n this.element_.appendChild(el);\n this.auxbar_ = el;\n this.progressbar_.style.width = '0%';\n this.bufferbar_.style.width = '100%';\n this.auxbar_.style.width = '0%';\n this.element_.classList.add('is-upgraded');\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialProgress,\n classAsString: 'MaterialProgress',\n cssClass: 'mdl-js-progress',\n widget: true\n});","/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Radio MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialRadio = function MaterialRadio(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialRadio'] = MaterialRadio;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialRadio.prototype.Constant_ = { TINY_TIMEOUT: 0.001 };\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialRadio.prototype.CssClasses_ = {\n IS_FOCUSED: 'is-focused',\n IS_DISABLED: 'is-disabled',\n IS_CHECKED: 'is-checked',\n IS_UPGRADED: 'is-upgraded',\n JS_RADIO: 'mdl-js-radio',\n RADIO_BTN: 'mdl-radio__button',\n RADIO_OUTER_CIRCLE: 'mdl-radio__outer-circle',\n RADIO_INNER_CIRCLE: 'mdl-radio__inner-circle',\n RIPPLE_EFFECT: 'mdl-js-ripple-effect',\n RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',\n RIPPLE_CONTAINER: 'mdl-radio__ripple-container',\n RIPPLE_CENTER: 'mdl-ripple--center',\n RIPPLE: 'mdl-ripple'\n};\n/**\n * Handle change of state.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialRadio.prototype.onChange_ = function (event) {\n // Since other radio buttons don't get change events, we need to look for\n // them to update their classes.\n var radios = document.getElementsByClassName(this.CssClasses_.JS_RADIO);\n for (var i = 0; i < radios.length; i++) {\n var button = radios[i].querySelector('.' + this.CssClasses_.RADIO_BTN);\n // Different name == different group, so no point updating those.\n if (button.getAttribute('name') === this.btnElement_.getAttribute('name')) {\n if (typeof radios[i]['MaterialRadio'] !== 'undefined') {\n radios[i]['MaterialRadio'].updateClasses_();\n }\n }\n }\n};\n/**\n * Handle focus.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialRadio.prototype.onFocus_ = function (event) {\n this.element_.classList.add(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle lost focus.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialRadio.prototype.onBlur_ = function (event) {\n this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle mouseup.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialRadio.prototype.onMouseup_ = function (event) {\n this.blur_();\n};\n/**\n * Update classes.\n *\n * @private\n */\nMaterialRadio.prototype.updateClasses_ = function () {\n this.checkDisabled();\n this.checkToggleState();\n};\n/**\n * Add blur.\n *\n * @private\n */\nMaterialRadio.prototype.blur_ = function () {\n // TODO: figure out why there's a focus event being fired after our blur,\n // so that we can avoid this hack.\n window.setTimeout(function () {\n this.btnElement_.blur();\n }.bind(this), this.Constant_.TINY_TIMEOUT);\n};\n// Public methods.\n/**\n * Check the components disabled state.\n *\n * @public\n */\nMaterialRadio.prototype.checkDisabled = function () {\n if (this.btnElement_.disabled) {\n this.element_.classList.add(this.CssClasses_.IS_DISABLED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_DISABLED);\n }\n};\nMaterialRadio.prototype['checkDisabled'] = MaterialRadio.prototype.checkDisabled;\n/**\n * Check the components toggled state.\n *\n * @public\n */\nMaterialRadio.prototype.checkToggleState = function () {\n if (this.btnElement_.checked) {\n this.element_.classList.add(this.CssClasses_.IS_CHECKED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_CHECKED);\n }\n};\nMaterialRadio.prototype['checkToggleState'] = MaterialRadio.prototype.checkToggleState;\n/**\n * Disable radio.\n *\n * @public\n */\nMaterialRadio.prototype.disable = function () {\n this.btnElement_.disabled = true;\n this.updateClasses_();\n};\nMaterialRadio.prototype['disable'] = MaterialRadio.prototype.disable;\n/**\n * Enable radio.\n *\n * @public\n */\nMaterialRadio.prototype.enable = function () {\n this.btnElement_.disabled = false;\n this.updateClasses_();\n};\nMaterialRadio.prototype['enable'] = MaterialRadio.prototype.enable;\n/**\n * Check radio.\n *\n * @public\n */\nMaterialRadio.prototype.check = function () {\n this.btnElement_.checked = true;\n this.onChange_(null);\n};\nMaterialRadio.prototype['check'] = MaterialRadio.prototype.check;\n/**\n * Uncheck radio.\n *\n * @public\n */\nMaterialRadio.prototype.uncheck = function () {\n this.btnElement_.checked = false;\n this.onChange_(null);\n};\nMaterialRadio.prototype['uncheck'] = MaterialRadio.prototype.uncheck;\n/**\n * Initialize element.\n */\nMaterialRadio.prototype.init = function () {\n if (this.element_) {\n this.btnElement_ = this.element_.querySelector('.' + this.CssClasses_.RADIO_BTN);\n this.boundChangeHandler_ = this.onChange_.bind(this);\n this.boundFocusHandler_ = this.onChange_.bind(this);\n this.boundBlurHandler_ = this.onBlur_.bind(this);\n this.boundMouseUpHandler_ = this.onMouseup_.bind(this);\n var outerCircle = document.createElement('span');\n outerCircle.classList.add(this.CssClasses_.RADIO_OUTER_CIRCLE);\n var innerCircle = document.createElement('span');\n innerCircle.classList.add(this.CssClasses_.RADIO_INNER_CIRCLE);\n this.element_.appendChild(outerCircle);\n this.element_.appendChild(innerCircle);\n var rippleContainer;\n if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {\n this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);\n rippleContainer = document.createElement('span');\n rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER);\n rippleContainer.classList.add(this.CssClasses_.RIPPLE_EFFECT);\n rippleContainer.classList.add(this.CssClasses_.RIPPLE_CENTER);\n rippleContainer.addEventListener('mouseup', this.boundMouseUpHandler_);\n var ripple = document.createElement('span');\n ripple.classList.add(this.CssClasses_.RIPPLE);\n rippleContainer.appendChild(ripple);\n this.element_.appendChild(rippleContainer);\n }\n this.btnElement_.addEventListener('change', this.boundChangeHandler_);\n this.btnElement_.addEventListener('focus', this.boundFocusHandler_);\n this.btnElement_.addEventListener('blur', this.boundBlurHandler_);\n this.element_.addEventListener('mouseup', this.boundMouseUpHandler_);\n this.updateClasses_();\n this.element_.classList.add(this.CssClasses_.IS_UPGRADED);\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialRadio,\n classAsString: 'MaterialRadio',\n cssClass: 'mdl-js-radio',\n widget: true\n});","/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Slider MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialSlider = function MaterialSlider(element) {\n this.element_ = element;\n // Browser feature detection.\n this.isIE_ = window.navigator.msPointerEnabled;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialSlider'] = MaterialSlider;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialSlider.prototype.Constant_ = {};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialSlider.prototype.CssClasses_ = {\n IE_CONTAINER: 'mdl-slider__ie-container',\n SLIDER_CONTAINER: 'mdl-slider__container',\n BACKGROUND_FLEX: 'mdl-slider__background-flex',\n BACKGROUND_LOWER: 'mdl-slider__background-lower',\n BACKGROUND_UPPER: 'mdl-slider__background-upper',\n IS_LOWEST_VALUE: 'is-lowest-value',\n IS_UPGRADED: 'is-upgraded'\n};\n/**\n * Handle input on element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialSlider.prototype.onInput_ = function (event) {\n this.updateValueStyles_();\n};\n/**\n * Handle change on element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialSlider.prototype.onChange_ = function (event) {\n this.updateValueStyles_();\n};\n/**\n * Handle mouseup on element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialSlider.prototype.onMouseUp_ = function (event) {\n event.target.blur();\n};\n/**\n * Handle mousedown on container element.\n * This handler is purpose is to not require the use to click\n * exactly on the 2px slider element, as FireFox seems to be very\n * strict about this.\n *\n * @param {Event} event The event that fired.\n * @private\n * @suppress {missingProperties}\n */\nMaterialSlider.prototype.onContainerMouseDown_ = function (event) {\n // If this click is not on the parent element (but rather some child)\n // ignore. It may still bubble up.\n if (event.target !== this.element_.parentElement) {\n return;\n }\n // Discard the original event and create a new event that\n // is on the slider element.\n event.preventDefault();\n var newEvent = new MouseEvent('mousedown', {\n target: event.target,\n buttons: event.buttons,\n clientX: event.clientX,\n clientY: this.element_.getBoundingClientRect().y\n });\n this.element_.dispatchEvent(newEvent);\n};\n/**\n * Handle updating of values.\n *\n * @private\n */\nMaterialSlider.prototype.updateValueStyles_ = function () {\n // Calculate and apply percentages to div structure behind slider.\n var fraction = (this.element_.value - this.element_.min) / (this.element_.max - this.element_.min);\n if (fraction === 0) {\n this.element_.classList.add(this.CssClasses_.IS_LOWEST_VALUE);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_LOWEST_VALUE);\n }\n if (!this.isIE_) {\n this.backgroundLower_.style.flex = fraction;\n this.backgroundLower_.style.webkitFlex = fraction;\n this.backgroundUpper_.style.flex = 1 - fraction;\n this.backgroundUpper_.style.webkitFlex = 1 - fraction;\n }\n};\n// Public methods.\n/**\n * Disable slider.\n *\n * @public\n */\nMaterialSlider.prototype.disable = function () {\n this.element_.disabled = true;\n};\nMaterialSlider.prototype['disable'] = MaterialSlider.prototype.disable;\n/**\n * Enable slider.\n *\n * @public\n */\nMaterialSlider.prototype.enable = function () {\n this.element_.disabled = false;\n};\nMaterialSlider.prototype['enable'] = MaterialSlider.prototype.enable;\n/**\n * Update slider value.\n *\n * @param {number} value The value to which to set the control (optional).\n * @public\n */\nMaterialSlider.prototype.change = function (value) {\n if (typeof value !== 'undefined') {\n this.element_.value = value;\n }\n this.updateValueStyles_();\n};\nMaterialSlider.prototype['change'] = MaterialSlider.prototype.change;\n/**\n * Initialize element.\n */\nMaterialSlider.prototype.init = function () {\n if (this.element_) {\n if (this.isIE_) {\n // Since we need to specify a very large height in IE due to\n // implementation limitations, we add a parent here that trims it down to\n // a reasonable size.\n var containerIE = document.createElement('div');\n containerIE.classList.add(this.CssClasses_.IE_CONTAINER);\n this.element_.parentElement.insertBefore(containerIE, this.element_);\n this.element_.parentElement.removeChild(this.element_);\n containerIE.appendChild(this.element_);\n } else {\n // For non-IE browsers, we need a div structure that sits behind the\n // slider and allows us to style the left and right sides of it with\n // different colors.\n var container = document.createElement('div');\n container.classList.add(this.CssClasses_.SLIDER_CONTAINER);\n this.element_.parentElement.insertBefore(container, this.element_);\n this.element_.parentElement.removeChild(this.element_);\n container.appendChild(this.element_);\n var backgroundFlex = document.createElement('div');\n backgroundFlex.classList.add(this.CssClasses_.BACKGROUND_FLEX);\n container.appendChild(backgroundFlex);\n this.backgroundLower_ = document.createElement('div');\n this.backgroundLower_.classList.add(this.CssClasses_.BACKGROUND_LOWER);\n backgroundFlex.appendChild(this.backgroundLower_);\n this.backgroundUpper_ = document.createElement('div');\n this.backgroundUpper_.classList.add(this.CssClasses_.BACKGROUND_UPPER);\n backgroundFlex.appendChild(this.backgroundUpper_);\n }\n this.boundInputHandler = this.onInput_.bind(this);\n this.boundChangeHandler = this.onChange_.bind(this);\n this.boundMouseUpHandler = this.onMouseUp_.bind(this);\n this.boundContainerMouseDownHandler = this.onContainerMouseDown_.bind(this);\n this.element_.addEventListener('input', this.boundInputHandler);\n this.element_.addEventListener('change', this.boundChangeHandler);\n this.element_.addEventListener('mouseup', this.boundMouseUpHandler);\n this.element_.parentElement.addEventListener('mousedown', this.boundContainerMouseDownHandler);\n this.updateValueStyles_();\n this.element_.classList.add(this.CssClasses_.IS_UPGRADED);\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialSlider,\n classAsString: 'MaterialSlider',\n cssClass: 'mdl-js-slider',\n widget: true\n});","/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Snackbar MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialSnackbar = function MaterialSnackbar(element) {\n this.element_ = element;\n this.textElement_ = this.element_.querySelector('.' + this.cssClasses_.MESSAGE);\n this.actionElement_ = this.element_.querySelector('.' + this.cssClasses_.ACTION);\n if (!this.textElement_) {\n throw new Error('There must be a message element for a snackbar.');\n }\n if (!this.actionElement_) {\n throw new Error('There must be an action element for a snackbar.');\n }\n this.active = false;\n this.actionHandler_ = undefined;\n this.message_ = undefined;\n this.actionText_ = undefined;\n this.queuedNotifications_ = [];\n this.setActionHidden_(true);\n};\nwindow['MaterialSnackbar'] = MaterialSnackbar;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialSnackbar.prototype.Constant_ = {\n // The duration of the snackbar show/hide animation, in ms.\n ANIMATION_LENGTH: 250\n};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialSnackbar.prototype.cssClasses_ = {\n SNACKBAR: 'mdl-snackbar',\n MESSAGE: 'mdl-snackbar__text',\n ACTION: 'mdl-snackbar__action',\n ACTIVE: 'mdl-snackbar--active'\n};\n/**\n * Display the snackbar.\n *\n * @private\n */\nMaterialSnackbar.prototype.displaySnackbar_ = function () {\n this.element_.setAttribute('aria-hidden', 'true');\n if (this.actionHandler_) {\n this.actionElement_.textContent = this.actionText_;\n this.actionElement_.addEventListener('click', this.actionHandler_);\n this.setActionHidden_(false);\n }\n this.textElement_.textContent = this.message_;\n this.element_.classList.add(this.cssClasses_.ACTIVE);\n this.element_.setAttribute('aria-hidden', 'false');\n setTimeout(this.cleanup_.bind(this), this.timeout_);\n};\n/**\n * Show the snackbar.\n *\n * @param {Object} data The data for the notification.\n * @public\n */\nMaterialSnackbar.prototype.showSnackbar = function (data) {\n if (data === undefined) {\n throw new Error('Please provide a data object with at least a message to display.');\n }\n if (data['message'] === undefined) {\n throw new Error('Please provide a message to be displayed.');\n }\n if (data['actionHandler'] && !data['actionText']) {\n throw new Error('Please provide action text with the handler.');\n }\n if (this.active) {\n this.queuedNotifications_.push(data);\n } else {\n this.active = true;\n this.message_ = data['message'];\n if (data['timeout']) {\n this.timeout_ = data['timeout'];\n } else {\n this.timeout_ = 2750;\n }\n if (data['actionHandler']) {\n this.actionHandler_ = data['actionHandler'];\n }\n if (data['actionText']) {\n this.actionText_ = data['actionText'];\n }\n this.displaySnackbar_();\n }\n};\nMaterialSnackbar.prototype['showSnackbar'] = MaterialSnackbar.prototype.showSnackbar;\n/**\n * Check if the queue has items within it.\n * If it does, display the next entry.\n *\n * @private\n */\nMaterialSnackbar.prototype.checkQueue_ = function () {\n if (this.queuedNotifications_.length > 0) {\n this.showSnackbar(this.queuedNotifications_.shift());\n }\n};\n/**\n * Cleanup the snackbar event listeners and accessiblity attributes.\n *\n * @private\n */\nMaterialSnackbar.prototype.cleanup_ = function () {\n this.element_.classList.remove(this.cssClasses_.ACTIVE);\n setTimeout(function () {\n this.element_.setAttribute('aria-hidden', 'true');\n this.textElement_.textContent = '';\n if (!Boolean(this.actionElement_.getAttribute('aria-hidden'))) {\n this.setActionHidden_(true);\n this.actionElement_.textContent = '';\n this.actionElement_.removeEventListener('click', this.actionHandler_);\n }\n this.actionHandler_ = undefined;\n this.message_ = undefined;\n this.actionText_ = undefined;\n this.active = false;\n this.checkQueue_();\n }.bind(this), this.Constant_.ANIMATION_LENGTH);\n};\n/**\n * Set the action handler hidden state.\n *\n * @param {boolean} value\n * @private\n */\nMaterialSnackbar.prototype.setActionHidden_ = function (value) {\n if (value) {\n this.actionElement_.setAttribute('aria-hidden', 'true');\n } else {\n this.actionElement_.removeAttribute('aria-hidden');\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialSnackbar,\n classAsString: 'MaterialSnackbar',\n cssClass: 'mdl-js-snackbar',\n widget: true\n});","/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Spinner MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @param {HTMLElement} element The element that will be upgraded.\n * @constructor\n */\nvar MaterialSpinner = function MaterialSpinner(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialSpinner'] = MaterialSpinner;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialSpinner.prototype.Constant_ = { MDL_SPINNER_LAYER_COUNT: 4 };\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialSpinner.prototype.CssClasses_ = {\n MDL_SPINNER_LAYER: 'mdl-spinner__layer',\n MDL_SPINNER_CIRCLE_CLIPPER: 'mdl-spinner__circle-clipper',\n MDL_SPINNER_CIRCLE: 'mdl-spinner__circle',\n MDL_SPINNER_GAP_PATCH: 'mdl-spinner__gap-patch',\n MDL_SPINNER_LEFT: 'mdl-spinner__left',\n MDL_SPINNER_RIGHT: 'mdl-spinner__right'\n};\n/**\n * Auxiliary method to create a spinner layer.\n *\n * @param {number} index Index of the layer to be created.\n * @public\n */\nMaterialSpinner.prototype.createLayer = function (index) {\n var layer = document.createElement('div');\n layer.classList.add(this.CssClasses_.MDL_SPINNER_LAYER);\n layer.classList.add(this.CssClasses_.MDL_SPINNER_LAYER + '-' + index);\n var leftClipper = document.createElement('div');\n leftClipper.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER);\n leftClipper.classList.add(this.CssClasses_.MDL_SPINNER_LEFT);\n var gapPatch = document.createElement('div');\n gapPatch.classList.add(this.CssClasses_.MDL_SPINNER_GAP_PATCH);\n var rightClipper = document.createElement('div');\n rightClipper.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER);\n rightClipper.classList.add(this.CssClasses_.MDL_SPINNER_RIGHT);\n var circleOwners = [\n leftClipper,\n gapPatch,\n rightClipper\n ];\n for (var i = 0; i < circleOwners.length; i++) {\n var circle = document.createElement('div');\n circle.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE);\n circleOwners[i].appendChild(circle);\n }\n layer.appendChild(leftClipper);\n layer.appendChild(gapPatch);\n layer.appendChild(rightClipper);\n this.element_.appendChild(layer);\n};\nMaterialSpinner.prototype['createLayer'] = MaterialSpinner.prototype.createLayer;\n/**\n * Stops the spinner animation.\n * Public method for users who need to stop the spinner for any reason.\n *\n * @public\n */\nMaterialSpinner.prototype.stop = function () {\n this.element_.classList.remove('is-active');\n};\nMaterialSpinner.prototype['stop'] = MaterialSpinner.prototype.stop;\n/**\n * Starts the spinner animation.\n * Public method for users who need to manually start the spinner for any reason\n * (instead of just adding the 'is-active' class to their markup).\n *\n * @public\n */\nMaterialSpinner.prototype.start = function () {\n this.element_.classList.add('is-active');\n};\nMaterialSpinner.prototype['start'] = MaterialSpinner.prototype.start;\n/**\n * Initialize element.\n */\nMaterialSpinner.prototype.init = function () {\n if (this.element_) {\n for (var i = 1; i <= this.Constant_.MDL_SPINNER_LAYER_COUNT; i++) {\n this.createLayer(i);\n }\n this.element_.classList.add('is-upgraded');\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialSpinner,\n classAsString: 'MaterialSpinner',\n cssClass: 'mdl-js-spinner',\n widget: true\n});","/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Checkbox MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialSwitch = function MaterialSwitch(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialSwitch'] = MaterialSwitch;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialSwitch.prototype.Constant_ = { TINY_TIMEOUT: 0.001 };\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialSwitch.prototype.CssClasses_ = {\n INPUT: 'mdl-switch__input',\n TRACK: 'mdl-switch__track',\n THUMB: 'mdl-switch__thumb',\n FOCUS_HELPER: 'mdl-switch__focus-helper',\n RIPPLE_EFFECT: 'mdl-js-ripple-effect',\n RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',\n RIPPLE_CONTAINER: 'mdl-switch__ripple-container',\n RIPPLE_CENTER: 'mdl-ripple--center',\n RIPPLE: 'mdl-ripple',\n IS_FOCUSED: 'is-focused',\n IS_DISABLED: 'is-disabled',\n IS_CHECKED: 'is-checked'\n};\n/**\n * Handle change of state.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialSwitch.prototype.onChange_ = function (event) {\n this.updateClasses_();\n};\n/**\n * Handle focus of element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialSwitch.prototype.onFocus_ = function (event) {\n this.element_.classList.add(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle lost focus of element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialSwitch.prototype.onBlur_ = function (event) {\n this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle mouseup.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialSwitch.prototype.onMouseUp_ = function (event) {\n this.blur_();\n};\n/**\n * Handle class updates.\n *\n * @private\n */\nMaterialSwitch.prototype.updateClasses_ = function () {\n this.checkDisabled();\n this.checkToggleState();\n};\n/**\n * Add blur.\n *\n * @private\n */\nMaterialSwitch.prototype.blur_ = function () {\n // TODO: figure out why there's a focus event being fired after our blur,\n // so that we can avoid this hack.\n window.setTimeout(function () {\n this.inputElement_.blur();\n }.bind(this), this.Constant_.TINY_TIMEOUT);\n};\n// Public methods.\n/**\n * Check the components disabled state.\n *\n * @public\n */\nMaterialSwitch.prototype.checkDisabled = function () {\n if (this.inputElement_.disabled) {\n this.element_.classList.add(this.CssClasses_.IS_DISABLED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_DISABLED);\n }\n};\nMaterialSwitch.prototype['checkDisabled'] = MaterialSwitch.prototype.checkDisabled;\n/**\n * Check the components toggled state.\n *\n * @public\n */\nMaterialSwitch.prototype.checkToggleState = function () {\n if (this.inputElement_.checked) {\n this.element_.classList.add(this.CssClasses_.IS_CHECKED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_CHECKED);\n }\n};\nMaterialSwitch.prototype['checkToggleState'] = MaterialSwitch.prototype.checkToggleState;\n/**\n * Disable switch.\n *\n * @public\n */\nMaterialSwitch.prototype.disable = function () {\n this.inputElement_.disabled = true;\n this.updateClasses_();\n};\nMaterialSwitch.prototype['disable'] = MaterialSwitch.prototype.disable;\n/**\n * Enable switch.\n *\n * @public\n */\nMaterialSwitch.prototype.enable = function () {\n this.inputElement_.disabled = false;\n this.updateClasses_();\n};\nMaterialSwitch.prototype['enable'] = MaterialSwitch.prototype.enable;\n/**\n * Activate switch.\n *\n * @public\n */\nMaterialSwitch.prototype.on = function () {\n this.inputElement_.checked = true;\n this.updateClasses_();\n};\nMaterialSwitch.prototype['on'] = MaterialSwitch.prototype.on;\n/**\n * Deactivate switch.\n *\n * @public\n */\nMaterialSwitch.prototype.off = function () {\n this.inputElement_.checked = false;\n this.updateClasses_();\n};\nMaterialSwitch.prototype['off'] = MaterialSwitch.prototype.off;\n/**\n * Initialize element.\n */\nMaterialSwitch.prototype.init = function () {\n if (this.element_) {\n this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);\n var track = document.createElement('div');\n track.classList.add(this.CssClasses_.TRACK);\n var thumb = document.createElement('div');\n thumb.classList.add(this.CssClasses_.THUMB);\n var focusHelper = document.createElement('span');\n focusHelper.classList.add(this.CssClasses_.FOCUS_HELPER);\n thumb.appendChild(focusHelper);\n this.element_.appendChild(track);\n this.element_.appendChild(thumb);\n this.boundMouseUpHandler = this.onMouseUp_.bind(this);\n if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {\n this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);\n this.rippleContainerElement_ = document.createElement('span');\n this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);\n this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT);\n this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);\n this.rippleContainerElement_.addEventListener('mouseup', this.boundMouseUpHandler);\n var ripple = document.createElement('span');\n ripple.classList.add(this.CssClasses_.RIPPLE);\n this.rippleContainerElement_.appendChild(ripple);\n this.element_.appendChild(this.rippleContainerElement_);\n }\n this.boundChangeHandler = this.onChange_.bind(this);\n this.boundFocusHandler = this.onFocus_.bind(this);\n this.boundBlurHandler = this.onBlur_.bind(this);\n this.inputElement_.addEventListener('change', this.boundChangeHandler);\n this.inputElement_.addEventListener('focus', this.boundFocusHandler);\n this.inputElement_.addEventListener('blur', this.boundBlurHandler);\n this.element_.addEventListener('mouseup', this.boundMouseUpHandler);\n this.updateClasses_();\n this.element_.classList.add('is-upgraded');\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialSwitch,\n classAsString: 'MaterialSwitch',\n cssClass: 'mdl-js-switch',\n widget: true\n});","/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Textfield MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialTextfield = function MaterialTextfield(element) {\n this.element_ = element;\n this.maxRows = this.Constant_.NO_MAX_ROWS;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialTextfield'] = MaterialTextfield;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialTextfield.prototype.Constant_ = {\n NO_MAX_ROWS: -1,\n MAX_ROWS_ATTRIBUTE: 'maxrows'\n};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialTextfield.prototype.CssClasses_ = {\n LABEL: 'mdl-textfield__label',\n INPUT: 'mdl-textfield__input',\n IS_DIRTY: 'is-dirty',\n IS_FOCUSED: 'is-focused',\n IS_DISABLED: 'is-disabled',\n IS_INVALID: 'is-invalid',\n IS_UPGRADED: 'is-upgraded',\n HAS_PLACEHOLDER: 'has-placeholder'\n};\n/**\n * Handle input being entered.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialTextfield.prototype.onKeyDown_ = function (event) {\n var currentRowCount = event.target.value.split('\\n').length;\n if (event.keyCode === 13) {\n if (currentRowCount >= this.maxRows) {\n event.preventDefault();\n }\n }\n};\n/**\n * Handle focus.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialTextfield.prototype.onFocus_ = function (event) {\n this.element_.classList.add(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle lost focus.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialTextfield.prototype.onBlur_ = function (event) {\n this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle reset event from out side.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialTextfield.prototype.onReset_ = function (event) {\n this.updateClasses_();\n};\n/**\n * Handle class updates.\n *\n * @private\n */\nMaterialTextfield.prototype.updateClasses_ = function () {\n this.checkDisabled();\n this.checkValidity();\n this.checkDirty();\n this.checkFocus();\n};\n// Public methods.\n/**\n * Check the disabled state and update field accordingly.\n *\n * @public\n */\nMaterialTextfield.prototype.checkDisabled = function () {\n if (this.input_.disabled) {\n this.element_.classList.add(this.CssClasses_.IS_DISABLED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_DISABLED);\n }\n};\nMaterialTextfield.prototype['checkDisabled'] = MaterialTextfield.prototype.checkDisabled;\n/**\n * Check the focus state and update field accordingly.\n *\n * @public\n */\nMaterialTextfield.prototype.checkFocus = function () {\n if (Boolean(this.element_.querySelector(':focus'))) {\n this.element_.classList.add(this.CssClasses_.IS_FOCUSED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);\n }\n};\nMaterialTextfield.prototype['checkFocus'] = MaterialTextfield.prototype.checkFocus;\n/**\n * Check the validity state and update field accordingly.\n *\n * @public\n */\nMaterialTextfield.prototype.checkValidity = function () {\n if (this.input_.validity) {\n if (this.input_.validity.valid) {\n this.element_.classList.remove(this.CssClasses_.IS_INVALID);\n } else {\n this.element_.classList.add(this.CssClasses_.IS_INVALID);\n }\n }\n};\nMaterialTextfield.prototype['checkValidity'] = MaterialTextfield.prototype.checkValidity;\n/**\n * Check the dirty state and update field accordingly.\n *\n * @public\n */\nMaterialTextfield.prototype.checkDirty = function () {\n if (this.input_.value && this.input_.value.length > 0) {\n this.element_.classList.add(this.CssClasses_.IS_DIRTY);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_DIRTY);\n }\n};\nMaterialTextfield.prototype['checkDirty'] = MaterialTextfield.prototype.checkDirty;\n/**\n * Disable text field.\n *\n * @public\n */\nMaterialTextfield.prototype.disable = function () {\n this.input_.disabled = true;\n this.updateClasses_();\n};\nMaterialTextfield.prototype['disable'] = MaterialTextfield.prototype.disable;\n/**\n * Enable text field.\n *\n * @public\n */\nMaterialTextfield.prototype.enable = function () {\n this.input_.disabled = false;\n this.updateClasses_();\n};\nMaterialTextfield.prototype['enable'] = MaterialTextfield.prototype.enable;\n/**\n * Update text field value.\n *\n * @param {string} value The value to which to set the control (optional).\n * @public\n */\nMaterialTextfield.prototype.change = function (value) {\n this.input_.value = value || '';\n this.updateClasses_();\n};\nMaterialTextfield.prototype['change'] = MaterialTextfield.prototype.change;\n/**\n * Initialize element.\n */\nMaterialTextfield.prototype.init = function () {\n if (this.element_) {\n this.label_ = this.element_.querySelector('.' + this.CssClasses_.LABEL);\n this.input_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);\n if (this.input_) {\n if (this.input_.hasAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE)) {\n this.maxRows = parseInt(this.input_.getAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE), 10);\n if (isNaN(this.maxRows)) {\n this.maxRows = this.Constant_.NO_MAX_ROWS;\n }\n }\n if (this.input_.hasAttribute('placeholder')) {\n this.element_.classList.add(this.CssClasses_.HAS_PLACEHOLDER);\n }\n this.boundUpdateClassesHandler = this.updateClasses_.bind(this);\n this.boundFocusHandler = this.onFocus_.bind(this);\n this.boundBlurHandler = this.onBlur_.bind(this);\n this.boundResetHandler = this.onReset_.bind(this);\n this.input_.addEventListener('input', this.boundUpdateClassesHandler);\n this.input_.addEventListener('focus', this.boundFocusHandler);\n this.input_.addEventListener('blur', this.boundBlurHandler);\n this.input_.addEventListener('reset', this.boundResetHandler);\n if (this.maxRows !== this.Constant_.NO_MAX_ROWS) {\n // TODO: This should handle pasting multi line text.\n // Currently doesn't.\n this.boundKeyDownHandler = this.onKeyDown_.bind(this);\n this.input_.addEventListener('keydown', this.boundKeyDownHandler);\n }\n var invalid = this.element_.classList.contains(this.CssClasses_.IS_INVALID);\n this.updateClasses_();\n this.element_.classList.add(this.CssClasses_.IS_UPGRADED);\n if (invalid) {\n this.element_.classList.add(this.CssClasses_.IS_INVALID);\n }\n if (this.input_.hasAttribute('autofocus')) {\n this.element_.focus();\n this.checkFocus();\n }\n }\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialTextfield,\n classAsString: 'MaterialTextfield',\n cssClass: 'mdl-js-textfield',\n widget: true\n});","/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Tooltip MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialTooltip = function MaterialTooltip(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialTooltip'] = MaterialTooltip;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialTooltip.prototype.Constant_ = {};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialTooltip.prototype.CssClasses_ = {\n IS_ACTIVE: 'is-active',\n BOTTOM: 'mdl-tooltip--bottom',\n LEFT: 'mdl-tooltip--left',\n RIGHT: 'mdl-tooltip--right',\n TOP: 'mdl-tooltip--top'\n};\n/**\n * Handle mouseenter for tooltip.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialTooltip.prototype.handleMouseEnter_ = function (event) {\n var props = event.target.getBoundingClientRect();\n var left = props.left + props.width / 2;\n var top = props.top + props.height / 2;\n var marginLeft = -1 * (this.element_.offsetWidth / 2);\n var marginTop = -1 * (this.element_.offsetHeight / 2);\n if (this.element_.classList.contains(this.CssClasses_.LEFT) || this.element_.classList.contains(this.CssClasses_.RIGHT)) {\n left = props.width / 2;\n if (top + marginTop < 0) {\n this.element_.style.top = '0';\n this.element_.style.marginTop = '0';\n } else {\n this.element_.style.top = top + 'px';\n this.element_.style.marginTop = marginTop + 'px';\n }\n } else {\n if (left + marginLeft < 0) {\n this.element_.style.left = '0';\n this.element_.style.marginLeft = '0';\n } else {\n this.element_.style.left = left + 'px';\n this.element_.style.marginLeft = marginLeft + 'px';\n }\n }\n if (this.element_.classList.contains(this.CssClasses_.TOP)) {\n this.element_.style.top = props.top - this.element_.offsetHeight - 10 + 'px';\n } else if (this.element_.classList.contains(this.CssClasses_.RIGHT)) {\n this.element_.style.left = props.left + props.width + 10 + 'px';\n } else if (this.element_.classList.contains(this.CssClasses_.LEFT)) {\n this.element_.style.left = props.left - this.element_.offsetWidth - 10 + 'px';\n } else {\n this.element_.style.top = props.top + props.height + 10 + 'px';\n }\n this.element_.classList.add(this.CssClasses_.IS_ACTIVE);\n};\n/**\n * Hide tooltip on mouseleave or scroll\n *\n * @private\n */\nMaterialTooltip.prototype.hideTooltip_ = function () {\n this.element_.classList.remove(this.CssClasses_.IS_ACTIVE);\n};\n/**\n * Initialize element.\n */\nMaterialTooltip.prototype.init = function () {\n if (this.element_) {\n var forElId = this.element_.getAttribute('for') || this.element_.getAttribute('data-mdl-for');\n if (forElId) {\n this.forElement_ = document.getElementById(forElId);\n }\n if (this.forElement_) {\n // It's left here because it prevents accidental text selection on Android\n if (!this.forElement_.hasAttribute('tabindex')) {\n this.forElement_.setAttribute('tabindex', '0');\n }\n this.boundMouseEnterHandler = this.handleMouseEnter_.bind(this);\n this.boundMouseLeaveAndScrollHandler = this.hideTooltip_.bind(this);\n this.forElement_.addEventListener('mouseenter', this.boundMouseEnterHandler, false);\n this.forElement_.addEventListener('touchend', this.boundMouseEnterHandler, false);\n this.forElement_.addEventListener('mouseleave', this.boundMouseLeaveAndScrollHandler, false);\n window.addEventListener('scroll', this.boundMouseLeaveAndScrollHandler, true);\n window.addEventListener('touchstart', this.boundMouseLeaveAndScrollHandler);\n }\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialTooltip,\n classAsString: 'MaterialTooltip',\n cssClass: 'mdl-tooltip'\n});","/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Data Table Card MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {Element} element The element that will be upgraded.\n */\nvar MaterialDataTable = function MaterialDataTable(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialDataTable'] = MaterialDataTable;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialDataTable.prototype.Constant_ = {};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialDataTable.prototype.CssClasses_ = {\n DATA_TABLE: 'mdl-data-table',\n SELECTABLE: 'mdl-data-table--selectable',\n SELECT_ELEMENT: 'mdl-data-table__select',\n IS_SELECTED: 'is-selected',\n IS_UPGRADED: 'is-upgraded'\n};\n/**\n * Generates and returns a function that toggles the selection state of a\n * single row (or multiple rows).\n *\n * @param {Element} checkbox Checkbox that toggles the selection state.\n * @param {Element} row Row to toggle when checkbox changes.\n * @param {(Array<Object>|NodeList)=} opt_rows Rows to toggle when checkbox changes.\n * @private\n */\nMaterialDataTable.prototype.selectRow_ = function (checkbox, row, opt_rows) {\n if (row) {\n return function () {\n if (checkbox.checked) {\n row.classList.add(this.CssClasses_.IS_SELECTED);\n } else {\n row.classList.remove(this.CssClasses_.IS_SELECTED);\n }\n }.bind(this);\n }\n if (opt_rows) {\n return function () {\n var i;\n var el;\n if (checkbox.checked) {\n for (i = 0; i < opt_rows.length; i++) {\n el = opt_rows[i].querySelector('td').querySelector('.mdl-checkbox');\n el['MaterialCheckbox'].check();\n opt_rows[i].classList.add(this.CssClasses_.IS_SELECTED);\n }\n } else {\n for (i = 0; i < opt_rows.length; i++) {\n el = opt_rows[i].querySelector('td').querySelector('.mdl-checkbox');\n el['MaterialCheckbox'].uncheck();\n opt_rows[i].classList.remove(this.CssClasses_.IS_SELECTED);\n }\n }\n }.bind(this);\n }\n};\n/**\n * Creates a checkbox for a single or or multiple rows and hooks up the\n * event handling.\n *\n * @param {Element} row Row to toggle when checkbox changes.\n * @param {(Array<Object>|NodeList)=} opt_rows Rows to toggle when checkbox changes.\n * @private\n */\nMaterialDataTable.prototype.createCheckbox_ = function (row, opt_rows) {\n var label = document.createElement('label');\n var labelClasses = [\n 'mdl-checkbox',\n 'mdl-js-checkbox',\n 'mdl-js-ripple-effect',\n this.CssClasses_.SELECT_ELEMENT\n ];\n label.className = labelClasses.join(' ');\n var checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.classList.add('mdl-checkbox__input');\n if (row) {\n checkbox.checked = row.classList.contains(this.CssClasses_.IS_SELECTED);\n checkbox.addEventListener('change', this.selectRow_(checkbox, row));\n } else if (opt_rows) {\n checkbox.addEventListener('change', this.selectRow_(checkbox, null, opt_rows));\n }\n label.appendChild(checkbox);\n componentHandler.upgradeElement(label, 'MaterialCheckbox');\n return label;\n};\n/**\n * Initialize element.\n */\nMaterialDataTable.prototype.init = function () {\n if (this.element_) {\n var firstHeader = this.element_.querySelector('th');\n var bodyRows = Array.prototype.slice.call(this.element_.querySelectorAll('tbody tr'));\n var footRows = Array.prototype.slice.call(this.element_.querySelectorAll('tfoot tr'));\n var rows = bodyRows.concat(footRows);\n if (this.element_.classList.contains(this.CssClasses_.SELECTABLE)) {\n var th = document.createElement('th');\n var headerCheckbox = this.createCheckbox_(null, rows);\n th.appendChild(headerCheckbox);\n firstHeader.parentElement.insertBefore(th, firstHeader);\n for (var i = 0; i < rows.length; i++) {\n var firstCell = rows[i].querySelector('td');\n if (firstCell) {\n var td = document.createElement('td');\n if (rows[i].parentNode.nodeName.toUpperCase() === 'TBODY') {\n var rowCheckbox = this.createCheckbox_(rows[i]);\n td.appendChild(rowCheckbox);\n }\n rows[i].insertBefore(td, firstCell);\n }\n }\n this.element_.classList.add(this.CssClasses_.IS_UPGRADED);\n }\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialDataTable,\n classAsString: 'MaterialDataTable',\n cssClass: 'mdl-js-data-table'\n});","/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Ripple MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialRipple = function MaterialRipple(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialRipple'] = MaterialRipple;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialRipple.prototype.Constant_ = {\n INITIAL_SCALE: 'scale(0.0001, 0.0001)',\n INITIAL_SIZE: '1px',\n INITIAL_OPACITY: '0.4',\n FINAL_OPACITY: '0',\n FINAL_SCALE: ''\n};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialRipple.prototype.CssClasses_ = {\n RIPPLE_CENTER: 'mdl-ripple--center',\n RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',\n RIPPLE: 'mdl-ripple',\n IS_ANIMATING: 'is-animating',\n IS_VISIBLE: 'is-visible'\n};\n/**\n * Handle mouse / finger down on element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialRipple.prototype.downHandler_ = function (event) {\n if (!this.rippleElement_.style.width && !this.rippleElement_.style.height) {\n var rect = this.element_.getBoundingClientRect();\n this.boundHeight = rect.height;\n this.boundWidth = rect.width;\n this.rippleSize_ = Math.sqrt(rect.width * rect.width + rect.height * rect.height) * 2 + 2;\n this.rippleElement_.style.width = this.rippleSize_ + 'px';\n this.rippleElement_.style.height = this.rippleSize_ + 'px';\n }\n this.rippleElement_.classList.add(this.CssClasses_.IS_VISIBLE);\n if (event.type === 'mousedown' && this.ignoringMouseDown_) {\n this.ignoringMouseDown_ = false;\n } else {\n if (event.type === 'touchstart') {\n this.ignoringMouseDown_ = true;\n }\n var frameCount = this.getFrameCount();\n if (frameCount > 0) {\n return;\n }\n this.setFrameCount(1);\n var bound = event.currentTarget.getBoundingClientRect();\n var x;\n var y;\n // Check if we are handling a keyboard click.\n if (event.clientX === 0 && event.clientY === 0) {\n x = Math.round(bound.width / 2);\n y = Math.round(bound.height / 2);\n } else {\n var clientX = event.clientX !== undefined ? event.clientX : event.touches[0].clientX;\n var clientY = event.clientY !== undefined ? event.clientY : event.touches[0].clientY;\n x = Math.round(clientX - bound.left);\n y = Math.round(clientY - bound.top);\n }\n this.setRippleXY(x, y);\n this.setRippleStyles(true);\n window.requestAnimationFrame(this.animFrameHandler.bind(this));\n }\n};\n/**\n * Handle mouse / finger up on element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialRipple.prototype.upHandler_ = function (event) {\n // Don't fire for the artificial \"mouseup\" generated by a double-click.\n if (event && event.detail !== 2) {\n // Allow a repaint to occur before removing this class, so the animation\n // shows for tap events, which seem to trigger a mouseup too soon after\n // mousedown.\n window.setTimeout(function () {\n this.rippleElement_.classList.remove(this.CssClasses_.IS_VISIBLE);\n }.bind(this), 0);\n }\n};\n/**\n * Initialize element.\n */\nMaterialRipple.prototype.init = function () {\n if (this.element_) {\n var recentering = this.element_.classList.contains(this.CssClasses_.RIPPLE_CENTER);\n if (!this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT_IGNORE_EVENTS)) {\n this.rippleElement_ = this.element_.querySelector('.' + this.CssClasses_.RIPPLE);\n this.frameCount_ = 0;\n this.rippleSize_ = 0;\n this.x_ = 0;\n this.y_ = 0;\n // Touch start produces a compat mouse down event, which would cause a\n // second ripples. To avoid that, we use this property to ignore the first\n // mouse down after a touch start.\n this.ignoringMouseDown_ = false;\n this.boundDownHandler = this.downHandler_.bind(this);\n this.element_.addEventListener('mousedown', this.boundDownHandler);\n this.element_.addEventListener('touchstart', this.boundDownHandler);\n this.boundUpHandler = this.upHandler_.bind(this);\n this.element_.addEventListener('mouseup', this.boundUpHandler);\n this.element_.addEventListener('mouseleave', this.boundUpHandler);\n this.element_.addEventListener('touchend', this.boundUpHandler);\n this.element_.addEventListener('blur', this.boundUpHandler);\n /**\n * Getter for frameCount_.\n * @return {number} the frame count.\n */\n this.getFrameCount = function () {\n return this.frameCount_;\n };\n /**\n * Setter for frameCount_.\n * @param {number} fC the frame count.\n */\n this.setFrameCount = function (fC) {\n this.frameCount_ = fC;\n };\n /**\n * Getter for rippleElement_.\n * @return {Element} the ripple element.\n */\n this.getRippleElement = function () {\n return this.rippleElement_;\n };\n /**\n * Sets the ripple X and Y coordinates.\n * @param {number} newX the new X coordinate\n * @param {number} newY the new Y coordinate\n */\n this.setRippleXY = function (newX, newY) {\n this.x_ = newX;\n this.y_ = newY;\n };\n /**\n * Sets the ripple styles.\n * @param {boolean} start whether or not this is the start frame.\n */\n this.setRippleStyles = function (start) {\n if (this.rippleElement_ !== null) {\n var transformString;\n var scale;\n var size;\n var offset = 'translate(' + this.x_ + 'px, ' + this.y_ + 'px)';\n if (start) {\n scale = this.Constant_.INITIAL_SCALE;\n size = this.Constant_.INITIAL_SIZE;\n } else {\n scale = this.Constant_.FINAL_SCALE;\n size = this.rippleSize_ + 'px';\n if (recentering) {\n offset = 'translate(' + this.boundWidth / 2 + 'px, ' + this.boundHeight / 2 + 'px)';\n }\n }\n transformString = 'translate(-50%, -50%) ' + offset + scale;\n this.rippleElement_.style.webkitTransform = transformString;\n this.rippleElement_.style.msTransform = transformString;\n this.rippleElement_.style.transform = transformString;\n if (start) {\n this.rippleElement_.classList.remove(this.CssClasses_.IS_ANIMATING);\n } else {\n this.rippleElement_.classList.add(this.CssClasses_.IS_ANIMATING);\n }\n }\n };\n /**\n * Handles an animation frame.\n */\n this.animFrameHandler = function () {\n if (this.frameCount_-- > 0) {\n window.requestAnimationFrame(this.animFrameHandler.bind(this));\n } else {\n this.setRippleStyles(false);\n }\n };\n }\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialRipple,\n classAsString: 'MaterialRipple',\n cssClass: 'mdl-js-ripple-effect',\n widget: false\n});"]}
2 0 \ No newline at end of file
web/static/js/vendor/samp.js 0 โ†’ 100755
... ... @@ -0,0 +1,1307 @@
  1 +// samp
  2 +// ----
  3 +// Provides capabilities for using the SAMP Web Profile from JavaScript.
  4 +// Exported tokens are in the samp.* namespace.
  5 +// Inline documentation is somewhat patchy (partly because I don't know
  6 +// what javascript documentation is supposed to look like) - it is
  7 +// suggested to use it conjunction with the provided examples,
  8 +// currently visible at http://astrojs.github.com/sampjs/
  9 +// (gh-pages branch of github sources).
  10 +
  11 +var samp = (function() {
  12 +
  13 + // Constants defining well-known location of SAMP Web Profile hub etc.
  14 + var WEBSAMP_PORT = 21012;
  15 + var WEBSAMP_PATH = "/";
  16 + var WEBSAMP_PREFIX = "samp.webhub.";
  17 + var WEBSAMP_CLIENT_PREFIX = "";
  18 +
  19 + // Tokens representing permissible types in a SAMP object (e.g. a message)
  20 + TYPE_STRING = "string";
  21 + TYPE_LIST = "list";
  22 + TYPE_MAP = "map";
  23 +
  24 + var heir = function(proto) {
  25 + function F() {};
  26 + F.prototype = proto;
  27 + return new F();
  28 + };
  29 +
  30 + // Utility functions for navigating DOM etc.
  31 + // -----------------------------------------
  32 +
  33 + var getSampType = function(obj) {
  34 + if (typeof obj === "string") {
  35 + return TYPE_STRING;
  36 + }
  37 + else if (obj instanceof Array) {
  38 + return TYPE_LIST;
  39 + }
  40 + else if (obj instanceof Object && obj !== null) {
  41 + return TYPE_MAP;
  42 + }
  43 + else {
  44 + throw new Error("Not legal SAMP object type: " + obj);
  45 + }
  46 + };
  47 + var getChildElements = function(el, childTagName) {
  48 + var children = el.childNodes;
  49 + var child;
  50 + var childEls = [];
  51 + var i;
  52 + for (i = 0; i < children.length; i++) {
  53 + child = children[i];
  54 + if (child.nodeType === 1) { // Element
  55 + if (childTagName && (child.tagName !== childTagName)) {
  56 + throw new Error("Child <" + children[i].tagName + ">"
  57 + + " of <" + el.tagName + ">"
  58 + + " is not a <" + childTagName + ">");
  59 + }
  60 + childEls.push(child);
  61 + }
  62 + }
  63 + return childEls;
  64 + };
  65 + var getSoleChild = function(el, childTagName) {
  66 + var children = getChildElements(el, childTagName);
  67 + if (children.length === 1 ) {
  68 + return children[0];
  69 + }
  70 + else {
  71 + throw new Error("No sole child of <" + el.tagName + ">");
  72 + }
  73 + };
  74 + var getTextContent = function(el) {
  75 + var txt = "";
  76 + var i;
  77 + var child;
  78 + for (i = 0; i < el.childNodes.length; i++ ) {
  79 + child = el.childNodes[i];
  80 + if (child.nodeType === 1) { // Element
  81 + throw new Error("Element found in text content");
  82 + }
  83 + else if (child.nodeType === 3 || // Text
  84 + child.nodeType === 4 ) { // CDATASection
  85 + txt += child.nodeValue;
  86 + }
  87 + }
  88 + return txt;
  89 + };
  90 + var stringify = function(obj) {
  91 + return typeof JSON === "undefined" ? "..." : JSON.stringify(obj);
  92 + };
  93 +
  94 + // XmlRpc class:
  95 + // Utilities for packing and unpacking XML-RPC messages.
  96 + // See xml-rpc.com.
  97 +
  98 + var XmlRpc = {};
  99 +
  100 + // Takes text and turns it into something suitable for use as the content
  101 + // of an XML-RPC string - special characters are escaped.
  102 + XmlRpc.escapeXml = function(s) {
  103 + return s.replace(/&/g, "&amp;")
  104 + .replace(/</g, "&lt;")
  105 + .replace(/>/g, "&gt;");
  106 + };
  107 +
  108 + // Asserts that the elements of paramList match the types given by typeList.
  109 + // TypeList must be an array containing only TYPE_STRING, TYPE_LIST
  110 + // and TYPE_MAP objects in some combination. paramList must be the
  111 + // same length.
  112 + // In case of mismatch an error is thrown.
  113 + XmlRpc.checkParams = function(paramList, typeList) {
  114 + var i;
  115 + for (i = 0; i < typeList.length; i++) {
  116 + if (typeList[i] !== TYPE_STRING &&
  117 + typeList[i] !== TYPE_LIST &&
  118 + typeList[i] !== TYPE_MAP) {
  119 + throw new Error("Unknown type " + typeList[i]
  120 + + " in check list");
  121 + }
  122 + }
  123 + var npar = paramList.length;
  124 + var actualTypeList = [];
  125 + var ok = true;
  126 + for (i = 0; i < npar; i++) {
  127 + actualTypeList.push(getSampType(paramList[i]));
  128 + }
  129 + ok = ok && (typeList.length === npar);
  130 + for (i = 0; ok && i < npar; i++ ) {
  131 + ok = ok && typeList[i] === actualTypeList[i];
  132 + }
  133 + if (!ok) {
  134 + throw new Error("Param type list mismatch: "
  135 + + "[" + typeList + "] != "
  136 + + "[" + actualTypeList + "]");
  137 + }
  138 + };
  139 +
  140 + // Turns a SAMP object (structure of strings, lists, maps) into an
  141 + // XML string suitable for use with XML-RPC.
  142 + XmlRpc.valueToXml = function v2x(obj, prefix) {
  143 + prefix = prefix || "";
  144 + var a;
  145 + var i;
  146 + var result;
  147 + var type = getSampType(obj);
  148 + if (type === TYPE_STRING) {
  149 + return prefix
  150 + + "<value><string>"
  151 + + XmlRpc.escapeXml(obj)
  152 + + "</string></value>";
  153 + }
  154 + else if (type === TYPE_LIST) {
  155 + result = [];
  156 + result.push(prefix + "<value>",
  157 + prefix + " <array>",
  158 + prefix + " <data>");
  159 + for (i = 0; i < obj.length; i++) {
  160 + result.push(v2x(obj[i], prefix + " "));
  161 + }
  162 + result.push(prefix + " </data>",
  163 + prefix + " </array>",
  164 + prefix + "</value>");
  165 +
  166 + return result.join("\n");
  167 + }
  168 + else if (type === TYPE_MAP) {
  169 + result = [];
  170 + result.push(prefix + "<value>");
  171 + result.push(prefix + " <struct>");
  172 + for (i in obj) {
  173 + result.push(prefix + " <member>");
  174 + result.push(prefix + " <name>"
  175 + + XmlRpc.escapeXml(i)
  176 + + "</name>");
  177 + result.push(v2x(obj[i], prefix + " "));
  178 + result.push(prefix + " </member>");
  179 + }
  180 + result.push(prefix + " </struct>");
  181 + result.push(prefix + "</value>");
  182 + return result.join("\n");
  183 + }
  184 + else {
  185 + throw new Error("bad type"); // shouldn't get here
  186 + }
  187 + };
  188 +
  189 + // Turns an XML string from and XML-RPC message into a SAMP object
  190 + // (structure of strings, lists, maps).
  191 + XmlRpc.xmlToValue = function x2v(valueEl, allowInt) {
  192 + var childEls = getChildElements(valueEl);
  193 + var i;
  194 + var j;
  195 + var txt;
  196 + var node;
  197 + var childEl;
  198 + var elName;
  199 + if (childEls.length === 0) {
  200 + return getTextContent(valueEl);
  201 + }
  202 + else if (childEls.length === 1) {
  203 + childEl = childEls[0];
  204 + elName = childEl.tagName;
  205 + if (elName === "string") {
  206 + return getTextContent(childEl);
  207 + }
  208 + else if (elName === "array") {
  209 + var valueEls =
  210 + getChildElements(getSoleChild(childEl, "data"), "value");
  211 + var list = [];
  212 + for (i = 0; i < valueEls.length; i++) {
  213 + list.push(x2v(valueEls[i], allowInt));
  214 + }
  215 + return list;
  216 + }
  217 + else if (elName === "struct") {
  218 + var memberEls = getChildElements(childEl, "member");
  219 + var map = {};
  220 + var s_name;
  221 + var s_value;
  222 + var jc;
  223 + for (i = 0; i < memberEls.length; i++) {
  224 + s_name = undefined;
  225 + s_value = undefined;
  226 + for (j = 0; j < memberEls[i].childNodes.length; j++) {
  227 + jc = memberEls[i].childNodes[j];
  228 + if (jc.nodeType == 1) {
  229 + if (jc.tagName === "name") {
  230 + s_name = getTextContent(jc);
  231 + }
  232 + else if (jc.tagName === "value") {
  233 + s_value = x2v(jc, allowInt);
  234 + }
  235 + }
  236 + }
  237 + if (s_name !== undefined && s_value !== undefined) {
  238 + map[s_name] = s_value;
  239 + }
  240 + else {
  241 + throw new Error("No <name> and/or <value> "
  242 + + "in <member>?");
  243 + }
  244 + }
  245 + return map;
  246 + }
  247 + else if (allowInt && (elName === "int" || elName === "i4")) {
  248 + return getTextContent(childEl);
  249 + }
  250 + else {
  251 + throw new Error("Non SAMP-friendly value content: "
  252 + + "<" + elName + ">");
  253 + }
  254 + }
  255 + else {
  256 + throw new Error("Bad XML-RPC <value> content - multiple elements");
  257 + }
  258 + };
  259 +
  260 + // Turns the content of an XML-RPC <params> element into an array of
  261 + // SAMP objects.
  262 + XmlRpc.decodeParams = function(paramsEl) {
  263 + var paramEls = getChildElements(paramsEl, "param");
  264 + var i;
  265 + var results = [];
  266 + for (i = 0; i < paramEls.length; i++) {
  267 + results.push(XmlRpc.xmlToValue(getSoleChild(paramEls[i], "value")));
  268 + }
  269 + return results;
  270 + };
  271 +
  272 + // Turns the content of an XML-RPC <fault> element into an XmlRpc.Fault
  273 + // object.
  274 + XmlRpc.decodeFault = function(faultEl) {
  275 + var faultObj = XmlRpc.xmlToValue(getSoleChild(faultEl, "value"), true);
  276 + return new XmlRpc.Fault(faultObj.faultString, faultObj.faultCode);
  277 + };
  278 +
  279 + // Turns an XML-RPC response element (should be <methodResponse>) into
  280 + // either a SAMP response object or an XmlRpc.Fault object.
  281 + // Note that a fault response does not throw an error, so check for
  282 + // the type of the result if you want to know whether a fault occurred.
  283 + // An error will however be thrown if the supplied XML does not
  284 + // correspond to a legal XML-RPC response.
  285 + XmlRpc.decodeResponse = function(xml) {
  286 + var mrEl = xml.documentElement;
  287 + if (mrEl.tagName !== "methodResponse") {
  288 + throw new Error("Response element is not <methodResponse>");
  289 + }
  290 + var contentEl = getSoleChild(mrEl);
  291 + if (contentEl.tagName === "fault") {
  292 + return XmlRpc.decodeFault(contentEl);
  293 + }
  294 + else if (contentEl.tagName === "params") {
  295 + return XmlRpc.decodeParams(contentEl)[0];
  296 + }
  297 + else {
  298 + throw new Error("Bad XML-RPC response - unknown element"
  299 + + " <" + contentEl.tagName + ">");
  300 + }
  301 + };
  302 +
  303 + // XmlRpc.Fault class:
  304 + // Represents an XML-RPC Fault response.
  305 + XmlRpc.Fault = function(faultString, faultCode) {
  306 + this.faultString = faultString;
  307 + this.faultCode = faultCode;
  308 + };
  309 + XmlRpc.Fault.prototype.toString = function() {
  310 + return "XML-RPC Fault (" + this.faultCode + "): " + this.faultString;
  311 + };
  312 +
  313 + // XmlRpcRequest class:
  314 + // Represents an call which can be sent to an XML-RPC server.
  315 + var XmlRpcRequest = function(methodName, params) {
  316 + this.methodName = methodName;
  317 + this.params = params || [];
  318 + }
  319 + XmlRpcRequest.prototype.toString = function() {
  320 + return this.methodName + "(" + stringify(this.params) + ")";
  321 + };
  322 + XmlRpcRequest.prototype.addParam = function(param) {
  323 + this.params.push(param);
  324 + return this;
  325 + };
  326 + XmlRpcRequest.prototype.addParams = function(params) {
  327 + var i;
  328 + for (i = 0; i < params.length; i++) {
  329 + this.params.push(params[i]);
  330 + }
  331 + return this;
  332 + };
  333 + XmlRpcRequest.prototype.checkParams = function(typeList) {
  334 + XmlRpc.checkParams(this.params, typeList);
  335 + };
  336 + XmlRpcRequest.prototype.toXml = function() {
  337 + var lines = [];
  338 + lines.push(
  339 + "<?xml version='1.0'?>",
  340 + "<methodCall>",
  341 + " <methodName>" + this.methodName + "</methodName>",
  342 + " <params>");
  343 + for (var i = 0; i < this.params.length; i++) {
  344 + lines.push(" <param>",
  345 + XmlRpc.valueToXml(this.params[i], " "),
  346 + " </param>");
  347 + }
  348 + lines.push(
  349 + " </params>",
  350 + "</methodCall>");
  351 + return lines.join("\n");
  352 + };
  353 +
  354 + // XmlRpcClient class:
  355 + // Object capable of sending XML-RPC calls to an XML-RPC server.
  356 + // That server will typically reside on the host on which the
  357 + // javascript is running; it is not likely to reside on the host
  358 + // which served the javascript. That means that sandboxing restrictions
  359 + // will be in effect. Much of the work done here is therefore to
  360 + // do the client-side work required to potentially escape the sandbox.
  361 + // The endpoint parameter, if supplied, is the URL of the XML-RPC server.
  362 + // If absent, the default SAMP Web Profile server is used.
  363 + var XmlRpcClient = function(endpoint) {
  364 + this.endpoint = endpoint ||
  365 + "http://localhost:" + WEBSAMP_PORT + WEBSAMP_PATH;
  366 + };
  367 +
  368 + // Creates an XHR facade - an object that presents an interface
  369 + // resembling that of an XMLHttpRequest Level 2.
  370 + // This facade may be based on an actual XMLHttpRequest Level 2 object
  371 + // (on browsers that support it), or it may fake one using other
  372 + // available technology.
  373 + //
  374 + // The created facade in any case presents the following interface:
  375 + //
  376 + // open(method, url)
  377 + // send(body)
  378 + // abort()
  379 + // setContentType()
  380 + // responseText
  381 + // responseXML
  382 + // onload
  383 + // onerror(err) - includes timeout; abort is ignored
  384 + //
  385 + // See the documentation at http://www.w3.org/TR/XMLHttpRequest/
  386 + // for semantics.
  387 + //
  388 + // XMLHttpRequest Level 2 supports Cross-Origin Resource Sharing (CORS)
  389 + // which makes sandbox evasion possible. Faked XHRL2s returned by
  390 + // this method may use CORS or some other technology to evade the
  391 + // sandbox. The SAMP hub itself may selectively allow some of these
  392 + // technologies and not others, according to configuration.
  393 + XmlRpcClient.createXHR = function() {
  394 +
  395 + // Creates an XHR facade based on a genuine XMLHttpRequest Level 2.
  396 + var XhrL2 = function(xhr) {
  397 + this.xhr = xhr;
  398 + xhr.onreadystatechange = (function(l2) {
  399 + return function() {
  400 + if (xhr.readyState !== 4) {
  401 + return;
  402 + }
  403 + else if (!l2.completed) {
  404 + if (+xhr.status === 200) {
  405 + l2.completed = true;
  406 + l2.responseText = xhr.responseText;
  407 + l2.responseXML = xhr.responseXML;
  408 + if (l2.onload) {
  409 + l2.onload();
  410 + }
  411 + }
  412 + }
  413 + };
  414 + })(this);
  415 + xhr.onerror = (function(l2) {
  416 + return function(event) {
  417 + if (!l2.completed) {
  418 + l2.completed = true;
  419 + if (l2.onerror) {
  420 + if (event) {
  421 + event.toString = function() {return "No hub?";};
  422 + }
  423 + else {
  424 + event = "No hub?";
  425 + }
  426 + l2.onerror(event);
  427 + }
  428 + }
  429 + };
  430 + })(this);
  431 + xhr.ontimeout = (function(l2) {
  432 + return function(event) {
  433 + if (!l2.completed) {
  434 + l2.completed = true;
  435 + if (l2.onerror) {
  436 + l2.onerror("timeout");
  437 + }
  438 + }
  439 + };
  440 + })(this);
  441 + };
  442 + XhrL2.prototype.open = function(method, url) {
  443 + this.xhr.open(method, url);
  444 + };
  445 + XhrL2.prototype.send = function(body) {
  446 + this.xhr.send(body);
  447 + };
  448 + XhrL2.prototype.abort = function() {
  449 + this.xhr.abort();
  450 + }
  451 + XhrL2.prototype.setContentType = function(mimeType) {
  452 + if ("setRequestHeader" in this.xhr) {
  453 + this.xhr.setRequestHeader("Content-Type", mimeType);
  454 + }
  455 + }
  456 +
  457 + // Creates an XHR facade based on an XDomainRequest (IE8+ only).
  458 + var XdrL2 = function(xdr) {
  459 + this.xdr = xdr;
  460 + xdr.onload = (function(l2) {
  461 + return function() {
  462 + var e;
  463 + l2.responseText = xdr.responseText;
  464 + if (xdr.contentType === "text/xml" ||
  465 + xdr.contentType === "application/xml" ||
  466 + /\/x-/.test(xdr.contentType)) {
  467 + try {
  468 + var xdoc = new ActiveXObject("Microsoft.XMLDOM");
  469 + xdoc.loadXML(xdr.responseText);
  470 + l2.responseXML = xdoc;
  471 + }
  472 + catch (e) {
  473 + l2.responseXML = e;
  474 + }
  475 + }
  476 + if (l2.onload) {
  477 + l2.onload();
  478 + }
  479 + };
  480 + })(this);
  481 + xdr.onerror = (function(l2) {
  482 + return function(event) {
  483 + if (l2.onerror) {
  484 + l2.onerror(event);
  485 + }
  486 + };
  487 + })(this);
  488 + xdr.ontimeout = (function(l2) {
  489 + return function(event) {
  490 + if (l2.onerror) {
  491 + l2.onerror(event);
  492 + }
  493 + };
  494 + })(this);
  495 + };
  496 + XdrL2.prototype.open = function(method, url) {
  497 + this.xdr.open(method, url);
  498 + };
  499 + XdrL2.prototype.send = function(body) {
  500 + this.xdr.send(body);
  501 + };
  502 + XdrL2.prototype.abort = function() {
  503 + this.xdr.abort();
  504 + };
  505 + XdrL2.prototype.setContentType = function(mimeType) {
  506 + // can't do it.
  507 + };
  508 +
  509 + // Creates an XHR Facade based on available XMLHttpRequest-type
  510 + // capabilibities.
  511 + // If an actual XMLHttpRequest Level 2 is available, use that.
  512 + if (typeof XMLHttpRequest !== "undefined") {
  513 + var xhr = new XMLHttpRequest();
  514 + if ("withCredentials" in xhr) {
  515 + return new XhrL2(xhr);
  516 + }
  517 + }
  518 +
  519 + // Else if an XDomainRequest is available, use that.
  520 + if (typeof XDomainRequest !== "undefined") {
  521 + return new XdrL2(new XDomainRequest());
  522 + }
  523 +
  524 + // Else fake an XMLHttpRequest using Flash/flXHR, if available
  525 + // and use that.
  526 + if (typeof flensed.flXHR !== "undefined") {
  527 + return new XhrL2(new flensed.flXHR({instancePooling: true}));
  528 + }
  529 +
  530 + // No luck.
  531 + throw new Error("no cross-origin mechanism available");
  532 + };
  533 +
  534 + // Executes a request by passing it to the XML-RPC server.
  535 + // On success, the result is passed to the resultHandler.
  536 + // On failure, the errHandler is called with one of two possible
  537 + // arguments: an XmlRpc.Fault object, or an Error object.
  538 + XmlRpcClient.prototype.execute = function(req, resultHandler, errHandler) {
  539 + (function(xClient) {
  540 + var xhr;
  541 + var e;
  542 + try {
  543 + xhr = XmlRpcClient.createXHR();
  544 + xhr.open("POST", xClient.endpoint);
  545 + xhr.setContentType("text/xml");
  546 + }
  547 + catch (e) {
  548 + errHandler(e);
  549 + throw e;
  550 + }
  551 + xhr.onload = function() {
  552 + var xml = xhr.responseXML;
  553 + var result;
  554 + var e;
  555 + if (xml) {
  556 + try {
  557 + result = XmlRpc.decodeResponse(xml);
  558 + }
  559 + catch (e) {
  560 + if (errHandler) {
  561 + errHandler(e);
  562 + }
  563 + return;
  564 + }
  565 + }
  566 + else {
  567 + if (errHandler) {
  568 + errHandler("no XML response");
  569 + }
  570 + return;
  571 + }
  572 + if (result instanceof XmlRpc.Fault) {
  573 + if (errHandler) {
  574 + errHandler(result);
  575 + }
  576 + }
  577 + else {
  578 + if (resultHandler) {
  579 + resultHandler(result);
  580 + }
  581 + }
  582 + };
  583 + xhr.onerror = function(event) {
  584 + if (event) {
  585 + event.toString = function() {return "No hub?";}
  586 + }
  587 + else {
  588 + event = "No hub";
  589 + }
  590 + if (errHandler) {
  591 + errHandler(event);
  592 + }
  593 + };
  594 + xhr.send(req.toXml());
  595 + return xhr;
  596 + })(this);
  597 + };
  598 +
  599 + // Message class:
  600 + // Aggregates an MType string and a params map.
  601 + var Message = function(mtype, params) {
  602 + this["samp.mtype"] = mtype;
  603 + this["samp.params"] = params;
  604 + };
  605 +
  606 + // Connection class:
  607 + // this is what clients use to communicate with the hub.
  608 + //
  609 + // All the methods from the Hub Abstract API as described in the
  610 + // SAMP standard are available as methods of a Connection object.
  611 + // The initial private-key argument required by the Web Profile is
  612 + // handled internally by this object - you do not need to supply it
  613 + // when calling one of the methods.
  614 + //
  615 + // All these calls have the same form:
  616 + //
  617 + // connection.method([method-args], resultHandler, errorHandler)
  618 + //
  619 + // the first argument is an array of the arguments (as per the SAMP
  620 + // abstract hub API), the second argument is a function which is
  621 + // called on successful completion with the result of the SAMP call
  622 + // as its argument, and the third argument is a function which is
  623 + // called on unsuccessful completion with an error object as its
  624 + // argument. The resultHandler and errorHandler arguments are optional.
  625 + //
  626 + // So for instance if you have a Connection object conn,
  627 + // you can send a notify message to all other clients by doing, e.g.:
  628 + //
  629 + // conn.notifyAll([new samp.Message(mtype, params)])
  630 + //
  631 + // Connection has other methods as well as the hub API ones
  632 + // as documented below.
  633 + var Connection = function(regInfo) {
  634 + this.regInfo = regInfo;
  635 + this.privateKey = regInfo["samp.private-key"];
  636 + if (! typeof(this.privateKey) === "string") {
  637 + throw new Error("Bad registration object");
  638 + }
  639 + this.xClient = new XmlRpcClient();
  640 + };
  641 + (function() {
  642 + var connMethods = {
  643 + call: [TYPE_STRING, TYPE_STRING, TYPE_MAP],
  644 + callAll: [TYPE_STRING, TYPE_MAP],
  645 + callAndWait: [TYPE_STRING, TYPE_MAP, TYPE_STRING],
  646 + declareMetadata: [TYPE_MAP],
  647 + declareSubscriptions: [TYPE_MAP],
  648 + getMetadata: [TYPE_STRING],
  649 + getRegisteredClients: [],
  650 + getSubscribedClients: [TYPE_STRING],
  651 + getSubscriptions: [TYPE_STRING],
  652 + notify: [TYPE_STRING, TYPE_MAP],
  653 + notifyAll: [TYPE_MAP],
  654 + ping: [],
  655 + reply: [TYPE_STRING, TYPE_MAP]
  656 + };
  657 + var fn;
  658 + var types;
  659 + for (fn in connMethods) {
  660 + (function(fname, types) {
  661 + // errHandler may be passed an XmlRpc.Fault or a thrown Error.
  662 + Connection.prototype[fname] =
  663 + function(sampArgs, resultHandler, errHandler) {
  664 + var closer =
  665 + (function(c) {return function() {c.close()}})(this);
  666 + errHandler = errHandler || closer
  667 + XmlRpc.checkParams(sampArgs, types);
  668 + var request = new XmlRpcRequest(WEBSAMP_PREFIX + fname);
  669 + request.addParam(this.privateKey);
  670 + request.addParams(sampArgs);
  671 + return this.xClient.
  672 + execute(request, resultHandler, errHandler);
  673 + };
  674 + })(fn, connMethods[fn]);
  675 + }
  676 + })();
  677 + Connection.prototype.unregister = function() {
  678 + var e;
  679 + if (this.callbackRequest) {
  680 + try {
  681 + this.callbackRequest.abort();
  682 + }
  683 + catch (e) {
  684 + }
  685 + }
  686 + var request = new XmlRpcRequest(WEBSAMP_PREFIX + "unregister");
  687 + request.addParam(this.privateKey);
  688 + try {
  689 + this.xClient.execute(request);
  690 + }
  691 + catch (e) {
  692 + // log unregister failed
  693 + }
  694 + delete this.regInfo;
  695 + delete this.privateKey;
  696 + };
  697 +
  698 + // Closes this connection. It unregisters from the hub if still
  699 + // registered, but may harmlessly be called multiple times.
  700 + Connection.prototype.close = function() {
  701 + var e;
  702 + if (this.closed) {
  703 + return;
  704 + }
  705 + this.closed = true;
  706 + try {
  707 + if (this.regInfo) {
  708 + this.unregister();
  709 + }
  710 + }
  711 + catch (e) {
  712 + }
  713 + if (this.onclose) {
  714 + oc = this.onclose;
  715 + delete this.onclose;
  716 + try {
  717 + oc();
  718 + }
  719 + catch (e) {
  720 + }
  721 + }
  722 + };
  723 +
  724 + // Arranges for this connection to receive callbacks.
  725 + //
  726 + // The callableClient argument must be an object implementing the
  727 + // SAMP callable client API, i.e. it must have the following methods:
  728 + //
  729 + // receiveNotification(string sender-id, map message)
  730 + // receiveCall(string sender-id, string msg-id, map message)
  731 + // receiveResponse(string responder-id, string msg-tag, map response)
  732 + //
  733 + // The successHandler argument will be called with no arguments if the
  734 + // allowCallbacks hub method completes successfully - it is a suitable
  735 + // hook to use for declaring subscriptions.
  736 + //
  737 + // The CallableClient class provides a suitable implementation, see below.
  738 + Connection.prototype.setCallable = function(callableClient,
  739 + successHandler) {
  740 + var e;
  741 + if (this.callbackRequest) {
  742 + try {
  743 + this.callbackRequest.abort();
  744 + }
  745 + catch (e) {
  746 + }
  747 + finally {
  748 + delete this.callbackRequest;
  749 + }
  750 + }
  751 + if (!callableClient && !this.regInfo) {
  752 + return;
  753 + }
  754 + var request =
  755 + new XmlRpcRequest(WEBSAMP_PREFIX + "allowReverseCallbacks");
  756 + request.addParam(this.privateKey);
  757 + request.addParam(callableClient ? "1" : "0");
  758 + var closer = (function(c) {return function() {c.close()}})(this);
  759 + if (callableClient) {
  760 + (function(connection) {
  761 + var invokeCallback = function(callback) {
  762 + var methodName = callback["samp.methodName"];
  763 + var methodParams = callback["samp.params"];
  764 + var handlerFunc = undefined;
  765 + if (methodName === WEBSAMP_CLIENT_PREFIX
  766 + + "receiveNotification") {
  767 + handlerFunc = callableClient.receiveNotification;
  768 + }
  769 + else if (methodName === WEBSAMP_CLIENT_PREFIX
  770 + + "receiveCall") {
  771 + handlerFunc = callableClient.receiveCall;
  772 + }
  773 + else if (methodName === WEBSAMP_CLIENT_PREFIX
  774 + + "receiveResponse") {
  775 + handlerFunc = callableClient.receiveResponse;
  776 + }
  777 + else {
  778 + // unknown callback??
  779 + }
  780 + if (handlerFunc) {
  781 + handlerFunc.apply(callableClient, methodParams);
  782 + }
  783 + };
  784 + var startTime;
  785 + var resultHandler = function(result) {
  786 + if (getSampType(result) != TYPE_LIST) {
  787 + errHandler(new Error("pullCallbacks result not List"));
  788 + return;
  789 + }
  790 + var i;
  791 + var e;
  792 + for (i = 0; i < result.length; i++) {
  793 + try {
  794 + invokeCallback(result[i]);
  795 + }
  796 + catch (e) {
  797 + // log here?
  798 + }
  799 + }
  800 + callWaiter();
  801 + };
  802 + var errHandler = function(error) {
  803 + var elapsed = new Date().getTime() - startTime;
  804 + if (elapsed < 1000) {
  805 + connection.close()
  806 + }
  807 + else {
  808 + // probably a timeout
  809 + callWaiter();
  810 + }
  811 + };
  812 + var callWaiter = function() {
  813 + if (!connection.regInfo) {
  814 + return;
  815 + }
  816 + var request =
  817 + new XmlRpcRequest(WEBSAMP_PREFIX + "pullCallbacks");
  818 + request.addParam(connection.privateKey);
  819 + request.addParam("600");
  820 + startTime = new Date().getTime();
  821 + connection.callbackRequest =
  822 + connection.xClient.
  823 + execute(request, resultHandler, errHandler);
  824 + };
  825 + var sHandler = function() {
  826 + callWaiter();
  827 + successHandler();
  828 + };
  829 + connection.xClient.execute(request, sHandler, closer);
  830 + })(this);
  831 + }
  832 + else {
  833 + this.xClient.execute(request, successHandler, closer);
  834 + }
  835 + };
  836 +
  837 + // Takes a public URL and returns a URL that can be used from within
  838 + // this javascript context. Some translation may be required, since
  839 + // a URL sent by an external application may be cross-domain, in which
  840 + // case browser sandboxing would typically disallow access to it.
  841 + Connection.prototype.translateUrl = function(url) {
  842 + var translator = this.regInfo["samp.url-translator"] || "";
  843 + return translator + url;
  844 + };
  845 + Connection.Action = function(actName, actArgs, resultKey) {
  846 + this.actName = actName;
  847 + this.actArgs = actArgs;
  848 + this.resultKey = resultKey;
  849 + };
  850 +
  851 + // Suitable implementation for a callable client object which can
  852 + // be supplied to Connection.setCallable().
  853 + // Its callHandler and replyHandler members are string->function maps
  854 + // which can be used to provide handler functions for MTypes and
  855 + // message tags respectively.
  856 + //
  857 + // In more detail:
  858 + // The callHandler member maps a string representing an MType to
  859 + // a function with arguments (senderId, message, isCall).
  860 + // The replyHandler member maps a string representing a message tag to
  861 + // a function with arguments (responderId, msgTag, response).
  862 + var CallableClient = function(connection) {
  863 + this.callHandler = {};
  864 + this.replyHandler = {};
  865 + };
  866 + CallableClient.prototype.init = function(connection) {
  867 + };
  868 + CallableClient.prototype.receiveNotification = function(senderId, message) {
  869 + var mtype = message["samp.mtype"];
  870 + var handled = false;
  871 + var e;
  872 + if (mtype in this.callHandler) {
  873 + try {
  874 + this.callHandler[mtype](senderId, message, false);
  875 + }
  876 + catch (e) {
  877 + }
  878 + handled = true;
  879 + }
  880 + return handled;
  881 + };
  882 + CallableClient.prototype.receiveCall = function(senderId, msgId, message) {
  883 + var mtype = message["samp.mtype"];
  884 + var handled = false;
  885 + var response;
  886 + var result;
  887 + var e;
  888 + if (mtype in this.callHandler) {
  889 + try {
  890 + result = this.callHandler[mtype](senderId, message, true) || {};
  891 + response = {"samp.status": "samp.ok",
  892 + "samp.result": result};
  893 + handled = true;
  894 + }
  895 + catch (e) {
  896 + response = {"samp.status": "samp.error",
  897 + "samp.error": {"samp.errortxt": e.toString()}};
  898 + }
  899 + }
  900 + else {
  901 + response = {"samp.status": "samp.warning",
  902 + "samp.result": {},
  903 + "samp.error": {"samp.errortxt": "no action"}};
  904 + }
  905 + this.connection.reply([msgId, response]);
  906 + return handled;
  907 + };
  908 + CallableClient.prototype.receiveResponse = function(responderId, msgTag,
  909 + response) {
  910 + var handled = false;
  911 + var e;
  912 + if (msgTag in this.replyHandler) {
  913 + try {
  914 + this.replyHandler[msgTag](responderId, msgTag, response);
  915 + handled = true;
  916 + }
  917 + catch (e) {
  918 + }
  919 + }
  920 + return handled;
  921 + };
  922 + CallableClient.prototype.calculateSubscriptions = function() {
  923 + var subs = {};
  924 + var mt;
  925 + for (mt in this.callHandler) {
  926 + subs[mt] = {};
  927 + }
  928 + return subs;
  929 + };
  930 +
  931 + // ClientTracker is a CallableClient which also provides tracking of
  932 + // registered clients.
  933 + //
  934 + // Its onchange member, if defined, will be called with arguments
  935 + // (client-id, change-type, associated-data) whenever the list or
  936 + // characteristics of registered clients has changed.
  937 + var ClientTracker = function() {
  938 + var tracker = this;
  939 + this.ids = {};
  940 + this.metas = {};
  941 + this.subs = {};
  942 + this.replyHandler = {};
  943 + this.callHandler = {
  944 + "samp.hub.event.shutdown": function(senderId, message) {
  945 + tracker.connection.close();
  946 + },
  947 + "samp.hub.disconnect": function(senderId, message) {
  948 + tracker.connection.close();
  949 + },
  950 + "samp.hub.event.register": function(senderId, message) {
  951 + var id = message["samp.params"]["id"];
  952 + tracker.ids[id] = true;
  953 + tracker.changed(id, "register", null);
  954 + },
  955 + "samp.hub.event.unregister": function(senderId, message) {
  956 + var id = message["samp.params"]["id"];
  957 + delete tracker.ids[id];
  958 + delete tracker.metas[id];
  959 + delete tracker.subs[id];
  960 + tracker.changed(id, "unregister", null);
  961 + },
  962 + "samp.hub.event.metadata": function(senderId, message) {
  963 + var id = message["samp.params"]["id"];
  964 + var meta = message["samp.params"]["metadata"];
  965 + tracker.metas[id] = meta;
  966 + tracker.changed(id, "meta", meta);
  967 + },
  968 + "samp.hub.event.subscriptions": function(senderId, message) {
  969 + var id = message["samp.params"]["id"];
  970 + var subs = message["samp.params"]["subscriptions"];
  971 + tracker.subs[id] = subs;
  972 + tracker.changed(id, "subs", subs);
  973 + }
  974 + };
  975 + };
  976 + ClientTracker.prototype = heir(CallableClient.prototype);
  977 + ClientTracker.prototype.changed = function(id, type, data) {
  978 + if (this.onchange) {
  979 + this.onchange(id, type, data);
  980 + }
  981 + };
  982 + ClientTracker.prototype.init = function(connection) {
  983 + var tracker = this;
  984 + this.connection = connection;
  985 + var retrieveInfo = function(id, type, infoFuncName, infoArray) {
  986 + connection[infoFuncName]([id], function(info) {
  987 + infoArray[id] = info;
  988 + tracker.changed(id, type, info);
  989 + });
  990 + };
  991 + connection.getRegisteredClients([], function(idlist) {
  992 + var i;
  993 + var id;
  994 + tracker.ids = {};
  995 + for (i = 0; i < idlist.length; i++) {
  996 + id = idlist[i];
  997 + tracker.ids[id] = true;
  998 + retrieveInfo(id, "meta", "getMetadata", tracker.metas);
  999 + retrieveInfo(id, "subs", "getSubscriptions", tracker.subs);
  1000 + }
  1001 + tracker.changed(null, "ids", null);
  1002 + });
  1003 + };
  1004 + ClientTracker.prototype.getName = function(id) {
  1005 + var meta = this.metas[id];
  1006 + return (meta && meta["samp.name"]) ? meta["samp.name"] : "[" + id + "]";
  1007 + };
  1008 +
  1009 + // Connector class:
  1010 + // A higher level class which can manage transparent hub
  1011 + // registration/unregistration and client tracking.
  1012 + //
  1013 + // On construction, the name argument is mandatory, and corresponds
  1014 + // to the samp.name item submitted at registration time.
  1015 + // The other arguments are optional.
  1016 + // meta is a metadata map (if absent, no metadata is declared)
  1017 + // callableClient is a callable client object for receiving callbacks
  1018 + // (if absent, the client is not callable).
  1019 + // subs is a subscriptions map (if absent, no subscriptions are declared)
  1020 + var Connector = function(name, meta, callableClient, subs) {
  1021 + this.name = name;
  1022 + this.meta = meta;
  1023 + this.callableClient = callableClient;
  1024 + this.subs = subs;
  1025 + this.regTextNodes = [];
  1026 + this.whenRegs = [];
  1027 + this.whenUnregs = [];
  1028 + this.connection = undefined;
  1029 + this.onreg = undefined;
  1030 + this.onunreg = undefined;
  1031 + };
  1032 + var setRegText = function(connector, txt) {
  1033 + var i;
  1034 + var nodes = connector.regTextNodes;
  1035 + var node;
  1036 + for (i = 0; i < nodes.length; i++) {
  1037 + node = nodes[i];
  1038 + node.innerHTML = "";
  1039 + node.appendChild(document.createTextNode(txt));
  1040 + }
  1041 + };
  1042 + Connector.prototype.setConnection = function(conn) {
  1043 + var connector = this;
  1044 + var e;
  1045 + if (this.connection) {
  1046 + this.connection.close();
  1047 + if (this.onunreg) {
  1048 + try {
  1049 + this.onunreg();
  1050 + }
  1051 + catch (e) {
  1052 + }
  1053 + }
  1054 + }
  1055 + this.connection = conn;
  1056 + if (conn) {
  1057 + conn.onclose = function() {
  1058 + connector.connection = null;
  1059 + if (connector.onunreg) {
  1060 + try {
  1061 + connector.onunreg();
  1062 + }
  1063 + catch (e) {
  1064 + }
  1065 + }
  1066 + connector.update();
  1067 + };
  1068 + if (this.meta) {
  1069 + conn.declareMetadata([this.meta]);
  1070 + }
  1071 + if (this.callableClient) {
  1072 + if (this.callableClient.init) {
  1073 + this.callableClient.init(conn);
  1074 + }
  1075 + conn.setCallable(this.callableClient, function() {
  1076 + conn.declareSubscriptions([connector.subs]);
  1077 + });
  1078 + }
  1079 + if (this.onreg) {
  1080 + try {
  1081 + this.onreg(conn);
  1082 + }
  1083 + catch (e) {
  1084 + }
  1085 + }
  1086 + }
  1087 + this.update();
  1088 + };
  1089 + Connector.prototype.register = function() {
  1090 + var connector = this;
  1091 + var regErrHandler = function(err) {
  1092 + setRegText(connector, "no (" + err.toString() + ")");
  1093 + };
  1094 + var regSuccessHandler = function(conn) {
  1095 + connector.setConnection(conn);
  1096 + setRegText(connector, conn ? "Yes" : "No");
  1097 + };
  1098 + register(this.name, regSuccessHandler, regErrHandler);
  1099 + };
  1100 + Connector.prototype.unregister = function() {
  1101 + if (this.connection) {
  1102 + this.connection.unregister([]);
  1103 + this.setConnection(null);
  1104 + }
  1105 + };
  1106 +
  1107 + // Returns a document fragment which contains Register/Unregister
  1108 + // buttons for use by the user to attempt to connect/disconnect
  1109 + // with the hub. This is useful for models where explicit
  1110 + // user registration is encouraged or required, but when using
  1111 + // the register-on-demand model such buttons are not necessary.
  1112 + Connector.prototype.createRegButtons = function() {
  1113 + var connector = this;
  1114 + var regButt = document.createElement("button");
  1115 + regButt.setAttribute("type", "button");
  1116 + regButt.appendChild(document.createTextNode("Register"));
  1117 + regButt.onclick = function() {connector.register();};
  1118 + this.whenUnregs.push(regButt);
  1119 + var unregButt = document.createElement("button");
  1120 + unregButt.setAttribute("type", "button");
  1121 + unregButt.appendChild(document.createTextNode("Unregister"));
  1122 + unregButt.onclick = function() {connector.unregister();};
  1123 + this.whenRegs.push(unregButt);
  1124 + var regText = document.createElement("span");
  1125 + this.regTextNodes.push(regText);
  1126 + var node = document.createDocumentFragment();
  1127 + node.appendChild(regButt);
  1128 + node.appendChild(document.createTextNode(" "));
  1129 + node.appendChild(unregButt);
  1130 + var label = document.createElement("span");
  1131 + label.innerHTML = " <strong>Registered: </strong>";
  1132 + node.appendChild(label);
  1133 + node.appendChild(regText);
  1134 + this.update();
  1135 + return node;
  1136 + };
  1137 +
  1138 + Connector.prototype.update = function() {
  1139 + var i;
  1140 + var isConnected = !! this.connection;
  1141 + var enableds = isConnected ? this.whenRegs : this.whenUnregs;
  1142 + var disableds = isConnected ? this.whenUnregs : this.whenRegs;
  1143 + for (i = 0; i < enableds.length; i++) {
  1144 + enableds[i].removeAttribute("disabled");
  1145 + }
  1146 + for (i = 0; i < disableds.length; i++) {
  1147 + disableds[i].setAttribute("disabled", "disabled");
  1148 + }
  1149 + setRegText(this, "No");
  1150 + };
  1151 +
  1152 + // Provides execution of a SAMP operation with register-on-demand.
  1153 + // You can use this method to provide lightweight registration/use
  1154 + // of web SAMP. Simply provide a connHandler function which
  1155 + // does something with a connection (e.g. sends a message) and
  1156 + // Connector.runWithConnection on it. This will connect if not
  1157 + // already connected, and call the connHandler on with the connection.
  1158 + // No explicit registration action is then required from the user.
  1159 + //
  1160 + // If the regErrorHandler argument is supplied, it is a function of
  1161 + // one (error) argument called in the case that registration-on-demand
  1162 + // fails.
  1163 + //
  1164 + // This is a more-or-less complete sampjs page:
  1165 + // <script>
  1166 + // var connector = new samp.Connector("pinger", {"samp.name": "Pinger"})
  1167 + // var pingFunc = function(connection) {
  1168 + // connection.notifyAll([new samp.Message("samp.app.ping", {})])
  1169 + // }
  1170 + // </script>
  1171 + // <button onclick="connector.runWithConnection(pingFunc)">Ping</button>
  1172 + Connector.prototype.runWithConnection =
  1173 + function(connHandler, regErrorHandler) {
  1174 + var connector = this;
  1175 + var regSuccessHandler = function(conn) {
  1176 + connector.setConnection(conn);
  1177 + connHandler(conn);
  1178 + };
  1179 + var regFailureHandler = function(e) {
  1180 + connector.setConnection(undefined);
  1181 + regErrorHandler(e);
  1182 + };
  1183 + var pingResultHandler = function(result) {
  1184 + connHandler(connector.connection);
  1185 + };
  1186 + var pingErrorHandler = function(err) {
  1187 + register(this.name, regSuccessHandler, regFailureHandler);
  1188 + };
  1189 + if (this.connection) {
  1190 + // Use getRegisteredClients as the most lightweight check
  1191 + // I can think of that this connection is still OK.
  1192 + // Ping doesn't work because the server replies even if the
  1193 + // private-key is incorrect/invalid. Is that a bug or not?
  1194 + this.connection.
  1195 + getRegisteredClients([], pingResultHandler, pingErrorHandler);
  1196 + }
  1197 + else {
  1198 + register(this.name, regSuccessHandler, regFailureHandler);
  1199 + }
  1200 + };
  1201 +
  1202 + // Sets up an interval timer to run at intervals and notify a callback
  1203 + // about whether a hub is currently running.
  1204 + // Every millis milliseconds, the supplied availHandler function is
  1205 + // called with a boolean argument: true if a (web profile) hub is
  1206 + // running, false if not.
  1207 + // Returns the interval timer (can be passed to clearInterval()).
  1208 + Connector.prototype.onHubAvailability = function(availHandler, millis) {
  1209 + samp.ping(availHandler);
  1210 +
  1211 + // Could use the W3C Page Visibility API to avoid making these
  1212 + // checks when the page is not visible.
  1213 + return setInterval(function() {samp.ping(availHandler);}, millis);
  1214 + };
  1215 +
  1216 + // Determines whether a given subscriptions map indicates subscription
  1217 + // to a given mtype.
  1218 + var isSubscribed = function(subs, mtype) {
  1219 + var matching = function(pattern, mtype) {
  1220 + if (pattern == mtype) {
  1221 + return true;
  1222 + }
  1223 + else if (pattern === "*") {
  1224 + return true;
  1225 + }
  1226 + else {
  1227 + var prefix;
  1228 + var split = /^(.*)\.\*$/.exec(pat);
  1229 + if (split) {
  1230 + prefix = split[1];
  1231 + if (prefix === mtype.substring(0, prefix.length)) {
  1232 + return true;
  1233 + }
  1234 + }
  1235 + }
  1236 + return false;
  1237 + };
  1238 + var pat;
  1239 + for (pat in subs) {
  1240 + if (matching(pat, mtype)) {
  1241 + return true;
  1242 + }
  1243 + }
  1244 + return false;
  1245 + };
  1246 +
  1247 + // Attempts registration with a SAMP hub.
  1248 + // On success the supplied connectionHandler function is called
  1249 + // with the connection as an argument, on failure the supplied
  1250 + // errorHandler is called with an argument that may be an Error
  1251 + // or an XmlRpc.Fault.
  1252 + var register = function(appName, connectionHandler, errorHandler) {
  1253 + var xClient = new XmlRpcClient();
  1254 + var regRequest = new XmlRpcRequest(WEBSAMP_PREFIX + "register");
  1255 + var securityInfo = {"samp.name": appName};
  1256 + regRequest.addParam(securityInfo);
  1257 + regRequest.checkParams([TYPE_MAP]);
  1258 + var resultHandler = function(result) {
  1259 + var conn;
  1260 + var e;
  1261 + try {
  1262 + conn = new Connection(result, 1000);
  1263 + }
  1264 + catch (e) {
  1265 + errorHandler(e);
  1266 + return;
  1267 + }
  1268 + connectionHandler(conn);
  1269 + };
  1270 + xClient.execute(regRequest, resultHandler, errorHandler);
  1271 + };
  1272 +
  1273 + // Calls the hub ping method once. It is not necessary to be
  1274 + // registered to do this.
  1275 + // The supplied pingHandler function is called with a boolean argument:
  1276 + // true if a (web profile) hub is running, false if not.
  1277 + var ping = function(pingHandler) {
  1278 + var xClient = new XmlRpcClient();
  1279 + var pingRequest = new XmlRpcRequest(WEBSAMP_PREFIX + "ping");
  1280 + var resultHandler = function(result) {
  1281 + pingHandler(true);
  1282 + };
  1283 + var errorHandler = function(error) {
  1284 + pingHandler(false);
  1285 + };
  1286 + xClient.execute(pingRequest, resultHandler, errorHandler);
  1287 + };
  1288 +
  1289 +
  1290 + /* Exports. */
  1291 + var jss = {};
  1292 + jss.XmlRpcRequest = XmlRpcRequest;
  1293 + jss.XmlRpcClient = XmlRpcClient;
  1294 + jss.Message = Message;
  1295 + jss.TYPE_STRING = TYPE_STRING;
  1296 + jss.TYPE_LIST = TYPE_LIST;
  1297 + jss.TYPE_MAP = TYPE_MAP;
  1298 + jss.register = register;
  1299 + jss.ping = ping;
  1300 + jss.isSubscribed = isSubscribed;
  1301 + jss.Connector = Connector;
  1302 + jss.CallableClient = CallableClient;
  1303 + jss.ClientTracker = ClientTracker;
  1304 +
  1305 + return jss;
  1306 +})();
  1307 +
... ...
web/view/home.html.jinja2
... ... @@ -8,13 +8,41 @@
8 8 {% block content %}
9 9  
10 10 {% macro target_button(target) -%}
11   - <img width="64px" height="64px"
12   - src="{{ static('img/target/'~target.slug~'_128.png') }}"
13   - title="{{ target.title }}"
14   - alt="{{ target.name }}"
15   - class="target {{ target.slug }} {{ 'locked' if target.locked else 'active' }}"
16   - data-target-slug="{{ target.slug }}"
17   - >
  11 + <div class="target {{ target.slug }} {{ 'locked' if target.locked else 'active' }}"
  12 + data-target-slug="{{ target.slug }}">
  13 + <img width="64px" height="64px"
  14 + src="{{ static('img/target/'~target.slug~'_128.png') }}"
  15 + title="{{ target.title }}"
  16 + alt="{{ target.name }}">
  17 + <img width="64px" height="64px"
  18 + src="{{ static('img/target/empty_128.png') }}"
  19 + title="No data at specified interval for {{ target.title }}"
  20 + alt="No data for {{ target.name }}"
  21 + class="decorator empty">
  22 +{# <img width="32px" height="32px"#}
  23 +{# src="{{ static('img/target/loading_32.gif') }}"#}
  24 +{# title="Loading data for {{ target.title }}โ€ฆ"#}
  25 +{# alt="Loader for {{ target.name }}"#}
  26 +{# class="decorator loading">#}
  27 + <div class="decorator loading" title="Loading data for {{ target.title }}โ€ฆ">
  28 + <div class="small-loader-container">
  29 + <div class="small-loader-circle-1">
  30 + <div class="small-loader-circle-2">
  31 + <div class="small-loader-circle-3">
  32 + <div class="small-loader-circle-4">
  33 + <div class="small-loader-circle-5">
  34 + <div class="small-loader-circle-6">
  35 + <div class="small-loader-circle-7">
  36 + </div>
  37 + </div>
  38 + </div>
  39 + </div>
  40 + </div>
  41 + </div>
  42 + </div>
  43 + </div>
  44 + </div>
  45 + </div>
18 46 {%- endmacro %}
19 47  
20 48 {% macro icon(name) %}<i class="fa fa-{{ name }}" aria-hidden="true"></i>{% endmacro %}
... ... @@ -83,17 +111,19 @@
83 111 <div class="mdl-layout-spacer"></div>
84 112  
85 113 </div>
  114 +
  115 +
86 116 <main id="plots_wrapper" class="mdl-layout__content">
87 117  
88 118 <div class="mdl-grid">
89   - <div class="mdl-cell mdl-cell--4-col">
  119 + <div class="mdl-cell mdl-cell--4-col mdl-cell--8-col-tablet mdl-cell--4-col-phone">
90 120 <section id="orbits"></section>
91 121 <button id="download" class="mdl-button mdl-button--raised mdl-button--primary"
92 122 title="Download the CSV raw data for each target in a tarball.">
93 123 Download
94 124 </button>
95 125 </div>
96   - <div class="mdl-cell mdl-cell--8-col">
  126 + <div class="mdl-cell mdl-cell--8-col mdl-cell--8-col-tablet mdl-cell--4-col-phone">
97 127 <section id="time_series">
98 128 <p id="zoom_controls_help" class="help mdl-cell--8-col">Drag to zoom in, double click to zoom out.</p>
99 129 </section>
... ... @@ -105,6 +135,7 @@
105 135 {% endblock %}
106 136  
107 137  
  138 +{#### CSS ####################################################################}
108 139  
109 140 {% block styles %}
110 141 <style>
... ... @@ -116,10 +147,10 @@
116 147 padding-left: 30px;
117 148 }
118 149  
119   -
120 150 #plots_wrapper {
121 151 {# position: relative;#}
122 152 }
  153 +
123 154 #plots_loader {
124 155 position: fixed;
125 156 top: 0; left: 0; bottom: 0; right: 0;
... ... @@ -147,7 +178,7 @@
147 178 border-radius: 100%;
148 179 position: absolute;
149 180 border: 1px solid #6978ff;
150   - animation: up 1s;
  181 + animation: keyframes_rotate 1s;
151 182 animation-iteration-count: infinite;
152 183 transition: 2s;
153 184 border-bottom: none;
... ... @@ -159,7 +190,7 @@
159 190 top: 50%;
160 191 }
161 192  
162   - @keyframes up {
  193 + @keyframes keyframes_rotate {
163 194 from {
164 195 transform: rotate(0deg);
165 196 }
... ... @@ -208,6 +239,9 @@
208 239 margin: 3em auto;
209 240 }
210 241  
  242 + #time_series svg {
  243 + cursor: crosshair;
  244 + }
211 245 #time_series .help {
212 246 position: absolute;
213 247 text-align: center;
... ... @@ -278,6 +312,7 @@
278 312 .targets-filters .target {
279 313 float: left;
280 314 cursor: pointer;
  315 + position: relative;
281 316 }
282 317 .targets-filters .target:not(.active) {
283 318 -webkit-filter: grayscale(100%);
... ... @@ -308,11 +343,22 @@
308 343 animation-timing-function: linear;
309 344 }
310 345  
311   -{# #orbits {#}
312   -{# background-image: url('{{ static('img/orbitals_background.png') }}');#}
313   -{# background-repeat: repeat;#}
314   -{# background-size: 42%;#}
315   -{# }#}
  346 + .targets-filters .target .decorator {
  347 + position: absolute;
  348 + top: 0;
  349 + left: 0;
  350 + display: none;
  351 + }
  352 + .targets-filters .target.empty .decorator.empty {
  353 + display: block;
  354 + }
  355 + .targets-filters .target .decorator.loading {
  356 + top: 19px;
  357 + left: 19px;
  358 + }
  359 + .targets-filters .target.loading .decorator.loading {
  360 + display: block;
  361 + }
316 362  
317 363 #parameters .parameter {
318 364 outline: 0;
... ... @@ -320,17 +366,158 @@
320 366 #parameters .parameter.active {
321 367 background-color: #c8d3e1;
322 368 }
323   - #time_series svg {
324   - cursor: crosshair;
325   - }
  369 +
  370 +.small-loader-container {
  371 + width: 27px;
  372 + margin: 0 auto;
  373 + background: none;
  374 + pointer-events: none;
  375 +}
  376 +
  377 +.small-loader-circle-1 {
  378 + height: 27px;
  379 + width: 27px;
  380 + background: rgba(255, 238, 195, 0.72);
  381 +}
  382 +
  383 +.small-loader-circle-2 {
  384 + height: 22px;
  385 + width: 22px;
  386 + background: none;
  387 +{# background: rgba(56, 53, 194, 0.5);#}
  388 +}
  389 +
  390 +.small-loader-circle-3 {
  391 + height: 18px;
  392 + width: 18px;
  393 + background: rgba(29, 65, 255, 0.9);
  394 +}
  395 +
  396 +.small-loader-circle-4 {
  397 + height: 13px;
  398 + width: 13px;
  399 + background: none;
  400 +{# background: rgba(98, 109, 237, 0.5);#}
  401 +}
  402 +
  403 +.small-loader-circle-5 {
  404 + height: 9px;
  405 + width: 9px;
  406 + background: rgba(238, 238, 238, 0.8);
  407 +}
  408 +
  409 +.small-loader-circle-6 {
  410 + height: 4px;
  411 + width: 4px;
  412 + background: none;
  413 +{# background: rgba(0, 0, 0, 0);#}
  414 +}
  415 +
  416 +.small-loader-circle-7 {
  417 + height: 2px;
  418 + width: 2px;
  419 + background: rgb(110, 102, 255);
  420 +}
  421 +
  422 +.small-loader-circle-1,
  423 +.small-loader-circle-2,
  424 +.small-loader-circle-3,
  425 +.small-loader-circle-4,
  426 +.small-loader-circle-5,
  427 +.small-loader-circle-6,
  428 +.small-loader-circle-7 {
  429 + border-bottom: none;
  430 + border-radius: 50%;
  431 + -o-border-radius: 50%;
  432 + -ms-border-radius: 50%;
  433 + -webkit-border-radius: 50%;
  434 + -moz-border-radius: 50%;
  435 + box-shadow: 0px 0px 0px rgba(0,0,0,0.1);
  436 + -o-box-shadow: 0px 0px 0px rgba(0,0,0,0.1);
  437 + -ms-box-shadow: 0px 0px 0px rgba(0,0,0,0.1);
  438 + -webkit-box-shadow: 0px 0px 0px rgba(0,0,0,0.1);
  439 + -moz-box-shadow: 0px 0px 0px rgba(0,0,0,0.1);
  440 + animation-name: cssload-spin;
  441 + -o-animation-name: cssload-spin;
  442 + -ms-animation-name: cssload-spin;
  443 + -webkit-animation-name: cssload-spin;
  444 + -moz-animation-name: cssload-spin;
  445 + animation-duration: 4600ms;
  446 + -o-animation-duration: 4600ms;
  447 + -ms-animation-duration: 4600ms;
  448 + -webkit-animation-duration: 4600ms;
  449 + -moz-animation-duration: 4600ms;
  450 + animation-iteration-count: infinite;
  451 + -o-animation-iteration-count: infinite;
  452 + -ms-animation-iteration-count: infinite;
  453 + -webkit-animation-iteration-count: infinite;
  454 + -moz-animation-iteration-count: infinite;
  455 + animation-timing-function: linear;
  456 + -o-animation-timing-function: linear;
  457 + -ms-animation-timing-function: linear;
  458 + -webkit-animation-timing-function: linear;
  459 + -moz-animation-timing-function: linear;
  460 +}
  461 +
  462 +
  463 +
  464 +@keyframes cssload-spin {
  465 + from {
  466 + transform: rotate(0deg);
  467 + }
  468 + to {
  469 + transform: rotate(360deg);
  470 + }
  471 +}
  472 +
  473 +@-o-keyframes cssload-spin {
  474 + from {
  475 + -o-transform: rotate(0deg);
  476 + }
  477 + to {
  478 + -o-transform: rotate(360deg);
  479 + }
  480 +}
  481 +
  482 +@-ms-keyframes cssload-spin {
  483 + from {
  484 + -ms-transform: rotate(0deg);
  485 + }
  486 + to {
  487 + -ms-transform: rotate(360deg);
  488 + }
  489 +}
  490 +
  491 +@-webkit-keyframes cssload-spin {
  492 + from {
  493 + -webkit-transform: rotate(0deg);
  494 + }
  495 + to {
  496 + -webkit-transform: rotate(360deg);
  497 + }
  498 +}
  499 +
  500 +@-moz-keyframes cssload-spin {
  501 + from {
  502 + -moz-transform: rotate(0deg);
  503 + }
  504 + to {
  505 + -moz-transform: rotate(360deg);
  506 + }
  507 +}
  508 +
  509 +
326 510 </style>
327 511 {% endblock %}
328 512  
329 513  
330 514  
  515 +{#### JAVASCRIPT #############################################################}
  516 +
331 517 {% block scripts_footer %}
332 518 <script type="application/javascript" src="{{ static('js/vendor/d3-custom.js') }}"></script>
333 519 <script type="application/javascript" src="{{ static('js/vendor/moment.min.js') }}"></script>
  520 +<script type="application/javascript" src="{{ static('js/vendor/samp.js') }}"></script>
334 521 <script type="application/javascript" src="{{ static('js/swapp.js') }}"></script>
335 522 <script type="application/javascript">
336 523  
... ... @@ -357,7 +544,7 @@ var configuration = {
357 544 {% endfor %}
358 545 },
359 546 {# todo @Nicolas Define -somehow- error margins of each parameter ? #}
360   -{# todo: generate this from config #}
  547 +{# todo: generate this from config PARAMETERS #}
361 548 parameters : [
362 549 {
363 550 id: 'pdyn',
... ... @@ -367,7 +554,7 @@ var configuration = {
367 554 },
368 555 {
369 556 id: 'magn',
370   - title: "Magnetism (nT)",
  557 + title: "B Tangential (nT)",
371 558 active: false,
372 559 unit: "nT"
373 560 },
... ...
web/view/layout.html.jinja2
... ... @@ -16,6 +16,7 @@
16 16 <link rel="shortcut icon" href="{{ static('img/favicon.ico') }}">
17 17  
18 18 <link href="https://fonts.googleapis.com/css?family=Baumans" rel="stylesheet">
  19 + <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
19 20 <link rel="stylesheet" type="text/css" href="{{ static('css/font-awesome.min.css') }}">
20 21 <link rel="stylesheet" type="text/css" href="{{ static('css/material.min.css') }}">
21 22 <link rel="stylesheet" type="text/css" href="{{ static('css/main.css') }}">
... ... @@ -31,7 +32,7 @@
31 32  
32 33 <div id="nojs-alert" class="nojs">Heliopropa requires javascript. </div>
33 34  
34   - <div id="page-container" class="container">
  35 + <div id="page-container" class="mdl-layout mdl-layout--fixed-header container">
35 36  
36 37 <header class="header mdl-layout__header">
37 38 <div class="mdl-layout__header-row">
... ... @@ -60,7 +61,7 @@
60 61 {# </nav>#}
61 62 {# </div>#}
62 63  
63   - <div id="content">
  64 + <div id="content" class="">
64 65 {% block content %}
65 66 <p>Please override the "content" block in the page template.</p>
66 67 {% endblock %}
... ... @@ -99,6 +100,7 @@
99 100 {# </script>#}
100 101  
101 102 <script type="application/javascript" src="{{ static('js/vendor/jquery-3.2.1.min.js') }}"></script>
  103 + <script type="application/javascript" src="{{ static('js/vendor/material-custom.js') }}"></script>
102 104 <script type="application/javascript">
103 105 jQuery().ready(function($){ $(".nojs").hide(); });
104 106 </script>
... ...