network_executive 0.0.4 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. data/README.md +53 -24
  2. data/app/assets/fonts/network_executive/league_gothic.css +13 -0
  3. data/app/assets/fonts/network_executive/league_gothic.svg +148 -0
  4. data/app/assets/fonts/network_executive/league_gothic.ttf +0 -0
  5. data/app/assets/fonts/network_executive/league_gothic.woff +0 -0
  6. data/app/assets/javascripts/network_executive/components/iframe_notifier.coffee +14 -0
  7. data/app/assets/javascripts/network_executive/components/namespace.coffee +1 -0
  8. data/app/assets/javascripts/network_executive/components/osd.coffee +65 -0
  9. data/app/assets/javascripts/network_executive/components/photo_player.coffee +55 -0
  10. data/app/assets/javascripts/network_executive/components/postman.coffee +23 -0
  11. data/app/assets/javascripts/network_executive/components/set_top_box.coffee +81 -0
  12. data/app/assets/javascripts/network_executive/components/tweet_player.coffee +95 -0
  13. data/app/assets/javascripts/network_executive/components/you_tube_player.coffee +85 -0
  14. data/app/assets/javascripts/network_executive/slideshow.coffee +6 -0
  15. data/app/assets/javascripts/network_executive/twitter.coffee +7 -0
  16. data/app/assets/javascripts/network_executive/you_tube.coffee +8 -0
  17. data/app/assets/javascripts/network_executive.coffee +10 -0
  18. data/app/assets/stylesheets/network_executive/{gui_components.css → components/gui_components.css} +0 -0
  19. data/app/assets/stylesheets/network_executive/{normalize.css → components/normalize.css} +0 -0
  20. data/app/assets/stylesheets/network_executive/{osd.css → components/osd.css} +6 -34
  21. data/app/assets/stylesheets/network_executive/components/osd_guide.css +43 -0
  22. data/app/assets/stylesheets/network_executive/components/photo_player.css +61 -0
  23. data/app/assets/stylesheets/network_executive/{smpte.css → components/smpte.css} +0 -0
  24. data/app/assets/stylesheets/network_executive/components/tweet_player.css +60 -0
  25. data/app/assets/stylesheets/network_executive/components/you_tube_player.css +12 -0
  26. data/app/assets/stylesheets/network_executive/off_air.css +5 -0
  27. data/app/assets/stylesheets/network_executive/slideshow.css +4 -0
  28. data/app/assets/stylesheets/network_executive/twitter.css +5 -0
  29. data/app/assets/stylesheets/network_executive/you_tube.css +3 -0
  30. data/app/assets/stylesheets/{network_executive/application.css → network_executive.css} +5 -5
  31. data/app/controllers/network_executive/components_controller.rb +4 -0
  32. data/app/controllers/network_executive/guide_controller.rb +41 -0
  33. data/app/controllers/network_executive/programs_controller.rb +9 -0
  34. data/app/helpers/network_executive/network_helper.rb +6 -0
  35. data/app/models/network_executive/channel.rb +15 -14
  36. data/app/models/network_executive/guide.rb +65 -0
  37. data/app/models/network_executive/program.rb +69 -5
  38. data/app/models/network_executive/viewer.rb +4 -0
  39. data/app/programs/network_executive/off_air.rb +18 -0
  40. data/app/views/network_executive/components/slideshow.html.erb +20 -0
  41. data/app/views/network_executive/components/twitter.html.erb +16 -0
  42. data/app/views/network_executive/components/you_tube.html.erb +13 -0
  43. data/app/views/network_executive/guide/index.html.erb +30 -0
  44. data/app/views/network_executive/network/index.html.erb +3 -3
  45. data/app/views/network_executive/programs/off_air.html.erb +13 -0
  46. data/config/routes.rb +7 -1
  47. data/lib/network_executive/channel_schedule.rb +65 -0
  48. data/lib/network_executive/components/photo_player.rb +48 -0
  49. data/lib/network_executive/components/tweet_player.rb +48 -0
  50. data/lib/network_executive/components/you_tube_player.rb +15 -0
  51. data/lib/network_executive/components.rb +3 -0
  52. data/lib/network_executive/engine.rb +29 -3
  53. data/lib/network_executive/off_air_schedule.rb +18 -0
  54. data/lib/network_executive/producer.rb +3 -3
  55. data/lib/network_executive/program_schedule.rb +96 -0
  56. data/lib/network_executive/program_schedule_proxy.rb +55 -0
  57. data/lib/network_executive/scheduled_program.rb +26 -0
  58. data/lib/network_executive/scheduling.rb +15 -21
  59. data/lib/network_executive/time_calculations.rb +10 -0
  60. data/lib/network_executive/version.rb +1 -1
  61. data/lib/network_executive.rb +2 -1
  62. data/network_executive.gemspec +5 -0
  63. data/spec/models/channel_spec.rb +30 -12
  64. data/spec/models/{lineup_spec.rb → guide_spec.rb} +28 -6
  65. data/spec/models/program_spec.rb +46 -3
  66. data/spec/models/viewer_spec.rb +9 -1
  67. data/spec/programs/off_air_spec.rb +9 -0
  68. data/spec/spec_helper.rb +3 -2
  69. data/spec/unit/channel_schedule_spec.rb +67 -0
  70. data/spec/unit/components/photo_player_spec.rb +76 -0
  71. data/spec/unit/components/tweet_player_spec.rb +68 -0
  72. data/spec/unit/components/you_tube_player_spec.rb +17 -0
  73. data/spec/unit/off_air_schedule_spec.rb +28 -0
  74. data/spec/unit/producer_spec.rb +2 -4
  75. data/spec/unit/program_schedule_proxy_spec.rb +102 -0
  76. data/spec/unit/program_schedule_spec.rb +191 -0
  77. data/spec/unit/scheduled_program_spec.rb +57 -0
  78. data/spec/unit/scheduling_spec.rb +61 -72
  79. data/vendor/assets/javascripts/bigtext.js +264 -0
  80. metadata +185 -44
  81. data/app/assets/javascripts/application.js +0 -13
  82. data/app/assets/javascripts/network_executive/osd.js +0 -62
  83. data/app/assets/javascripts/network_executive/set_top_box.js +0 -45
  84. data/app/controllers/network_executive/lineup_controller.rb +0 -11
  85. data/app/models/network_executive/channel_schedule.rb +0 -13
  86. data/app/models/network_executive/lineup.rb +0 -74
  87. data/app/models/network_executive/lineup_range.rb +0 -34
  88. data/app/models/network_executive/program_schedule.rb +0 -148
  89. data/app/views/network_executive/lineup/index.html.erb +0 -26
  90. data/spec/models/channel_schedule_spec.rb +0 -29
  91. data/spec/models/lineup_range_spec.rb +0 -65
  92. data/spec/models/program_schedule_spec.rb +0 -399
data/README.md CHANGED
@@ -20,15 +20,59 @@ Run the installation script:
20
20
 
21
21
  $ rails g network_executive:install
22
22
 
23
+ If you experience lots of deadlock errors in production, you'll want to enabled
24
+ threaded mode in your Rails application.
25
+
26
+ All you have to do is uncomment the following line:
27
+
28
+ ```ruby
29
+ # config/environments/production.rb
30
+ # Enable threaded mode
31
+ config.threadsafe!
32
+ ```
33
+
34
+ Tenderlove has an interesting [blog post][tender_love] if you'd like to learn more.
35
+
23
36
  All that's left is to start building your network!
24
37
 
25
- ## Usage
38
+ # Ideas
26
39
 
27
- $ net_exec server
40
+ * _EAS_ - Allow a channel to break into the schedule to display important content
41
+ * _Ticker_ - Allow a separate feed of info. Tweets, metrics, WOWs, etc.
42
+ * _Network Logo_ - Useful?
43
+ * _Commericals / PSAs_ - The More You Know?
44
+ * _Set Top Box_ - The client-side component. SSEs?
45
+ * _On-Screen Guide_ - Client-side slide out remote to change channels/networks?
46
+ * _On-Demand_ - Change to and stay at a specific channel. "Live" to exit.
28
47
 
29
48
  ## Network
30
49
 
31
- A class that represents a server instance. This is what holds the channel-line up and serves content to the browser.
50
+ A class that represents a server instance. This is what holds the channel-line
51
+ up and serves content to the browser.
52
+
53
+ ## Channel
54
+
55
+ A class that represents a list of schedule programming and a client-side endpoint.
56
+
57
+ Navigating to a channel URL will "tune in" the viewer into the specified channel
58
+ and content will be pushed to the browser.
59
+
60
+ ## Program
61
+
62
+ A class that represents content to display to the user.
63
+
64
+ A program needs to have at least a URL to navigate the browser to.
65
+
66
+ ## Set Top Box
67
+
68
+ The Set Top Box represents the client-side code that drives the whole end user
69
+ experience.
70
+
71
+ ## On-Screen Guide
72
+
73
+ The On-Screen Guide allows a viewer access to the entire Network.
74
+
75
+ This provides an easy way to change channels.
32
76
 
