OLD | NEW |
1 <!DOCTYPE HTML> | 1 <!DOCTYPE HTML> |
2 <html i18n-values="dir:textdirection;"> | 2 <html i18n-values="dir:textdirection;"> |
3 <head> | 3 <head> |
4 <meta charset="utf-8"> | 4 <meta charset="utf-8"> |
5 <title>Media Player</title> | 5 <title>Media Player</title> |
6 <style type="text/css"> | 6 <style type="text/css"> |
7 | 7 |
8 body { | 8 body { |
9 overflow: hidden; | 9 overflow: hidden; |
10 background: black; | 10 background: black; |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 | 114 |
115 .soundbutton { | 115 .soundbutton { |
116 position: absolute; | 116 position: absolute; |
117 right: 30px; | 117 right: 30px; |
118 bottom: 0; | 118 bottom: 0; |
119 border-left: 1px solid #424242; | 119 border-left: 1px solid #424242; |
120 border-right: 1px solid black; | 120 border-right: 1px solid black; |
121 } | 121 } |
122 | 122 |
123 .soundiconhigh { | 123 .soundiconhigh { |
124 /* background: TODO(serya): Restore mediaplayer_vol_high.png after moving medi
aplayer to extension. */ | 124 background: url('images/mediaplayer_vol_high.png'); |
125 } | 125 } |
126 | 126 |
127 .soundiconmuted { | 127 .soundiconmuted { |
128 /* background: TODO(serya): Restore mediaplayer_vol_mute.png after moving medi
aplayer to extension. */ | 128 background: url('images/mediaplayer_vol_mute.png'); |
129 } | 129 } |
130 | 130 |
131 .soundiconhigh, | 131 .soundiconhigh, |
132 .soundiconmuted { | 132 .soundiconmuted { |
133 background-repeat: no-repeat; | 133 background-repeat: no-repeat; |
134 background-position: 6px 8px; | 134 background-position: 6px 8px; |
135 } | 135 } |
136 | 136 |
137 .volume { | 137 .volume { |
138 position: absolute; | 138 position: absolute; |
139 bottom: 30px; | 139 bottom: 30px; |
140 height: 80px; | 140 height: 80px; |
141 width: 30px; | 141 width: 30px; |
142 right: 30px; | 142 right: 30px; |
143 z-index: 99999; | 143 z-index: 99999; |
144 background: black; | 144 background: black; |
145 background: -webkit-linear-gradient(#323232, #070707); | 145 background: -webkit-linear-gradient(#323232, #070707); |
146 } | 146 } |
147 | 147 |
148 .fullscreen { | 148 .fullscreen { |
149 position: absolute; | 149 position: absolute; |
150 right: 60px; | 150 right: 60px; |
151 bottom: 0; | 151 bottom: 0; |
152 border-left: 1px solid #424242; | 152 border-left: 1px solid #424242; |
153 border-right: 1px solid black; | 153 border-right: 1px solid black; |
154 } | 154 } |
155 | 155 |
156 .fullscreenicon { | 156 .fullscreenicon { |
157 /* background: TODO(serya): Restore mediaplayer_full_screen.png after moving m
ediaplayer to extension. */ | 157 background: url('images/mediaplayer_full_screen.png'); |
158 background-repeat: no-repeat; | 158 background-repeat: no-repeat; |
159 background-position: 6px 8px; | 159 background-position: 6px 8px; |
160 } | 160 } |
161 | 161 |
162 .fullscreenexiticon { | 162 .fullscreenexiticon { |
163 /* background: TODO(serya): Restore mediaplayer_full_screen_exit.png after mov
ing mediaplayer to extension. */ | 163 background: url('images/mediaplayer_full_screen_exit.png'); |
164 background-repeat: no-repeat; | 164 background-repeat: no-repeat; |
165 background-position: 6px 8px; | 165 background-position: 6px 8px; |
166 } | 166 } |
167 | 167 |
168 .volumeslider { | 168 .volumeslider { |
169 -webkit-appearance: slider-vertical; | 169 -webkit-appearance: slider-vertical; |
170 position: absolute; | 170 position: absolute; |
171 left: 0; | 171 left: 0; |
172 right: 0; | 172 right: 0; |
173 bottom: 0; | 173 bottom: 0; |
174 top: 0; | 174 top: 0; |
175 } | 175 } |
176 | 176 |
177 .playbutton { | 177 .playbutton { |
178 position: absolute; | 178 position: absolute; |
179 left: 30px; | 179 left: 30px; |
180 bottom: 0; | 180 bottom: 0; |
181 border-left: 1px solid #424242; | 181 border-left: 1px solid #424242; |
182 border-right: 1px solid black; | 182 border-right: 1px solid black; |
183 } | 183 } |
184 | 184 |
185 .playicon { | 185 .playicon { |
186 /* background: TODO(serya): Restore mediaplayer_play.png after moving mediapla
yer to extension. */ | 186 background: url('images/mediaplayer_play.png'); |
187 background-repeat: no-repeat; | 187 background-repeat: no-repeat; |
188 background-position: 9px 8px; | 188 background-position: 9px 8px; |
189 } | 189 } |
190 | 190 |
191 .pausebutton { | 191 .pausebutton { |
192 position: absolute; | 192 position: absolute; |
193 left: 30px; | 193 left: 30px; |
194 bottom: 0; | 194 bottom: 0; |
195 border-left: 1px solid #424242; | 195 border-left: 1px solid #424242; |
196 border-right: 1px solid black; | 196 border-right: 1px solid black; |
197 } | 197 } |
198 | 198 |
199 .pauseicon { | 199 .pauseicon { |
200 /* background: Restore mediaplayer_pause.png after moving mediaplayer to exten
sion. */ | 200 background: url('images/mediaplayer_pause.png'); |
201 background-repeat: no-repeat; | 201 background-repeat: no-repeat; |
202 background-position: 9px 8px; | 202 background-position: 9px 8px; |
203 } | 203 } |
204 | 204 |
205 .prevbutton { | 205 .prevbutton { |
206 position: absolute; | 206 position: absolute; |
207 left: 0; | 207 left: 0; |
208 bottom: 0; | 208 bottom: 0; |
209 border-right: 1px solid black; | 209 border-right: 1px solid black; |
210 } | 210 } |
211 | 211 |
212 .previcon { | 212 .previcon { |
213 /* background: TODO(serya): Restore mediaplayer_prev.png after moving mediapla
yer to extension. */ | 213 background: url('images/mediaplayer_prev.png'); |
214 background-repeat: no-repeat; | 214 background-repeat: no-repeat; |
215 background-position: 6px 8px; | 215 background-position: 6px 8px; |
216 } | 216 } |
217 | 217 |
218 .playbackvideoelement { | 218 .playbackvideoelement { |
219 width: 100%; | 219 width: 100%; |
220 height: 100%; | 220 height: 100%; |
221 position: absolute; | 221 position: absolute; |
222 left: 0; | 222 left: 0; |
223 top: 0; | 223 top: 0; |
(...skipping 19 matching lines...) Expand all Loading... |
243 | 243 |
244 .nextbutton { | 244 .nextbutton { |
245 position: absolute; | 245 position: absolute; |
246 left: 60px; | 246 left: 60px; |
247 bottom: 0; | 247 bottom: 0; |
248 border-left: 1px solid #424242; | 248 border-left: 1px solid #424242; |
249 border-right: 1px solid black; | 249 border-right: 1px solid black; |
250 } | 250 } |
251 | 251 |
252 .nexticon { | 252 .nexticon { |
253 /* background: TODO(serya): Restore mediaplayer_next.png after moving mediapla
yer to extension. */ | 253 background: url('images/mediaplayer_next.png'); |
254 background-repeat: no-repeat; | 254 background-repeat: no-repeat; |
255 background-position: 6px 8px; | 255 background-position: 6px 8px; |
256 } | 256 } |
257 | 257 |
258 .playlistbutton { | 258 .playlistbutton { |
259 position: absolute; | 259 position: absolute; |
260 right: 0; | 260 right: 0; |
261 bottom: 0; | 261 bottom: 0; |
262 border-left: 1px solid #424242; | 262 border-left: 1px solid #424242; |
263 border-right: 1px solid black; | 263 border-right: 1px solid black; |
264 } | 264 } |
265 | 265 |
266 .playlisticon { | 266 .playlisticon { |
267 /* background: TODO(serya): Restore mediaplayer_playlist.png after moving medi
aplayer to extension. */ | 267 background: url('images/mediaplayer_playlist.png'); |
268 background-repeat: no-repeat; | 268 background-repeat: no-repeat; |
269 background-position: 6px 8px; | 269 background-position: 6px 8px; |
270 } | 270 } |
271 | 271 |
272 .controlbutton { | 272 .controlbutton { |
273 z-index: 9999; | 273 z-index: 9999; |
274 cursor: pointer; | 274 cursor: pointer; |
275 width: 28px; | 275 width: 28px; |
276 height: 30px; | 276 height: 30px; |
277 } | 277 } |
278 | 278 |
279 .controlbutton:hover { | 279 .controlbutton:hover { |
280 background: -webkit-linear-gradient(#6a7eac, #000); | 280 background: -webkit-linear-gradient(#6a7eac, #000); |
281 } | 281 } |
282 | 282 |
283 .icon { | 283 .icon { |
284 width: 100%; | 284 width: 100%; |
285 height: 100%; | 285 height: 100%; |
286 z-index: 9999; | 286 z-index: 9999; |
287 } | 287 } |
288 | 288 |
289 </style> | 289 </style> |
290 <script src="shared/js/local_strings.js"></script> | 290 <script src="chrome://resources/js/local_strings.js"></script> |
291 <script src="shared/js/media_common.js"></script> | 291 <script src="chrome://resources/js/media_common.js"></script> |
292 <script> | 292 <script> |
293 | 293 |
294 function $(o) { | 294 function $(o) { |
295 return document.getElementById(o); | 295 return document.getElementById(o); |
296 } | 296 } |
297 | 297 |
298 var videoPlaybackElement = null; | 298 var videoPlaybackElement = null; |
299 var audioPlaybackElement = null; | 299 var audioPlaybackElement = null; |
300 var currentPlaylist = null; | 300 var currentPlaylist = null; |
301 var currentItem = -1; | 301 var currentItem = -1; |
302 var savedVolumeValue = 0; | 302 var savedVolumeValue = 0; |
303 var hideVolumeTimerId = 0; | 303 var hideVolumeTimerId = 0; |
304 var localStrings; | 304 var localStrings; |
305 var fullScreen = false; | 305 var fullScreen = false; |
306 | 306 |
307 /////////////////////////////////////////////////////////////////////////////// | 307 /////////////////////////////////////////////////////////////////////////////// |
308 // Document Functions: | 308 // Document Functions: |
309 /** | 309 /** |
310 * Window onload handler, sets up the page. | 310 * Window onload handler, sets up the page. |
311 */ | 311 */ |
312 function load() { | 312 function load() { |
| 313 chrome.fileBrowserPrivate.getStrings(function(strings) { |
| 314 localStrings = new LocalStrings(strings); |
| 315 |
| 316 init(); |
| 317 }); |
| 318 } |
| 319 |
| 320 function init() { |
313 document.body.addEventListener('dragover', function(e) { | 321 document.body.addEventListener('dragover', function(e) { |
314 if (e.preventDefault) e.preventDefault(); | 322 if (e.preventDefault) e.preventDefault(); |
315 }); | 323 }); |
316 document.body.addEventListener('drop', function(e) { | 324 document.body.addEventListener('drop', function(e) { |
317 if (e.preventDefault) e.preventDefault(); | 325 if (e.preventDefault) e.preventDefault(); |
318 }); | 326 }); |
319 document.body.addEventListener('keydown', onkeydown); | 327 document.body.addEventListener('keydown', onkeydown); |
320 | 328 |
321 localStrings = new LocalStrings(); | 329 chrome.mediaPlayerPrivate.getPlaylist(true, getPlaylistCallback); |
322 chrome.send('getCurrentPlaylist', []); | 330 |
| 331 chrome.mediaPlayerPrivate.onPlaylistChanged.addListener(function() { |
| 332 chrome.mediaPlayerPrivate.getPlaylist(true, getPlaylistCallback); |
| 333 }); |
323 } | 334 } |
324 | 335 |
325 function onMediaProgress() { | 336 function onMediaProgress() { |
326 var element = getMediaElement(); | 337 var element = getMediaElement(); |
327 var current = element.currentTime; | 338 var current = element.currentTime; |
328 var duration = element.duration; | 339 var duration = element.duration; |
329 var progress = $('progress'); | 340 var progress = $('progress'); |
330 progress.value = (current*100)/duration; | 341 progress.value = (current*100)/duration; |
331 var played = $('sliderplayed'); | 342 var played = $('sliderplayed'); |
332 played.style.width = '' + progress.value + '%'; | 343 played.style.width = '' + progress.value + '%'; |
333 if (progress.value == 100) { | 344 if (progress.value == 100) { |
334 onMediaComplete(); | 345 onMediaComplete(); |
335 } | 346 } |
336 } | 347 } |
337 | 348 |
338 function onLoadedProgress(e) { | 349 function onLoadedProgress(e) { |
339 var element = $('sliderloaded'); | 350 var element = $('sliderloaded'); |
340 if (e.lengthComputable) { | 351 if (e.lengthComputable) { |
341 element.style.display = 'block'; | 352 element.style.display = 'block'; |
342 var percent = (e.loaded * 100) / e.total; | 353 var percent = (e.loaded * 100) / e.total; |
343 element.style.width = '' + percent + '%'; | 354 element.style.width = '' + percent + '%'; |
344 } else { | 355 } else { |
345 element.style.display = 'none'; | 356 element.style.display = 'none'; |
346 } | 357 } |
347 } | 358 } |
348 | 359 |
349 function onMediaError(e) { | 360 function onMediaError(e) { |
350 console.log('Got new error'); | 361 console.log('Got new error'); |
351 console.log(e); | 362 console.log(e); |
352 chrome.send('playbackError', ['Error playing back', | 363 chrome.mediaPlayerPrivate.setPlaybackError(currentPlaylist[currentItem].path); |
353 currentPlaylist[currentItem].path]); | |
354 if (currentPlaylist.length == 1) { | 364 if (currentPlaylist.length == 1) { |
355 $('error').textContent = localStrings.getString('errorstring'); | 365 $('error').textContent = localStrings.getString('PLAYBACK_ERROR'); |
356 } else { | 366 } else { |
357 chrome.send("showPlaylist", []); | 367 chrome.mediaPlayerPrivate.togglePlaylistPanel(); |
358 } | 368 } |
359 onMediaComplete(); | 369 onMediaComplete(); |
360 } | 370 } |
361 | 371 |
362 function onMediaComplete() { | 372 function onMediaComplete() { |
363 currentItem ++; | 373 currentItem ++; |
364 if (currentItem >= currentPlaylist.length) { | 374 if (currentItem >= currentPlaylist.length) { |
365 currentItem -= 1; | 375 currentItem -= 1; |
366 var element = getMediaElement(); | 376 var element = getMediaElement(); |
367 if (!getMediaElement().error) { | 377 if (!getMediaElement().error) { |
368 element.currentTime = 0; | 378 element.currentTime = 0; |
369 element.pause(); | 379 element.pause(); |
370 onMediaProgress(); | 380 onMediaProgress(); |
371 } | 381 } |
372 onMediaPause(); | 382 onMediaPause(); |
373 return; | 383 return; |
374 } | 384 } |
375 var mediaElement = getMediaElement(); | 385 var mediaElement = getMediaElement(); |
376 mediaElement.removeEventListener("progress", onLoadedProgress, true); | 386 mediaElement.removeEventListener("progress", onLoadedProgress, true); |
377 mediaElement.removeEventListener("timeupdate", onMediaProgress, true); | 387 mediaElement.removeEventListener("timeupdate", onMediaProgress, true); |
378 mediaElement.removeEventListener("durationchange", onMetadataAvail, true); | 388 mediaElement.removeEventListener("durationchange", onMetadataAvail, true); |
379 // MediaElement.removeEventListener("ended", onMediaComplete, true); | 389 // MediaElement.removeEventListener("ended", onMediaComplete, true); |
380 mediaElement.removeEventListener("play", onMediaPlay, true); | 390 mediaElement.removeEventListener("play", onMediaPlay, true); |
381 mediaElement.removeEventListener("pause", onMediaPause, true); | 391 mediaElement.removeEventListener("pause", onMediaPause, true); |
382 mediaElement.onerror = undefined; | 392 mediaElement.onerror = undefined; |
383 chrome.send('currentOffsetChanged', ['' + currentItem]); | 393 chrome.mediaPlayerPrivate.playAt(currentItem); |
384 playMediaFile(currentPlaylist[currentItem].path); | |
385 } | 394 } |
386 | 395 |
387 function onMediaPlay() { | 396 function onMediaPlay() { |
388 var pausebutton = $('pausebutton'); | 397 var pausebutton = $('pausebutton'); |
389 var playbutton = $('playbutton'); | 398 var playbutton = $('playbutton'); |
390 pausebutton.style.display = 'block'; | 399 pausebutton.style.display = 'block'; |
391 playbutton.style.display = 'none'; | 400 playbutton.style.display = 'none'; |
392 } | 401 } |
393 | 402 |
394 function onMediaPause() { | 403 function onMediaPause() { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 var element = getMediaElement(); | 443 var element = getMediaElement(); |
435 if (element.currentTime > 6) { | 444 if (element.currentTime > 6) { |
436 element.currentTime = 0; | 445 element.currentTime = 0; |
437 return; | 446 return; |
438 } | 447 } |
439 currentItem --; | 448 currentItem --; |
440 if (currentItem < 0) { | 449 if (currentItem < 0) { |
441 currentItem = -1; | 450 currentItem = -1; |
442 return; | 451 return; |
443 } | 452 } |
444 chrome.send('currentOffsetChanged', ['' + currentItem]); | 453 chrome.mediaPlayerPrivate.playAt(currentItem); |
445 playMediaFile(currentPlaylist[currentItem].path); | 454 playMediaFile(currentPlaylist[currentItem].path); |
446 } | 455 } |
447 | 456 |
448 function nextButtonClick() { | 457 function nextButtonClick() { |
449 currentItem ++; | 458 currentItem ++; |
450 if (currentItem >= currentPlaylist.length) { | 459 if (currentItem >= currentPlaylist.length) { |
451 currentItem = -1; | 460 currentItem = -1; |
452 return; | 461 return; |
453 } | 462 } |
454 chrome.send('currentOffsetChanged', ['' + currentItem]); | 463 chrome.mediaPlayerPrivate.playAt(currentItem); |
455 playMediaFile(currentPlaylist[currentItem].path); | 464 playMediaFile(currentPlaylist[currentItem].path); |
456 } | 465 } |
457 | 466 |
458 function userChangedProgress() { | 467 function userChangedProgress() { |
459 var val = $('progress').value; | 468 var val = $('progress').value; |
460 var element = getMediaElement(); | 469 var element = getMediaElement(); |
461 if (element.seekable && element.duration) { | 470 if (element.seekable && element.duration) { |
462 var current = (progress.value * element.duration)/100; | 471 var current = (progress.value * element.duration)/100; |
463 element.currentTime = current; | 472 element.currentTime = current; |
464 } | 473 } |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
769 fullScreen = !fullScreen; | 778 fullScreen = !fullScreen; |
770 var fullscreenicon = $('fullscreenicon'); | 779 var fullscreenicon = $('fullscreenicon'); |
771 if (fullScreen) { | 780 if (fullScreen) { |
772 fullscreenicon.classList.remove('fullscreenicon'); | 781 fullscreenicon.classList.remove('fullscreenicon'); |
773 fullscreenicon.classList.add('fullscreenexiticon'); | 782 fullscreenicon.classList.add('fullscreenexiticon'); |
774 } | 783 } |
775 else { | 784 else { |
776 fullscreenicon.classList.remove('fullscreenexiticon'); | 785 fullscreenicon.classList.remove('fullscreenexiticon'); |
777 fullscreenicon.classList.add('fullscreenicon'); | 786 fullscreenicon.classList.add('fullscreenicon'); |
778 } | 787 } |
779 chrome.send('toggleFullscreen', ['']); | 788 chrome.mediaPlayerPrivate.toggleFullscreen(); |
780 } | 789 } |
781 | 790 |
782 function onMetadataAvail() { | 791 function onMetadataAvail() { |
783 var element = getMediaElement(); | 792 var element = getMediaElement(); |
784 var duration = element.duration; | 793 var duration = element.duration; |
785 if (duration) { | 794 if (duration) { |
786 var durString = '' + Math.floor((duration / 60)) + ':' + (Math.floor(duratio
n) % 60); | 795 var durString = '' + Math.floor((duration / 60)) + ':' + (Math.floor(duratio
n) % 60); |
787 var durDiv = $('duration'); | 796 var durDiv = $('duration'); |
788 durDiv.textContent = durString; | 797 durDiv.textContent = durString; |
789 } | 798 } |
(...skipping 28 matching lines...) Expand all Loading... |
818 } | 827 } |
819 } | 828 } |
820 | 829 |
821 function stopAllPlayback() { | 830 function stopAllPlayback() { |
822 var element = getMediaElement(); | 831 var element = getMediaElement(); |
823 if (element != null) { | 832 if (element != null) { |
824 element.pause(); | 833 element.pause(); |
825 } | 834 } |
826 } | 835 } |
827 | 836 |
828 function playlistChanged(info, playlist) { | 837 function getPlaylistCallback(playlist) { |
829 if (info.force) { | 838 currentPlaylist = playlist.items; |
830 currentPlaylist = playlist; | 839 currentItem = playlist.position; |
831 stopAllPlayback(); | 840 |
832 if (playlist.length >= 1) { | 841 if (playlist.pendingPlaybackRequest) { |
833 if (info.currentOffset) { | 842 playMediaFile(currentPlaylist[currentItem].path); |
834 currentItem = info.currentOffset; | |
835 } else { | |
836 currentItem = 0; | |
837 } | |
838 var item = playlist[currentItem]; | |
839 chrome.send('currentOffsetChanged', ['' + currentItem]); | |
840 playMediaFile(item.path); | |
841 } | |
842 } else { | |
843 var media = getMediaElement(); | |
844 currentPlaylist = playlist; | |
845 // Only need to handle the case where we are not playing | |
846 // since if it is currently playing, it will just move | |
847 // to the next file when the current is complete. | |
848 if (media == null) { | |
849 for (var x = 0; x < playlist.length; x++) { | |
850 if (playlist[x].path == info.path) { | |
851 // found the newly added item. | |
852 currentItem = x; | |
853 chrome.send('currentOffsetChanged', ['' + currentItem]); | |
854 playMediaFile(playlist[x].path); | |
855 return; | |
856 } | |
857 } | |
858 if (playlist.length > 0) { | |
859 currentItem = 0; | |
860 chrome.send('currentOffsetChanged', ['' + currentItem]); | |
861 playMediaFile(playlist[0].path); | |
862 } | |
863 } | |
864 } | 843 } |
865 } | 844 } |
866 | 845 |
867 function togglePlaylist() { | 846 function togglePlaylist() { |
868 chrome.send("togglePlaylist", []); | 847 chrome.mediaPlayerPrivate.togglePlaylistPanel(); |
869 } | 848 } |
870 | 849 |
871 function playMediaFile(url) { | 850 function playMediaFile(url) { |
872 $('error').textContent = ''; | 851 $('error').textContent = ''; |
873 console.log('playfile '+url); | |
874 $('title').textContent = ''; | 852 $('title').textContent = ''; |
875 if (pathIsVideoFile(url) ) { | 853 if (pathIsVideoFile(url) ) { |
876 playVideoFile(url); | 854 playVideoFile(url); |
877 } else if(pathIsAudioFile(url)) { | 855 } else if(pathIsAudioFile(url)) { |
878 playAudioFile(url); | 856 playAudioFile(url); |
879 } else { | 857 } else { |
880 alert('file unknown:' + url); | 858 alert('file unknown:' + url); |
881 } | 859 } |
882 } | 860 } |
883 | 861 |
884 </script> | 862 </script> |
885 <body onload='load();' onselectstart='return false'> | 863 <body onload='load();' onselectstart='return false'> |
886 <div id='error' class='error'></div> | 864 <div id='error' class='error'></div> |
887 <div id='title' class='audiotitle'></div> | 865 <div id='title' class='audiotitle'></div> |
888 <div id='glow' class='glow'></div> | 866 <div id='glow' class='glow'></div> |
889 <div class='playercontrolsbox'> | 867 <div class='playercontrolsbox'> |
890 <div id='playercontrols'> | 868 <div id='playercontrols'> |
891 </div> | 869 </div> |
892 </div> | 870 </div> |
893 </body> | 871 </body> |
894 </html> | 872 </html> |
OLD | NEW |