33
77
  ### EAS
34
78
 
@@ -61,37 +105,19 @@ Commercials provide a fun and interesting way to break up the monotony of viewin
61
105
  The scheduling of commercials is determined by how many commercials are defined and long each program runs for. By default,
62
106
  commercial breaks are taken twice for each 30-minute block of programming.
63
107
 
64
- ## Viewer
65
-
66
- The viewer represents the client-side code that drives the whole end user experience.
67
-
68
- ## On-Screen Guide
69
-
70
- The On-Screen Guide allows a viewer access to the entire Network. This provides an easy way to change channels.
71
-
72
108
  ### On-Demand
73
109
 
74
- On-Demand is an On-Screen Guide feature that allows a viewer to continuously view one specific channel until further notice.
110
+ On-Demand is an On-Screen Guide feature that allows a viewer to continuously
111
+ view one specific channel until further notice.
75
112
 
76
113
  While commercials are ignored, EAS messages will still pre-empt programming.
77
114
 
78
- # Ideas
79
-
80
- * _Network_ - An server instance with a specific channel line-up. Think Tech vs. Sales vs. Marketing
81
- * _Channel Line-up_ - A JSON/YML file that defines URLs and display times
82
- * _EAS_ - Allow a channel to break into the schedule to display important content
83
- * _Ticker_ - Allow a separate feed of info. Tweets, metrics, WOWs, etc.
84
- * _Network Logo_ - Useful?
85
- * _Commericals / PSAs_ - The More You Know?
86
- * _Viewer_ - The client-side component. SSEs?
87
- * _Clicker_ - Client-side slide out remote to change channels/networks?
88
- * _On-Demand_ - Change to and stay at a specific channel. "Live" to exit.* _On-Demand_ - Change to and stay at a specific channel. "Live" to exit.1
89
-
90
115
  ## TODO
91
116
 
92
117
  * Raise an exception if there are no channels to ease bootstrapping for new users
93
118
  * Swap out jQuery for Zepto?
94
119
  * Add http://brad.is/coding/BigScreen/
120
+ * Should the installation generator turn on threaded mode?
95
121
 
96
122
  ## Contributing
97
123
 
@@ -100,3 +126,6 @@ While commercials are ignored, EAS messages will still pre-empt programming.
100
126
  3. Commit your changes (`git commit -am 'Add some feature'`)
101
127
  4. Push to the branch (`git push origin my-new-feature`)
102
128
  5. Create new Pull Request
129
+
130
+ [tender_love]: http://tenderlovemaking.com/2012/06/18/removing-config-threadsafe.html
131
+
@@ -0,0 +1,13 @@
1
+ /* Generated by Font Squirrel (http://www.fontsquirrel.com) on October 1, 2012 08:58:00 PM America/New_York */
2
+
3
+
4
+
5
+ @font-face {
6
+ font-family: 'LeagueGothicRegular';
7
+ src: url('league_gothic.woff') format('woff'),
8
+ url('league_gothic.ttf') format('truetype'),
9
+ url('league_gothic.svg#LeagueGothicRegular') format('svg');
10
+ font-weight: normal;
11
+ font-style: normal;
12
+ }
13
+
@@ -0,0 +1,148 @@
1
+ <?xml version="1.0" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3
+ <svg xmlns="http://www.w3.org/2000/svg">
4
+ <metadata>
5
+ This is a custom SVG webfont generated by Font Squirrel.
6
+ Copyright : Generated in 2009 by FontLab Studio Copyright info pending
7
+ </metadata>
8
+ <defs>
9
+ <font id="webfontFHzvtkso" horiz-adv-x="686" >
10
+ <font-face units-per-em="2048" ascent="1505" descent="-543" />
11
+ <missing-glyph horiz-adv-x="315" />
12
+ <glyph unicode=" " horiz-adv-x="315" />
13
+ <glyph unicode="&#x09;" horiz-adv-x="315" />
14
+ <glyph unicode="&#xa0;" horiz-adv-x="315" />
15
+ <glyph unicode="!" horiz-adv-x="387" d="M74 1505h239l-55 -1099h-129zM86 0v227h215v-227h-215z" />
16
+ <glyph unicode="&#x22;" horiz-adv-x="329" d="M57 1505h215l-30 -551h-154z" />
17
+ <glyph unicode="#" horiz-adv-x="1232" d="M49 438l27 195h198l37 258h-196l26 194h197l57 420h197l-57 -420h260l57 420h197l-58 -420h193l-27 -194h-192l-37 -258h190l-26 -195h-191l-59 -438h-197l60 438h-261l-59 -438h-197l60 438h-199zM471 633h260l37 258h-260z" />
18
+ <glyph unicode="$" horiz-adv-x="692" d="M37 358l192 13q12 -186 129 -187q88 0 93 185q0 29 -8.5 59.5t-19.5 55t-32.5 60.5t-34.5 53l-40 55q-28 38 -35 50q-68 92 -101 141.5t-70.5 141.5t-37.5 170q4 293 215 342v131h123v-125q201 -23 235 -282l-192 -25q-6 57 -28 92t-65 33q-80 -2 -84 -162 q0 -29 8.5 -60.5t18.5 -54t32.5 -59.5t34.5 -53l41 -59q30 -42 38 -52q6 -10 32 -48l37 -52q10 -14 33.5 -51t34.5 -58l26 -55q16 -35 23.5 -61.5t13.5 -60.5t6 -64q-4 -338 -245 -369v-217h-123v221q-236 41 -250 352z" />
19
+ <glyph unicode="%" horiz-adv-x="1001" d="M55 911v437q0 6 1 18t9.5 42t23.5 53.5t48 42t78 18.5q70 0 110 -44t44 -87l4 -43v-437q0 -6 -1 -18t-9.5 -43t-23.5 -53.5t-47 -42t-77 -19.5q-72 0 -112 44t-44 89zM158 0l553 1505h131l-547 -1505h-137zM178 911q-4 -55 37 -55q16 0 25.5 14.5t9.5 26.5v14v437 q2 55 -35 55q-18 0 -27.5 -13.5t-9.5 -27.5v-14v-437zM631 158v436q0 6 1 18.5t9 43t23.5 53t48 42t78.5 19.5q70 0 109.5 -44t43.5 -87l4 -45v-436q0 -6 -1 -18.5t-9 -42t-23.5 -53.5t-47 -42t-76.5 -18q-72 0 -112 43t-44 88zM754 158q-4 -57 37 -58q16 0 24 14.5t8 28.5 l2 15v436q2 55 -34 55q-18 0 -27.5 -13t-9.5 -28v-14v-436z" />
20
+ <glyph unicode="&#x26;" horiz-adv-x="854" d="M49 315q0 115 44 214.5t126 222.5q-106 225 -106 442v18q0 12 5 46t13 65t28.5 69t48.5 65.5t73 46t102 18.5q78 0 134 -34t80 -82t37 -96t13 -81v-35q0 -162 -205 -434q76 -174 148 -285q33 96 47 211l176 -33q-16 -213 -92 -358q55 -63 92 -76v-235q-23 0 -86 37.5 t-123 101.5q-123 -139 -252 -139t-216 97t-87 234zM262 326q2 -66 29.5 -108t70.5 -42q59 0 125 86q-88 139 -174 295q-6 -10 -14 -28.5t-22.5 -77.5t-14.5 -125zM305 1194q0 -111 55 -246q100 156 101 252q-2 2 0 15.5t-2 36t-11.5 43t-23.5 36t-41 15.5q-39 0 -58.5 -38 t-19.5 -75v-39z" />
21
+ <glyph unicode="'" horiz-adv-x="309" d="M45 1012l72 266h-72v227h215v-227l-113 -266h-102z" />
22
+ <glyph unicode="(" horiz-adv-x="561" d="M66 645q0 143 29.5 292.5t72.5 261.5t87 204t73 139l30 47l162 -84l-27.5 -40.5t-62.5 -114.5t-79 -182.5t-61.5 -238t-27.5 -284.5t26.5 -282.5t64.5 -240.5t76 -178t65 -118l26 -39l-162 -84q-12 18 -31.5 50t-69.5 133.5t-89 207t-70.5 257t-31.5 294.5z" />
23
+ <glyph unicode=")" horiz-adv-x="561" d="M41 -213q10 14 27.5 41t62.5 115t79 181t61.5 236.5t27.5 284.5t-26.5 282.5t-64.5 241t-76 179t-64 118.5l-27 39l162 84q12 -18 31.5 -50t69.5 -134t89 -206.5t71 -257.5t32 -296t-30 -292.5t-74 -261t-87 -203t-72 -138.5l-30 -47z" />
24
+ <glyph unicode="*" horiz-adv-x="677" d="M74 1251l43 148l164 -70l-19 176h154l-19 -176l164 70l43 -148l-172 -34l115 -138l-131 -80l-78 152l-76 -152l-131 80l115 138z" />
25
+ <glyph unicode="+" horiz-adv-x="1060" d="M74 649v172h370v346h172v-346h371v-172h-371v-346h-172v346h-370z" />
26
+ <glyph unicode="," horiz-adv-x="309" d="M45 0v227h215v-227l-113 -266h-102l72 266h-72z" />
27
+ <glyph unicode="-" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
28
+ <glyph unicode="." horiz-adv-x="321" d="M53 0v227h215v-227h-215z" />
29
+ <glyph unicode="/" horiz-adv-x="720" d="M8 -147l543 1652h162l-537 -1652h-168z" />
30
+ <glyph unicode="0" horiz-adv-x="724" d="M68 309v887q0 12 2 34.5t17 79t43 99.5t88.5 78t144 35t144 -34t88.5 -81t43 -95t17 -83l2 -33v-887q0 -12 -2 -34.5t-17 -79t-43 -99.5t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 80.5t-43 95.5t-17 80.5zM289 309q0 -12 1 -30.5t19.5 -49t53 -30.5t53 27.5t18.5 56.5 l2 26v887q0 12 -1 30.5t-19.5 49.5t-53 31t-53 -28t-18.5 -54l-2 -29v-887z" />
31
+ <glyph unicode="1" horiz-adv-x="475" d="M25 1180v141q82 16 140 62.5t77 82.5l18 39h133v-1505h-221v1180h-147z" />
32
+ <glyph unicode="2" horiz-adv-x="731" d="M55 0v219l39 62q25 39 88.5 152.5t112.5 220t91 241.5t44 238q0 184 -73.5 184t-73.5 -184v-105h-222v105q0 389 295 389t295 -375q0 -336 -346 -928h350v-219h-600z" />
33
+ <glyph unicode="3" d="M45 1071q0 70 2 115t17.5 115.5t44 112.5t84 75t135.5 33q78 0 135 -31t84.5 -71t44 -92t19.5 -79.5t3 -50.5q0 -291 -106 -397l-2 -2q127 -100 127 -414q0 -25 -3 -58.5t-19.5 -99t-44 -116t-85 -89t-135.5 -38.5q-80 0 -136 31.5t-86 75.5t-47.5 112.5t-20.5 118 t-3 112.5h217q2 -150 17.5 -203t58.5 -53q45 0 57.5 50.5t12.5 140.5q0 18 1 66t0 62.5t-4 49.5t-10 46l-18 33q-12 22 -29.5 29t-45 15t-62.5 10h-19v184q37 2 62.5 7.5t45 14.5t31 21.5t17.5 29.5t9 39.5t3 51.5v62v43q0 45 -1 68.5t-7 58t-21.5 51t-39.5 16.5 q-41 0 -52.5 -49t-13.5 -207h-217z" />
34
+ <glyph unicode="4" horiz-adv-x="684" d="M25 328v194l323 983h221v-983h103v-194h-103v-328h-202v328h-342zM213 522h154v471v45h-13l-12 -45z" />
35
+ <glyph unicode="5" horiz-adv-x="704" d="M74 438h221v-59q0 -115 14.5 -159t52.5 -44q37 0 52.5 45t15.5 156v336q0 111 -70 110q-33 0 -59.5 -40t-26.5 -70h-186v792h535v-219h-344v-313q8 6 21 15t47 23.5t59 12.5q78 0 133 -40t76.5 -99.5t28.5 -100.5t7 -71v-336q0 -393 -289 -393q-78 0 -133 29.5 t-84.5 71.5t-46 108.5t-20.5 118.5t-4 126z" />
36
+ <glyph unicode="6" horiz-adv-x="700" d="M66 309v856q0 356 288.5 356.5t288.5 -356.5v-94h-221q0 162 -11.5 210t-56.5 48q-39 0 -53 -37t-14 -127v-268q59 37 110 37q80 0 133.5 -36t76 -93t29.5 -101.5t7 -87.5v-307q0 -41 -8 -84t-34 -103.5t-89 -99t-157.5 -38.5t-158 38.5t-89 99t-33.5 103.5t-8 84z M287 244q0 -20 17.5 -44t49.5 -24q31 0 49.5 24.5t18.5 43.5v450q0 18 -18.5 43t-49 25t-48 -20.5t-19.5 -41.5v-456z" />
37
+ <glyph unicode="7" horiz-adv-x="589" d="M8 1286v219h557v-221l-221 -1284h-229l225 1286h-332z" />
38
+ <glyph unicode="8" horiz-adv-x="696" d="M53 322v176q0 188 115 297q-102 102 -102 276v127q0 23 2 49.5t18 79.5t43 93t84 71t135 31t135.5 -31t84 -71t43 -93t18.5 -79.5t2 -49.5v-127q0 -174 -103 -276q115 -109 115 -297v-176q0 -25 -2 -52.5t-18.5 -83t-45 -96.5t-88 -73.5t-141.5 -32.5t-141.5 32.5 t-88 73.5t-45 96.5t-18.5 83t-2 52.5zM268 410q2 -127 17.5 -175.5t62.5 -48.5q37 0 54.5 30t21.5 71t4 123q0 152 -13.5 209t-66.5 57t-66.5 -57t-13.5 -209zM283 1120q0 -127 12 -177t53 -50t53.5 50t12.5 177q0 113 -12.5 160t-53.5 47q-37 0 -50 -44t-15 -163z" />
39
+ <glyph unicode="9" horiz-adv-x="700" d="M57 340v94h222q0 -162 11 -210t56 -48q39 0 53.5 37t14.5 127v283q-59 -37 -111 -37q-80 0 -133 35.5t-75.5 93t-30 101.5t-7.5 87v293q0 41 8.5 84t34 103.5t89 99.5t157.5 39t157.5 -39t89 -99.5t34 -103.5t8.5 -84v-856q0 -356 -289 -356t-289 356zM279 825 q0 -18 18 -42.5t49 -24.5t48.5 20.5t19.5 40.5v443q0 20 -17.5 43.5t-50.5 23.5q-31 0 -49 -24.5t-18 -42.5v-437z" />
40
+ <glyph unicode=":" horiz-adv-x="362" d="M74 0v227h215v-227h-215zM74 893v227h215v-227h-215z" />
41
+ <glyph unicode=";" horiz-adv-x="362" d="M74 0v227h215v-227l-113 -266h-102l71 266h-71zM74 893v227h215v-227h-215z" />
42
+ <glyph unicode="&#x3c;" horiz-adv-x="1058" d="M74 649v160l911 475v-199l-698 -356l698 -356v-199z" />
43
+ <glyph unicode="=" horiz-adv-x="1058" d="M74 477v172h911v-172h-911zM74 864v172h911v-172h-911z" />
44
+ <glyph unicode="&#x3e;" horiz-adv-x="1058" d="M74 174v199l698 356l-698 356v199l911 -475v-160z" />
45
+ <glyph unicode="?" horiz-adv-x="645" d="M25 1260q12 33 33.5 68.5t59.5 81.5t96 76t124 27q82 -2 138 -33.5t82 -81.5t36 -91t10 -80q0 -82 -80 -219l-57 -96q-18 -32 -42 -106.5t-24 -143.5v-256h-190v256q0 102 24.5 195t48 140t64.5 117q43 72 53 113q6 27 -11 60.5t-56 33.5q-47 2 -82 -47t-49 -98zM199 0 h215v227h-215v-227z" />
46
+ <glyph unicode="@" horiz-adv-x="872" d="M66 303v889q0 43 17 94t56 106.5t117 92.5t184.5 37t184 -37t116.5 -92.5t56.5 -106.5t17.5 -94v-793h-164l-20 56q-4 -8 -11.5 -19.5t-37 -30t-64.5 -18.5q-145 0 -145 172v485q0 170 145 170q35 0 63.5 -17t39.5 -34l10 -16v45q0 51 -45 104.5t-145.5 53.5 t-145.5 -53.5t-45 -104.5v-889q0 -53 44 -103t146 -50q117 0 168 63l152 -86q-109 -143 -320 -143q-106 0 -184 35.5t-117 90t-56 103.5t-17 90zM535 573q0 -53 47 -53q49 0 49 53v455q0 53 -49 53q-47 0 -47 -53v-455z" />
47
+ <glyph unicode="A" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM307 541h152l-64 475l-6 39h-12l-6 -39z" />
48
+ <glyph unicode="B" horiz-adv-x="745" d="M82 0v1505h194q205 0 304.5 -91t99.5 -308q0 -106 -29.5 -175t-107.5 -136q6 -2 16 -9.5t37 -35t47.5 -65.5t36.5 -106.5t16 -152.5q0 -414 -342 -426h-272zM303 219q74 0 109 31q55 55 55 201q0 82 -16.5 134t-46 70.5t-48 22.5t-45.5 4h-8v-463zM303 885q23 0 34 1 t40 10t45 28.5t30.5 60.5t14.5 100.5t-14.5 100.5t-30.5 60.5t-45 28.5t-40 10t-34 1v-401z" />
49
+ <glyph unicode="C" horiz-adv-x="708" d="M68 309v887q0 12 2 34.5t17 79t43 99.5t88.5 78t144 35t144 -34t88.5 -81t43 -95t17 -83l2 -33v-207h-206v207q-2 0 0 11.5t-3.5 27.5t-12.5 32.5t-24.5 28t-43.5 11.5q-35 0 -54.5 -28t-21.5 -54l-2 -29v-887q0 -12 2 -30.5t21.5 -49t54.5 -30.5q41 0 62.5 27.5 t21.5 56.5v26v207h206v-207q0 -12 -2 -34.5t-17 -79t-43 -99.5t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 80.5t-43 95.5t-17 80.5z" />
50
+ <glyph unicode="D" horiz-adv-x="761" d="M82 0v1505h174q90 0 153.5 -12t112.5 -33.5t80 -67.5t50.5 -95.5t28.5 -139.5t12 -177t3 -228.5t-3 -228.5t-12 -176t-28.5 -138t-50.5 -95t-80 -67.5t-112.5 -34t-153.5 -12.5h-174zM303 221q94 0 123 41q39 55 41 320v172v52q0 330 -25 402q-23 66 -92 74q-18 2 -47 2 v-1063z" />
51
+ <glyph unicode="E" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506z" />
52
+ <glyph unicode="F" horiz-adv-x="616" d="M82 0v1505h526v-227h-305v-395h205v-228h-205v-655h-221z" />
53
+ <glyph unicode="G" horiz-adv-x="737" d="M68 274v35v887q0 12 2 34.5t17 79t43 99.5t88.5 78t144 35t144 -34t88.5 -81t43 -95t17 -83l2 -33v-231h-221v231q0 12 -1 30.5t-19.5 49.5t-53 31t-53 -28t-18.5 -54l-2 -29v-905q0 -12 1 -30.5t19.5 -49.5t53 -31t53 28t18.5 54l2 29v272h-88v187h309v-750h-131l-26 72 q-70 -88 -172 -88q-78 0 -134.5 33.5t-80 80.5t-34.5 95t-11 81z" />
54
+ <glyph unicode="H" horiz-adv-x="778" d="M82 0v1505h221v-622h172v622h221v-1505h-221v655h-172v-655h-221z" />
55
+ <glyph unicode="I" horiz-adv-x="385" d="M82 0v1505h221v-1505h-221z" />
56
+ <glyph unicode="J" horiz-adv-x="423" d="M12 -14v217q4 0 12.5 -1t29 2t35.5 12t28.5 34.5t13.5 62.5v1192h221v-1226q0 -137 -79 -221q-70 -74 -222 -73q-19 0 -39 1z" />
57
+ <glyph unicode="K" horiz-adv-x="768" d="M82 0v1505h221v-501v-25h8l11 25l184 501h215l-203 -495l230 -1010h-216l-153 655l-6 31h-6l-13 -31l-51 -123v-532h-221z" />
58
+ <glyph unicode="L" horiz-adv-x="604" d="M82 0v1505h221v-1300h293v-205h-514z" />
59
+ <glyph unicode="M" horiz-adv-x="991" d="M82 0v1505h270l131 -688l11 -80h4l10 80l131 688h270v-1505h-204v946v64h-13l-8 -64l-141 -946h-94l-142 946l-8 64h-12v-64v-946h-205z" />
60
+ <glyph unicode="N" horiz-adv-x="808" d="M82 0v1505h197l215 -784l18 -70h12v70v784h203v-1505h-197l-215 784l-18 70h-12v-70v-784h-203z" />
61
+ <glyph unicode="O" horiz-adv-x="724" d="M68 309v887q0 12 2 34.5t17 79t43 99.5t88.5 78t144 35t144 -34t88.5 -81t43 -95t17 -83l2 -33v-887q0 -12 -2 -34.5t-17 -79t-43 -99.5t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 80.5t-43 95.5t-17 80.5zM289 309q0 -12 1 -30.5t19.5 -49t53 -30.5t53 27.5t18.5 56.5 l2 26v887q0 12 -1 30.5t-19.5 49.5t-53 31t-53 -28t-18.5 -54l-2 -29v-887z" />
62
+ <glyph unicode="P" horiz-adv-x="720" d="M82 0v1505h221q166 0 277.5 -105.5t111.5 -345t-111.5 -346t-277.5 -106.5v-602h-221zM303 827q102 0 134 45.5t32 174.5q0 131 -33 182t-133 51v-453z" />
63
+ <glyph unicode="Q" horiz-adv-x="729" d="M68 309v887q0 12 2 34.5t17 79t43 99.5t88.5 78t144 35t144 -34t88.5 -81t43 -95t17 -83l2 -33v-887q0 -94 -45 -182q33 -43 88 -53v-189q-160 0 -227 117q-55 -18 -111 -18q-84 0 -144 33.5t-88 80.5t-43 95.5t-17 80.5zM289 309q0 -12 1 -30.5t19.5 -49t53 -30.5 t53 27.5t18.5 56.5l2 26v887q0 12 -1 30.5t-19.5 49.5t-53 31t-53 -28t-18.5 -54l-2 -29v-887z" />
64
+ <glyph unicode="R" horiz-adv-x="739" d="M82 0v1505h221q377 0 377 -434q0 -258 -123 -342l141 -729h-221l-115 635h-59v-635h-221zM303 840q31 0 52.5 5t51 24.5t45 68.5t15.5 125t-15.5 125t-45 68.5t-51 24.5t-52.5 5v-446z" />
65
+ <glyph unicode="S" horiz-adv-x="702" d="M37 422l217 20q0 -256 104 -256q90 0 91 166q0 29 -8.5 59.5t-32 73.5t-36.5 64l-54 79q-40 58 -48 72q-66 96 -102.5 158t-68 149t-31.5 162q0 139 71.5 245t216.5 108h10q88 0 150 -35q66 -37 95.5 -101.5t42 -127t12.5 -136.5l-217 -20q0 217 -89 217q-76 -2 -75 -150 q0 -18 4 -39.5t10 -39t18.5 -43t20.5 -40t28 -43.5l28 -43l33 -48l32 -46l104 -159q31 -49 67 -139.5t36 -166.5q0 -379 -308 -378q-82 0 -142 25.5t-94 63.5t-53.5 99t-25.5 117.5t-6 132.5z" />
66
+ <glyph unicode="T" horiz-adv-x="647" d="M4 1278v227h639v-227h-209v-1278h-221v1278h-209z" />
67
+ <glyph unicode="U" horiz-adv-x="749" d="M80 309v1196h221v-1196q0 -12 1 -30.5t19.5 -49t53.5 -30.5t53 27.5t18 56.5l3 26v1196h221v-1196q0 -12 -2 -34.5t-17.5 -79t-43 -99.5t-88 -77.5t-144.5 -34.5t-144.5 33.5t-88 80.5t-43 95.5t-17.5 80.5z" />
68
+ <glyph unicode="V" horiz-adv-x="716" d="M18 1505h215l111 -827l8 -64h13l8 64l110 827h215l-229 -1505h-221z" />
69
+ <glyph unicode="W" horiz-adv-x="1036" d="M25 1505h204l88 -782l5 -49h16l6 49l94 782h160l94 -782l6 -49h17l4 49l88 782h205l-203 -1505h-172l-102 713l-13 88h-8l-12 -88l-103 -713h-172z" />
70
+ <glyph unicode="X" horiz-adv-x="737" d="M16 0l244 791l-240 714h218l120 -381l7 -18h8l6 18l121 381h217l-240 -714l244 -791h-217l-127 449l-4 18h-8l-5 -18l-127 -449h-217z" />
71
+ <glyph unicode="Y" horiz-adv-x="700" d="M14 1505h217l111 -481l6 -14h4l6 14l111 481h217l-225 -864v-641h-221v641z" />
72
+ <glyph unicode="Z" horiz-adv-x="626" d="M20 0v238l347 1048h-297v219h536v-219l-352 -1067h352v-219h-586z" />
73
+ <glyph unicode="[" horiz-adv-x="538" d="M82 -16v1521h399v-196h-202v-1325h202v-197h-399v197z" />
74
+ <glyph unicode="\" horiz-adv-x="792" d="M8 1692h162l614 -1872h-168z" />
75
+ <glyph unicode="]" horiz-adv-x="538" d="M57 -16h203v1325h-203v196h400v-1521v-197h-400v197z" />
76
+ <glyph unicode="^" horiz-adv-x="1101" d="M53 809l381 696h234l381 -696h-199l-299 543l-299 -543h-199z" />
77
+ <glyph unicode="_" horiz-adv-x="1210" d="M74 -154h1063v-172h-1063v172z" />
78
+ <glyph unicode="`" horiz-adv-x="1024" d="M293 1489h215l106 -184h-159z" />
79
+ <glyph unicode="a" horiz-adv-x="681" d="M49 260q0 106 34 187t83 124t98 73t88 50.5t43 36.5v37v86q0 102 -57 102q-20 0 -32.5 -9t-17.5 -32.5t-7 -37t-2 -47.5v-39h-207v47q0 123 80.5 211t197.5 88q102 0 177 -74t75 -180v-351v-337q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-100.5 -34.5 q-59 0 -112.5 60t-53.5 216zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
80
+ <glyph unicode="b" d="M82 0v1505h207v-458q88 90 164 90q78 0 118.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-74h-207zM289 246q0 -29 19.5 -48.5t42 -19.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -21.5t-19.5 -46.5v-628z" />
81
+ <glyph unicode="c" horiz-adv-x="645" d="M66 315v490q0 332 264 332q137 0 201.5 -71t64.5 -251v-88h-207v135q0 51 -12 70.5t-47 19.5q-57 0 -58 -90v-604q0 -90 58 -90q35 0 47 19.5t12 70.5v156h207v-109q0 -180 -64.5 -250.5t-201.5 -70.5q-264 -1 -264 331z" />
82
+ <glyph unicode="d" d="M74 203v715q0 82 41 150.5t118 68.5q33 0 74 -22.5t66 -45.5l24 -22v458h207v-1505h-207v74q-88 -90 -164 -90q-78 0 -118.5 68.5t-40.5 150.5zM281 246q0 -29 16 -48.5t38.5 -19.5t42 19.5t19.5 48.5v628q0 25 -19.5 46.5t-42 21.5t-38.5 -19.5t-16 -48.5v-628z" />
83
+ <glyph unicode="e" horiz-adv-x="659" d="M66 279v563q0 12 2 31.5t16 70.5t40 90t81 71t129 32q76 0 130 -30t79.5 -73t40 -85t14.5 -72l2 -29v-326h-342v-243v-13q0 -8 4 -27.5t11.5 -34t23.5 -26.5t37 -12q35 0 53.5 27.5t18.5 56.5l2 29v122h192v-129q0 -12 -2 -31.5t-16.5 -68.5t-39 -88t-79.5 -69.5 t-131 -30.5q-74 0 -129.5 30.5t-80 73.5t-38.5 86t-16 74zM258 684h150v158q0 12 -1 31.5t-19.5 51t-53.5 31.5q-33 0 -52.5 -28.5t-21.5 -57.5l-2 -28v-158z" />
84
+ <glyph unicode="f" horiz-adv-x="475" d="M20 934v186h105v17v14q0 51 2 84t14.5 92t35 94t70.5 63.5t115 28.5q29 0 53.5 -3t35.5 -7l8 -4v-178q-27 8 -62 8q-66 0 -65 -180v-16v-13h104v-186h-104v-934h-207v934h-105z" />
85
+ <glyph unicode="g" horiz-adv-x="700" d="M12 -184q0 94 162 170q-125 35 -125 149q0 45 40 93t89 75q-51 35 -80.5 95.5t-34.5 105.5l-4 43v305q0 12 2 30.5t16.5 67.5t39 87t79 69t126.5 31q135 0 206 -103q102 102 170 103v-185q-72 0 -120 -24l10 -70v-317q0 -10 -2 -29.5t-17.5 -67t-40 -84t-79 -66.5 t-127.5 -30q-27 0 -39 2q-29 -25 -29 -51q0 -16 11 -28.5t42 -20.5t45.5 -10t59.5 -11q57 -8 101 -21t89 -41t70.5 -78t25.5 -120q0 -152 -103 -219t-251 -67q-164 4 -248 52t-84 165zM213 -150q0 -78 135 -77q59 0 108.5 19.5t49.5 55.5q0 33 -20.5 50.5t-90.5 29.5 l-106 21q-76 -44 -76 -99zM262 509q0 -17 15.5 -45t44.5 -28q31 0 47 25.5t16 50.5v25v307q-1 1 -1 3.5t1 7.5t1 6q0 8 -3 19q-4 15 -9 30.5t-18.5 25.5t-33.5 10q-29 0 -44.5 -25.5t-15.5 -52.5v-24v-307v-28z" />
86
+ <glyph unicode="h" horiz-adv-x="690" d="M82 0v1505h207v-479l32 32q30 30 66.5 54.5t69.5 24.5q76 0 115.5 -69t39.5 -150v-918h-206v887q0 49 -50 49q-18 0 -34.5 -13.5t-24.5 -25.5l-8 -14v-883h-207z" />
87
+ <glyph unicode="i" horiz-adv-x="370" d="M82 0v1120h207v-1120h-207zM82 1298v207h207v-207h-207z" />
88
+ <glyph unicode="j" horiz-adv-x="364" d="M-45 -182q29 -8 57 -8q64 0 64 142v10.5v10.5v1147h207v-1149q0 -51 -2 -83.5t-14.5 -90t-35 -92.5t-70.5 -62.5t-116 -27.5q-29 0 -51.5 3t-30.5 5l-8 4v191zM76 1298v207h207v-207h-207z" />
89
+ <glyph unicode="k" horiz-adv-x="641" d="M82 0v1505h207v-678v-36h10l12 36l101 293h186l-149 -364l188 -756h-199l-102 453l-4 16h-10l-7 -16l-26 -66v-387h-207z" />
90
+ <glyph unicode="l" horiz-adv-x="370" d="M82 0v1505h207v-1505h-207z" />
91
+ <glyph unicode="m" horiz-adv-x="1021" d="M82 0v1120h207v-94q2 0 32.5 30.5t68.5 55.5t71 25q100 0 139 -125l43 41t76 60.5t69 23.5q76 0 116 -69t40 -150v-918h-194v887q0 49 -56 49q-18 0 -37.5 -13.5t-29.5 -25.5l-11 -14v-883h-194v887q0 49 -55 49q-18 0 -38 -13.5t-30 -25.5l-10 -14v-883h-207z" />
92
+ <glyph unicode="n" horiz-adv-x="690" d="M82 0v1120h207v-94l32 32q30 30 66.5 54.5t69.5 24.5q76 0 115.5 -69t39.5 -150v-918h-206v887q0 49 -50 49q-18 0 -34.5 -13.5t-24.5 -25.5l-8 -14v-883h-207z" />
93
+ <glyph unicode="o" horiz-adv-x="657" d="M63 279v563q0 12 1.5 31.5t15.5 70.5t38.5 90t80 71t129.5 32q76 0 130 -30t79.5 -73t40 -85t16.5 -72v-29v-576q0 -12 -1 -31.5t-15.5 -68.5t-40 -88t-80 -69.5t-129.5 -30.5q-74 0 -129.5 30.5t-80 73.5t-38.5 86t-14 74zM257 259q0 -9 3 -20q4 -17 10 -34t21.5 -28 t36.5 -11q35 0 52 27.5t17 56.5l2 29v563q-2 0 0 11q1 4 1 8q0 9 -3 21q-4 17 -10 33.5t-21.5 28.5t-37.5 12q-33 0 -50.5 -28.5t-19.5 -57.5v-28v-563q1 -1 1 -4t-1 -9t-1 -7z" />
94
+ <glyph unicode="p" d="M82 -385v1505h207v-73q88 90 164 90q78 0 118.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-459h-207zM289 246q0 -25 19.5 -46.5t42 -21.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -19.5t-19.5 -48.5v-628z" />
95
+ <glyph unicode="q" d="M74 203v715q0 82 41 150.5t118 68.5q33 0 74 -22.5t66 -45.5l24 -22v73h207v-1505h-207v459q-88 -90 -164 -90q-78 0 -118.5 68.5t-40.5 150.5zM281 246q0 -29 16 -48.5t38.5 -19.5t42 21.5t19.5 46.5v628q0 29 -19.5 48.5t-42 19.5t-38.5 -19.5t-16 -48.5v-628z" />
96
+ <glyph unicode="r" horiz-adv-x="503" d="M82 0v1120h207v-125q8 41 58 91.5t149 50.5v-230q-34 11 -64 11q-56 0 -98 -37q-45 -41 -45 -103v-778h-207z" />
97
+ <glyph unicode="s" horiz-adv-x="630" d="M37 326h192q0 -170 97 -170q72 0 71 135q0 74 -129 198q-68 66 -98.5 99t-64 101.5t-33.5 144.5q0 55 12 104t39 95t78 74t123 30h11q78 0 131 -26q56 -28 80.5 -79t33 -95t8.5 -103h-193q0 131 -67 131q-63 -2 -64 -131q0 -33 23.5 -73t45 -62.5t66.5 -65.5 q190 -182 191 -342q0 -123 -64.5 -215t-199.5 -92q-72 0 -126.5 24.5t-85 60t-49 85t-23.5 89.5t-5 83z" />
98
+ <glyph unicode="t" horiz-adv-x="501" d="M20 934v186h105v277h207v-277h141v-186h-141v-557q0 -184 65 -184l76 8v-203q-45 -14 -111 -14q-68 0 -115.5 28.5t-70 64.5t-35 96t-14.5 95t-2 92v574h-105z" />
99
+ <glyph unicode="u" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q18 0 34.5 13.5t24.5 27.5l8 13v882h207v-1120h-207v94l-31 -32q-30 -30 -67 -54t-70 -24q-76 0 -115.5 68.5t-39.5 150.5z" />
100
+ <glyph unicode="v" horiz-adv-x="602" d="M16 1120h201l68 -649l8 -72h16l8 72l68 649h201l-183 -1120h-204z" />
101
+ <glyph unicode="w" horiz-adv-x="905" d="M20 1120h189l65 -585l9 -64h12l10 64l86 585h123l86 -585l10 -64h13l8 64l65 585h189l-166 -1120h-172l-80 535l-10 63h-8l-11 -63l-80 -535h-172z" />
102
+ <glyph unicode="x" horiz-adv-x="618" d="M16 0l193 578l-176 542h194l74 -262l6 -31h4l6 31l74 262h195l-176 -542l192 -578h-201l-84 283l-6 30h-4l-6 -30l-84 -283h-201z" />
103
+ <glyph unicode="y" horiz-adv-x="634" d="M25 1120h202l82 -688l4 -57h9l4 57l82 688h202l-198 -1204q-16 -127 -94 -222t-193 -95l-92 4v184q16 -4 49 -4q61 6 97 61.5t36 122.5z" />
104
+ <glyph unicode="z" horiz-adv-x="532" d="M12 0v168l285 764h-240v188h459v-168l-285 -764h285v-188h-504z" />
105
+ <glyph unicode="{" horiz-adv-x="688" d="M61 453v163q72 0 102 49.5t30 90.5v397q0 223 96 298t342 71v-172q-135 2 -188.5 -38t-53.5 -159v-397q0 -143 -127 -221q127 -82 127 -222v-397q0 -119 53.5 -159t188.5 -38v-172q-246 -4 -342 71t-96 298v397q0 20 -8.5 47t-41.5 59t-82 34z" />
106
+ <glyph unicode="|" horiz-adv-x="356" d="M82 -512v2204h192v-2204h-192z" />
107
+ <glyph unicode="}" horiz-adv-x="688" d="M57 -281q135 -2 188.5 38t53.5 159v397q0 139 127 222q-127 78 -127 221v397q0 119 -53 159t-189 38v172q246 4 342.5 -71t96.5 -298v-397q0 -23 8 -50.5t41 -58.5t82 -31v-163q-72 -4 -101.5 -52.5t-29.5 -87.5v-397q0 -223 -96.5 -298t-342.5 -71v172z" />
108
+ <glyph unicode="~" horiz-adv-x="1280" d="M113 1352q4 12 12 32.5t38 73.5t64.5 94t95 74t126.5 33q55 0 111 -18.5t82 -33t83 -51.5q106 -72 174 -71q57 0 105.5 46t66.5 91l19 45l135 -57q-4 -12 -12.5 -34t-38 -75t-64.5 -93t-91 -74t-120 -34q-121 0 -272 101q-115 74 -178.5 74t-113.5 -45.5t-69 -90.5 l-18 -45z" />
109
+ <glyph unicode="&#xa2;" horiz-adv-x="636" d="M66 508v489q0 297 208 328v242h123v-244q98 -16 144.5 -88t46.5 -227v-88h-189v135q0 90 -73 90q-72 0 -72 -90v-604q0 -90 72 -91q74 0 73 91v155h189v-108q0 -156 -46 -228.5t-145 -89.5v-303h-123v301q-208 31 -208 330z" />
110
+ <glyph unicode="&#xa3;" horiz-adv-x="817" d="M4 63q8 20 23.5 53.5t70 91.5t117.5 68q37 111 37 199q0 68 -31 174h-188v137h147l-6 21q-78 254 -78 342q0 70 15.5 131t48.5 116.5t92 89.5t139 36q96 2 164 -32t103.5 -93.5t50 -127t14.5 -149.5h-213q0 86 -25.5 142.5t-89.5 54.5q-47 -2 -68.5 -51t-21.5 -117 q0 -113 70 -338l6 -25h211v-137h-174q25 -100 24 -174q0 -104 -57 -219q16 -8 44 -24.5t48.5 -25.5t40.5 -9q74 4 82 190l188 -22q-12 -182 -81.5 -281.5t-169.5 -99.5q-51 0 -143.5 51t-129.5 51q-33 0 -61.5 -25.5t-40.5 -52.5l-12 -24z" />
111
+ <glyph unicode="&#xa5;" horiz-adv-x="720" d="M25 1505h217l110 -481l6 -14h4l7 14l110 481h217l-196 -753h147v-138h-176v-137h176v-137h-176v-340h-221v340h-176v137h176v137h-176v138h147z" />
112
+ <glyph unicode="&#xa9;" horiz-adv-x="1644" d="M53 751.5q0 317.5 225.5 544t543 226.5t543.5 -226.5t226 -544t-226 -542.5t-543.5 -225t-543 225t-225.5 542.5zM172 751.5q0 -266.5 191.5 -458t457.5 -191.5t459 191.5t193 458.5q0 268 -191.5 459.5t-460.5 191.5q-266 0 -457.5 -192.5t-191.5 -459zM627 487v531 q0 8 1 21.5t11 47t27.5 59t57.5 47t95 21.5q53 0 92 -20t56.5 -49t28 -57.5t12.5 -49.5v-20v-125h-138v125v17q0 11 -12 28.5t-37 17.5q-23 0 -35 -16t-12 -33l-2 -14v-531q0 -63 49 -63q25 0 37 15.5t12 31.5v16v125h138v-125q0 -8 -1 -21t-11.5 -47t-28 -59.5t-56.5 -47 t-92 -21.5q-86 0 -134 49t-54 98z" />
113
+ <glyph unicode="&#xad;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
114
+ <glyph unicode="&#xae;" horiz-adv-x="1644" d="M53 751.5q0 317.5 225.5 544t543 226.5t543.5 -226.5t226 -544t-226 -542.5t-543.5 -225t-543 225t-225.5 542.5zM172 751.5q0 -266.5 191.5 -458t457.5 -191.5t459 191.5t193 458.5q0 268 -191.5 459.5t-460.5 191.5q-266 0 -457.5 -192.5t-191.5 -459zM625 313v879h196 q231 0 232 -258q0 -76 -16.5 -125t-71.5 -96l106 -400h-151l-95 365h-55v-365h-145zM770 805h45q43 0 65.5 21.5t27.5 45t5 60.5q0 39 -5 63.5t-27.5 46t-65.5 21.5h-45v-258z" />
115
+ <glyph unicode="&#xb4;" horiz-adv-x="1024" d="M410 1305l106 184h215l-162 -184h-159z" />
116
+ <glyph unicode="&#x2000;" horiz-adv-x="845" />
117
+ <glyph unicode="&#x2001;" horiz-adv-x="1691" />
118
+ <glyph unicode="&#x2002;" horiz-adv-x="845" />
119
+ <glyph unicode="&#x2003;" horiz-adv-x="1691" />
120
+ <glyph unicode="&#x2004;" horiz-adv-x="563" />
121
+ <glyph unicode="&#x2005;" horiz-adv-x="421" />
122
+ <glyph unicode="&#x2006;" horiz-adv-x="280" />
123
+ <glyph unicode="&#x2007;" horiz-adv-x="280" />
124
+ <glyph unicode="&#x2008;" horiz-adv-x="210" />
125
+ <glyph unicode="&#x2009;" horiz-adv-x="337" />
126
+ <glyph unicode="&#x200a;" horiz-adv-x="92" />
127
+ <glyph unicode="&#x2010;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
128
+ <glyph unicode="&#x2011;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
129
+ <glyph unicode="&#x2012;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
130
+ <glyph unicode="&#x2013;" horiz-adv-x="806" d="M74 649v195h659v-195h-659z" />
131
+ <glyph unicode="&#x2014;" horiz-adv-x="972" d="M74 649v195h825v-195h-825z" />
132
+ <glyph unicode="&#x2018;" horiz-adv-x="309" d="M49 1012v227l113 266h102l-71 -266h71v-227h-215z" />
133
+ <glyph unicode="&#x2019;" horiz-adv-x="309" d="M45 1012l72 266h-72v227h215v-227l-113 -266h-102z" />
134
+ <glyph unicode="&#x201c;" horiz-adv-x="624" d="M53 1012v227l113 266h102l-71 -266h71v-227h-215zM356 1012v227l113 266h102l-71 -266h71v-227h-215z" />
135
+ <glyph unicode="&#x201d;" horiz-adv-x="624" d="M53 1012l72 266h-72v227h215v-227l-112 -266h-103zM356 1012l72 266h-72v227h215v-227l-112 -266h-103z" />
136
+ <glyph unicode="&#x2022;" horiz-adv-x="663" d="M82 817q0 102 72.5 175t179.5 73q102 0 175 -72.5t73 -175.5q0 -106 -73 -179t-175 -73q-106 0 -179 73t-73 179z" />
137
+ <glyph unicode="&#x2026;" horiz-adv-x="964" d="M53 0v227h215v-227h-215zM375 0v227h215v-227h-215zM696 0v227h215v-227h-215z" />
138
+ <glyph unicode="&#x202f;" horiz-adv-x="337" />
139
+ <glyph unicode="&#x205f;" horiz-adv-x="421" />
140
+ <glyph unicode="&#x20ac;" horiz-adv-x="813" d="M53 547v137h107v137h-107v137h107v238q0 12 2 34.5t17.5 79t43 99.5t88 78t144.5 35t144 -34t88 -81t43 -95t18 -83l2 -33v-84h-207v84q-2 0 0 11.5t-3 27.5t-12.5 32.5t-25 28t-43.5 11.5q-35 0 -54.5 -28t-21.5 -54l-2 -29v-238h233v-137h-233v-137h233v-137h-233v-238 q0 -12 2 -30.5t21.5 -49t54.5 -30.5q41 0 61.5 27.5t20.5 56.5l2 26v84h207v-84q0 -12 -2.5 -34.5t-17.5 -79t-43 -99.5t-88 -77.5t-144 -34.5t-144.5 33.5t-88 80.5t-43 95.5t-17.5 80.5l-2 35v238h-107z" />
141
+ <glyph unicode="&#x2122;" horiz-adv-x="937" d="M74 1401v104h321v-104h-104v-580h-113v580h-104zM440 821v684h138l67 -319h6l68 319h137v-684h-104v449l-78 -449h-51l-80 449v-449h-103z" />
142
+ <glyph unicode="&#xe000;" horiz-adv-x="1120" d="M0 1120h1120v-1120h-1120v1120z" />
143
+ <glyph unicode="&#xfb01;" horiz-adv-x="772" d="M20 934v186h105v31q0 45 1 69.5t7 77t22.5 84t43 67.5t72.5 53.5t108 17.5q33 0 69.5 -4.5t57.5 -8.5l20 -2v-184q-41 12 -110 12q-31 0 -50.5 -18.5t-25.5 -58t-7 -54t-1 -53.5v-29h358v-1120h-207v934h-151v-934h-207v934h-105z" />
144
+ <glyph unicode="&#xfb02;" horiz-adv-x="772" d="M20 934v186h105v31q0 45 1 69.5t7 77t22.5 84t43 67.5t72.5 53.5t108 17.5q33 0 69.5 -4.5t57.5 -8.5l20 -2h164v-1505h-207v1329q-37 4 -67.5 4t-50 -18.5t-25.5 -58t-7 -54t-1 -53.5v-29h104v-186h-104v-934h-207v934h-105z" />
145
+ <glyph unicode="&#xfb03;" horiz-adv-x="1320" d="M1032 0v1120h207v-1120h-207zM1032 1298v207h207v-207h-207zM495 934v186h105v17v14q0 51 2 84t14.5 92t35 94t70.5 63.5t115 28.5q29 0 53.5 -3t35.5 -7l8 -4v-178q-27 8 -62 8q-66 0 -65 -180v-16v-13h104v-186h-104v-934h-207v934h-105zM20 934v186h105v17v14 q0 51 2 84t14.5 92t35 94t70.5 63.5t115 28.5q29 0 53.5 -3t35.5 -7l8 -4v-178q-27 8 -62 8q-66 0 -65 -180v-16v-13h104v-186h-104v-934h-207v934h-105z" />
146
+ <glyph unicode="&#xfb04;" horiz-adv-x="1320" d="M1032 0v1505h207v-1505h-207zM495 934v186h105v17v14q0 51 2 84t14.5 92t35 94t70.5 63.5t115 28.5q29 0 53.5 -3t35.5 -7l8 -4v-178q-27 8 -62 8q-66 0 -65 -180v-16v-13h104v-186h-104v-934h-207v934h-105zM20 934v186h105v17v14q0 51 2 84t14.5 92t35 94t70.5 63.5 t115 28.5q29 0 53.5 -3t35.5 -7l8 -4v-178q-27 8 -62 8q-66 0 -65 -180v-16v-13h104v-186h-104v-934h-207v934h-105z" />
147
+ </font>
148
+ </defs></svg>
@@ -0,0 +1,14 @@
1
+ # Sends several generic events to the parent window that indicates the
2
+ # current state of the Iframe.
3
+
4
+ # Tell the parent that we are ready
5
+ @addEventListener 'DOMContentLoaded', (e) =>
6
+ @parent.postMessage { event:'domloaded:iframe' }, @location.origin
7
+ , false
8
+
9
+ events = [ 'load', 'error', 'change', 'hashchange', 'resize', 'pageshow', 'pagehide', 'beforeunload' ]
10
+
11
+ events.forEach (evt) =>
12
+ @addEventListener evt, (e) =>
13
+ @parent.postMessage { event:"#{evt}:iframe" }, @location.origin
14
+ , false
@@ -0,0 +1,65 @@
1
+ $ = document.querySelectorAll.bind(document)
2
+
3
+ MONTHS = 'January February March April May June July August September October November December'.split( ' ' )
4
+
5
+ class @NE.OSD
6
+ constructor : ->
7
+ @el = document.getElementById( 'osd' )
8
+ @guideEl = document.getElementById( 'guide' )
9
+
10
+ @autoHideTimer = null
11
+ @autoHideDelay = 1000
12
+
13
+ @guideUrl = 'guide.html'
14
+
15
+ document.addEventListener 'mousemove', @onMouseMove
16
+
17
+ setInterval( @updateTimestamps, 1000 )
18
+
19
+ onMouseMove : (e) =>
20
+ @cancelAutoHide()
21
+
22
+ unless @el.classList.contains( 'active' )
23
+ @el.classList.add 'active'
24
+
25
+ @render()
26
+
27
+ @autoHide()
28
+
29
+ autoHide : ->
30
+ @autoHideTimer = setTimeout( @doAutoHide, @autoHideDelay )
31
+
32
+ doAutoHide : =>
33
+ if @el.classList.contains( 'active' )
34
+ @el.classList.remove 'active'
35
+
36
+ cancelAutoHide : ->
37
+ clearTimeout @autoHideTimer
38
+
39
+ render : ->
40
+ @fetchGuide (xhr) =>
41
+ @guideEl.innerHTML = xhr.responseText
42
+
43
+ fetchGuide : (cb) ->
44
+ xhr = new XMLHttpRequest();
45
+
46
+ xhr.addEventListener 'readystatechange', (e) ->
47
+ cb( xhr ) if xhr.readyState == 4 && xhr.status == 200
48
+
49
+ xhr.open( 'GET', @guideUrl, true )
50
+ xhr.send()
51
+
52
+ updateTimestamps : ->
53
+ now = new Date()
54
+ mon = now.getMonth()
55
+ d = now.getDate()
56
+ y = now.getFullYear()
57
+ h = now.getHours()
58
+ min = now.getMinutes()
59
+ a = if h > 12 then 'pm' else 'am'
60
+
61
+ h = if h > 12 then h - 12 else h
62
+ min = if min < 10 then "0#{min}" else min
63
+
64
+ $('.osd-now-time')[0].innerHTML = "#{h}:#{min}#{a}"
65
+ $('.osd-now-date')[0].innerHTML = "#{MONTHS[mon]} #{d}, #{y}"
@@ -0,0 +1,55 @@
1
+ win = @
2
+
3
+ class @NE.PhotoPlayer
4
+ constructor : (photoId, titleId, descId, photogId, locId ) ->
5
+ @photo = document.getElementById( photoId )
6
+ @title = document.getElementById( titleId )
7
+ @description = document.getElementById( descId )
8
+ @photographer = document.getElementById( photogId )
9
+ @location = document.getElementById( locId )
10
+
11
+ @photos = []
12
+ @displayTime = 10000
13
+ @cursor = 0
14
+
15
+ win.addEventListener 'load:program', @onLoad, false
16
+
17
+ render : =>
18
+ return unless photo = @nextPhoto()
19
+
20
+ @renderPhoto photo.image_url
21
+ @renderTitle photo.title
22
+ @renderDescription photo.description
23
+ @renderPhotog photo.photographer
24
+ @renderLocation photo.location
25
+
26
+ renderPhoto : (url) ->
27
+ @photo.setAttribute 'src', url
28
+
29
+ renderTitle : (title) ->
30
+ @title.innerHTML = title
31
+
32
+ renderDescription : (desc) ->
33
+ @description.innerHTML = desc
34
+
35
+ renderPhotog : (photog) ->
36
+ @photographer.innerHTML = photog
37
+
38
+ renderLocation : (location) ->
39
+ @location.innerHTML = location
40
+
41
+ nextPhoto : ->
42
+ @cursor = 0 if @cursor > @photos.length - 1
43
+
44
+ p = @photos[@cursor]
45
+
46
+ @cursor++
47
+
48
+ p
49
+
50
+ onLoad : (e) =>
51
+ @photos = e.detail.data.photos
52
+
53
+ setInterval @render, @displayTime
54
+
55
+ @render()
@@ -0,0 +1,23 @@
1
+ # Converts postMessage events to page-level events, handling all JSON
2
+ # parsing in the process.
3
+ @addEventListener 'message', (e) =>
4
+ if e.origin == @location.origin
5
+ if e.data instanceof String
6
+ try
7
+ payload = JSON.parse( e.data )
8
+ catch e
9
+ payload = {}
10
+ else
11
+ payload = e.data || {}
12
+
13
+ if type = payload.event
14
+ delete payload.event
15
+
16
+ ce = new CustomEvent type,
17
+ detail :
18
+ data : payload,
19
+ source : e.source,
20
+ originalEvent : e
21
+
22
+ @dispatchEvent ce
23
+ , false
@@ -0,0 +1,81 @@
1
+ win = @
2
+
3
+ class @NE.SetTopBox
4
+ constructor : (channel) ->
5
+ @smpte = document.getElementById( 'smpte' )
6
+ @smpteMsg = document.getElementById( 'smpte_message' )
7
+ @program = document.getElementById( 'program' )
8
+
9
+ if @channel = channel
10
+ @establishUplink()
11
+ else
12
+ @setSmpteMessage 'No signal'
13
+
14
+ setSmpteMessage : (msg) ->
15
+ @smpteMsg.innerHTML = msg
16
+
17
+ showSmpte : ->
18
+ # Move this functionality to a class for better cross-browser support
19
+ @smpte.style.display = '-webkit-box'
20
+
21
+ hideSmpte : ->
22
+ @smpte.style.display = 'none'
23
+
24
+ establishUplink : ->
25
+ @uplink = new EventSource( "tune_in/#{@channel}" )
26
+
27
+ @uplink.addEventListener 'open', @onUplinkUp, false
28
+ @uplink.addEventListener 'message', @onUplinkMessage, false
29
+ @uplink.addEventListener 'error', @onUplinkDown, false
30
+
31
+ goTo : (url) ->
32
+ @program.setAttribute 'src', url
33
+
34
+ onUplinkUp : (e) =>
35
+ @setSmpteMessage 'Awaiting transmission...'
36
+
37
+ onUplinkDown : (e) =>
38
+ if e.eventPhase == EventSource.CLOSED
39
+ @setSmpteMessage 'Transmission lost...'
40
+
41
+ @goTo 'about:blank'
42
+
43
+ @showSmpte()
44
+
45
+ parseEvent : (e) ->
46
+ try
47
+ payload = JSON.parse( e.data )
48
+ catch e
49
+ payload = {}
50
+
51
+ payload
52
+
53
+ onUplinkMessage : (e) =>
54
+ console.log '[STB::message]', e.data
55
+
56
+ @hideSmpte()
57
+
58
+ payload = @parseEvent( e )
59
+
60
+ switch payload.event
61
+ when 'show:program' then cb = @onProgramShow
62
+ when 'update:program' then cb = @onProgramUpdate
63
+
64
+ cb( payload ) if cb
65
+
66
+ onProgramShow : (payload) =>
67
+ onIframeLoad = (e) =>
68
+ console.log '[STB::onIframeLoad]'
69
+
70
+ payload.onLoad.event = 'load:program'
71
+
72
+ e.detail.source.postMessage payload.onLoad, win.location.origin
73
+
74
+ win.removeEventListener 'load:iframe', onIframeLoad
75
+
76
+ win.addEventListener 'load:iframe', onIframeLoad, false
77
+
78
+ @goTo payload.url
79
+
80
+ onProgramUpdate : (payload) ->
81
+ @program.postMessage payload, win.location.origin
@@ -0,0 +1,95 @@
1
+ win = @
2
+ $ = @$
3
+
4
+ class @NE.TweetPlayer
5
+ constructor : (id) ->
6
+ @tweetEl = $(id)
7
+ @authorEl = document.getElementById( 'author' )
8
+ @avatarEl = document.getElementById( 'avatar' )
9
+ @backgroundEl = document.getElementById( 'background' )
10
+ @tweets = []
11
+ @displayTime = 10000
12
+ @cursor = 0
13
+
14
+ win.addEventListener 'load:program', @onLoad, false
15
+ win.addEventListener 'update:program', @onUpdate, false
16
+
17
+ render : =>
18
+ return unless tweet = @nextTweet()
19
+
20
+ @renderText tweet.text
21
+ @renderAuthor tweet.user
22
+ @renderAvatar tweet.user
23
+
24
+ nextTweet : ->
25
+ @cursor = 0 if @cursor > @tweets.length - 1
26
+
27
+ t = @tweets[@cursor]
28
+
29
+ @cursor++
30
+
31
+ t
32
+
33
+ renderText : (text) ->
34
+ buffer = []
35
+ pointer = -1
36
+ wc = 0
37
+ # Trailing ellipsis look awful
38
+ text = text.replace /(…|\.{2,})$/, ''
39
+
40
+ # TODO: Refactor
41
+ text.split( /\s/ ).forEach (substr, i, txt) ->
42
+ # First word
43
+ if buffer.length == 0
44
+ buffer.push substr
45
+ pointer++
46
+ wc = 1
47
+ # Last word was special-a
48
+ else if buffer[pointer].match( /,|!|\?|\.|@|#|:|\// ) and !substr.match(/https?:/) and (buffer[pointer].length > 4 or wc >= 4)
49
+ buffer.push substr
50
+ pointer++
51
+ wc = 1
52
+ # Current word is special-b, the buffer has more than 4 characters or more
53
+ # than 3 words, and the current word is NOT the last and more than 4
54
+ # characters
55
+ else if substr.match( /!|\?|@|#|:|;|\// ) and !buffer[pointer].match(/https?:/) and (buffer[pointer].length > 4 or wc >= 4) and (i < txt.length - 1 and substr.length > 4) and substr != '&amp;'
56
+ buffer.push substr
57
+ pointer++
58
+ wc = 1
59
+ # Current word is a URL and the buffer has more than 3 words
60
+ else if substr.match( /^https?/ ) and wc >= 3
61
+ buffer.push substr
62
+ pointer++
63
+ wc = 1
64
+ # Buffer has 5 or more words
65
+ else if wc >= 5 and substr != '&amp;'
66
+ buffer.push substr
67
+ pointer++
68
+ wc = 1
69
+ # Append it
70
+ else
71
+ buffer[pointer] += " #{substr}"
72
+ wc++
73
+
74
+ text = buffer.join '</div><div>'
75
+
76
+ text = "<div>#{text}</div>"
77
+
78
+ @tweetEl.html( text ).bigtext()
79
+
80
+ renderAuthor : (user) ->
81
+ @authorEl.innerHTML = user.screen_name
82
+
83
+ # Generates the URL for the original profile image by chopping off the suffix
84
+ renderAvatar : (user) ->
85
+ @backgroundEl.src = user.profile_image_url.replace '_normal', ''
86
+
87
+ onLoad : (e) =>
88
+ @tweets = e.detail.data.tweets
89
+
90
+ setInterval @render, @displayTime
91
+
92
+ @render()
93
+
94
+ onUpdate : (e) =>
95
+ # ...