prismcast 1.7.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/README.md +6 -6
  2. package/dist/app.js +24 -13
  3. package/dist/app.js.map +1 -1
  4. package/dist/browser/cdp.d.ts +4 -6
  5. package/dist/browser/cdp.js +13 -17
  6. package/dist/browser/cdp.js.map +1 -1
  7. package/dist/browser/index.js +3 -3
  8. package/dist/browser/index.js.map +1 -1
  9. package/dist/browser/login.js +11 -8
  10. package/dist/browser/login.js.map +1 -1
  11. package/dist/browser/precaching.d.ts +1 -1
  12. package/dist/browser/precaching.js +23 -23
  13. package/dist/browser/precaching.js.map +1 -1
  14. package/dist/browser/tuning/directv.js +4 -7
  15. package/dist/browser/tuning/directv.js.map +1 -1
  16. package/dist/browser/tuning/fox.js +1 -1
  17. package/dist/browser/tuning/fox.js.map +1 -1
  18. package/dist/browser/tuning/hbo.js +1 -1
  19. package/dist/browser/tuning/hbo.js.map +1 -1
  20. package/dist/browser/tuning/hulu.js +3 -3
  21. package/dist/browser/tuning/hulu.js.map +1 -1
  22. package/dist/browser/tuning/sling.js +2 -2
  23. package/dist/browser/tuning/sling.js.map +1 -1
  24. package/dist/channels/index.d.ts +2 -0
  25. package/dist/channels/index.js +438 -252
  26. package/dist/channels/index.js.map +1 -1
  27. package/dist/config/health.d.ts +3 -3
  28. package/dist/config/health.js +13 -18
  29. package/dist/config/health.js.map +1 -1
  30. package/dist/config/index.js +11 -2
  31. package/dist/config/index.js.map +1 -1
  32. package/dist/config/persistence.d.ts +59 -0
  33. package/dist/config/persistence.js +127 -0
  34. package/dist/config/persistence.js.map +1 -0
  35. package/dist/config/profiles.js +10 -10
  36. package/dist/config/profiles.js.map +1 -1
  37. package/dist/config/servicePacks.d.ts +46 -0
  38. package/dist/config/{providerPacks.js → servicePacks.js} +28 -31
  39. package/dist/config/servicePacks.js.map +1 -0
  40. package/dist/config/services.d.ts +202 -0
  41. package/dist/config/services.js +758 -0
  42. package/dist/config/services.js.map +1 -0
  43. package/dist/config/sites.js +61 -61
  44. package/dist/config/sites.js.map +1 -1
  45. package/dist/config/userChannels.d.ts +89 -27
  46. package/dist/config/userChannels.js +400 -184
  47. package/dist/config/userChannels.js.map +1 -1
  48. package/dist/config/userConfig.d.ts +13 -9
  49. package/dist/config/userConfig.js +78 -60
  50. package/dist/config/userConfig.js.map +1 -1
  51. package/dist/config/userProfiles.d.ts +31 -15
  52. package/dist/config/userProfiles.js +154 -123
  53. package/dist/config/userProfiles.js.map +1 -1
  54. package/dist/hdhr/channelMap.d.ts +1 -1
  55. package/dist/hdhr/channelMap.js +4 -7
  56. package/dist/hdhr/channelMap.js.map +1 -1
  57. package/dist/hdhr/discover.js +7 -15
  58. package/dist/hdhr/discover.js.map +1 -1
  59. package/dist/hdhr/index.js +6 -9
  60. package/dist/hdhr/index.js.map +1 -1
  61. package/dist/native/index.d.ts +2 -2
  62. package/dist/native/index.js +17 -27
  63. package/dist/native/index.js.map +1 -1
  64. package/dist/native/intercept.js +86 -89
  65. package/dist/native/intercept.js.map +1 -1
  66. package/dist/native/probe.js +2 -2
  67. package/dist/native/probe.js.map +1 -1
  68. package/dist/native/proxy.d.ts +2 -2
  69. package/dist/native/proxy.js +4 -4
  70. package/dist/native/proxy.js.map +1 -1
  71. package/dist/routes/assets.js +29 -51
  72. package/dist/routes/assets.js.map +1 -1
  73. package/dist/routes/auth.js +3 -3
  74. package/dist/routes/auth.js.map +1 -1
  75. package/dist/routes/channels.js +5 -11
  76. package/dist/routes/channels.js.map +1 -1
  77. package/dist/routes/components.d.ts +0 -8
  78. package/dist/routes/components.js +0 -19
  79. package/dist/routes/components.js.map +1 -1
  80. package/dist/routes/config/channels/index.d.ts +1 -1
  81. package/dist/routes/config/channels/index.js +1 -1
  82. package/dist/routes/config/channels/index.js.map +1 -1
  83. package/dist/routes/config/channels/routes.js +748 -420
  84. package/dist/routes/config/channels/routes.js.map +1 -1
  85. package/dist/routes/config/channels/table.d.ts +21 -6
  86. package/dist/routes/config/channels/table.js +456 -193
  87. package/dist/routes/config/channels/table.js.map +1 -1
  88. package/dist/routes/config/index.d.ts +2 -2
  89. package/dist/routes/config/index.js +3 -3
  90. package/dist/routes/config/index.js.map +1 -1
  91. package/dist/routes/config/{providers.js → services.js} +47 -42
  92. package/dist/routes/config/services.js.map +1 -0
  93. package/dist/routes/config/settings.js +88 -49
  94. package/dist/routes/config/settings.js.map +1 -1
  95. package/dist/routes/debug.js +5 -7
  96. package/dist/routes/debug.js.map +1 -1
  97. package/dist/routes/health.js +1 -1
  98. package/dist/routes/health.js.map +1 -1
  99. package/dist/routes/icons.d.ts +16 -0
  100. package/dist/routes/icons.js +44 -0
  101. package/dist/routes/icons.js.map +1 -0
  102. package/dist/routes/index.js +2 -2
  103. package/dist/routes/index.js.map +1 -1
  104. package/dist/routes/logs.js +4 -4
  105. package/dist/routes/logs.js.map +1 -1
  106. package/dist/routes/playlist.d.ts +6 -4
  107. package/dist/routes/playlist.js +98 -45
  108. package/dist/routes/playlist.js.map +1 -1
  109. package/dist/routes/root/content.js +94 -55
  110. package/dist/routes/root/content.js.map +1 -1
  111. package/dist/routes/root/scripts/channels.js +620 -478
  112. package/dist/routes/root/scripts/channels.js.map +1 -1
  113. package/dist/routes/root/scripts/config.js +884 -964
  114. package/dist/routes/root/scripts/config.js.map +1 -1
  115. package/dist/routes/root/scripts/shared.js +468 -188
  116. package/dist/routes/root/scripts/shared.js.map +1 -1
  117. package/dist/routes/root/scripts/status.js +252 -207
  118. package/dist/routes/root/scripts/status.js.map +1 -1
  119. package/dist/routes/root/styles.js +57 -8
  120. package/dist/routes/root/styles.js.map +1 -1
  121. package/dist/routes/services.d.ts +6 -0
  122. package/dist/routes/{providers.js → services.js} +43 -43
  123. package/dist/routes/services.js.map +1 -0
  124. package/dist/routes/ui.d.ts +1 -1
  125. package/dist/routes/ui.js +3 -1
  126. package/dist/routes/ui.js.map +1 -1
  127. package/dist/service/commands.js +8 -43
  128. package/dist/service/commands.js.map +1 -1
  129. package/dist/service/generators.d.ts +1 -1
  130. package/dist/service/generators.js +143 -41
  131. package/dist/service/generators.js.map +1 -1
  132. package/dist/streaming/codec.d.ts +20 -0
  133. package/dist/streaming/codec.js +68 -0
  134. package/dist/streaming/codec.js.map +1 -0
  135. package/dist/streaming/fmp4Segmenter.d.ts +2 -2
  136. package/dist/streaming/fmp4Segmenter.js.map +1 -1
  137. package/dist/streaming/hls.d.ts +4 -4
  138. package/dist/streaming/hls.js +35 -29
  139. package/dist/streaming/hls.js.map +1 -1
  140. package/dist/streaming/hlsResume.js +3 -3
  141. package/dist/streaming/hlsResume.js.map +1 -1
  142. package/dist/streaming/monitor.d.ts +2 -2
  143. package/dist/streaming/monitor.js +19 -13
  144. package/dist/streaming/monitor.js.map +1 -1
  145. package/dist/streaming/preroll.d.ts +15 -14
  146. package/dist/streaming/preroll.js +32 -12
  147. package/dist/streaming/preroll.js.map +1 -1
  148. package/dist/streaming/registry.d.ts +2 -2
  149. package/dist/streaming/registry.js +4 -8
  150. package/dist/streaming/registry.js.map +1 -1
  151. package/dist/streaming/setup.d.ts +4 -4
  152. package/dist/streaming/setup.js +28 -34
  153. package/dist/streaming/setup.js.map +1 -1
  154. package/dist/streaming/showInfo.js +8 -10
  155. package/dist/streaming/showInfo.js.map +1 -1
  156. package/dist/streaming/statusEmitter.d.ts +4 -3
  157. package/dist/streaming/statusEmitter.js +3 -3
  158. package/dist/streaming/statusEmitter.js.map +1 -1
  159. package/dist/types/channels.d.ts +18 -11
  160. package/dist/types/config.d.ts +3 -2
  161. package/dist/types/index.d.ts +4 -3
  162. package/dist/types/index.js +1 -0
  163. package/dist/types/index.js.map +1 -1
  164. package/dist/types/profiles.d.ts +9 -9
  165. package/dist/types/selection.d.ts +1 -1
  166. package/dist/types/shared.d.ts +1 -1
  167. package/dist/types/streaming.d.ts +8 -16
  168. package/dist/types/streaming.js +5 -1
  169. package/dist/types/streaming.js.map +1 -1
  170. package/dist/upgrade/commands.js +1 -16
  171. package/dist/upgrade/commands.js.map +1 -1
  172. package/dist/utils/chromeFetch.js +1 -1
  173. package/dist/utils/cliOutput.d.ts +10 -0
  174. package/dist/utils/cliOutput.js +17 -0
  175. package/dist/utils/cliOutput.js.map +1 -0
  176. package/dist/utils/debugFilter.js +3 -3
  177. package/dist/utils/debugFilter.js.map +1 -1
  178. package/dist/utils/fileLogger.js +4 -3
  179. package/dist/utils/fileLogger.js.map +1 -1
  180. package/dist/utils/format.d.ts +21 -4
  181. package/dist/utils/format.js +45 -7
  182. package/dist/utils/format.js.map +1 -1
  183. package/dist/utils/index.d.ts +1 -0
  184. package/dist/utils/index.js +1 -0
  185. package/dist/utils/index.js.map +1 -1
  186. package/dist/utils/logger.js +17 -27
  187. package/dist/utils/logger.js.map +1 -1
  188. package/dist/utils/morganStream.js +2 -2
  189. package/dist/utils/morganStream.js.map +1 -1
  190. package/dist/utils/platform.js +3 -2
  191. package/dist/utils/platform.js.map +1 -1
  192. package/dist/utils/retry.js +2 -4
  193. package/dist/utils/retry.js.map +1 -1
  194. package/dist/utils/streamContext.d.ts +7 -0
  195. package/dist/utils/streamContext.js +10 -1
  196. package/dist/utils/streamContext.js.map +1 -1
  197. package/dist/utils/version.js +4 -4
  198. package/dist/utils/version.js.map +1 -1
  199. package/package.json +5 -7
  200. package/dist/config/providerPacks.d.ts +0 -46
  201. package/dist/config/providerPacks.js.map +0 -1
  202. package/dist/config/providers.d.ts +0 -175
  203. package/dist/config/providers.js +0 -678
  204. package/dist/config/providers.js.map +0 -1
  205. package/dist/routes/config/providers.js.map +0 -1
  206. package/dist/routes/providers.d.ts +0 -6
  207. package/dist/routes/providers.js.map +0 -1
  208. /package/dist/routes/config/{providers.d.ts → services.d.ts} +0 -0
@@ -1,25 +1,33 @@
1
- // Site provider key. When a channel has its own streaming website, this key is used in the providers map. The site provider always wins as canonical.
1
+ // Channel identity fields — metadata that describes the channel itself, independent of which service serves it. This is the single source of truth for the
2
+ // identity/service-specific field separation used by: (1) applyVariantInheritance in services.ts (identity fields always come from the canonical),
3
+ // (2) startup migration in userChannels.ts (strips legacy identity fields from variant entries), and (3) DELTA_ALLOWED_FIELDS derivation (identity +
4
+ // service-specific editable fields). Adding a new identity field here automatically propagates to all three consumers.
5
+ export const CHANNEL_IDENTITY_FIELDS = new Set(["channelNumber", "guideTitle", "hdhrEnabled", "logoUrl", "name", "stationId", "tags", "tvgShift"]);
6
+ // Predefined tag vocabulary. These tags ship with PrismCast and are assigned to predefined channel definitions below. Users can delete predefined tags from
7
+ // their registry (they're tracked in channels.json deletedTags) and create their own tags. The runtime vocabulary is: (PREDEFINED_TAGS - deletedTags) + userTags.
8
+ export const PREDEFINED_TAGS = ["Documentary", "Entertainment", "HBO", "Kids", "Lifestyle", "Local", "Movies", "News", "Showtime", "Sports", "Starz"];
9
+ // Site service key. When a channel has its own streaming website, this key is used in the services map. The site service always wins as canonical.
2
10
  const SITE_KEY = "site";
3
- /* Nested channel definitions. Each entry maps a channel key to a ChannelDefinition with identity fields (name, stationId) and a providers map keyed by provider
4
- * slug. The "site" key represents the channel's own streaming website. All other keys are multi-provider platform slugs (cox, directv, hulu, sling, spectrum,
11
+ /* Nested channel definitions. Each entry maps a channel key to a ChannelDefinition with identity fields (name, stationId) and a services map keyed by service
12
+ * slug. The "site" key represents the channel's own streaming website. All other keys are multi-service platform slugs (cox, directv, hulu, sling, spectrum,
5
13
  * xfinity, yttv, foxone, paramountplus).
6
14
  *
7
15
  * At module load, the flattener compiles these nested definitions into the flat ChannelMap consumed by the rest of the codebase. Each variant entry gets
8
- * canonicalKey set to its parent definition's key, which buildProviderGroups in providers.ts uses to assemble provider groups.
16
+ * canonicalKey set to its parent definition's key, which buildServiceGroups in services.ts uses to assemble service groups.
9
17
  *
10
18
  * Canonical resolution rules:
11
- * 1. If "site" exists in providers, the canonical always gets the site URL.
12
- * 2. Otherwise, the provider whose key sorts first alphabetically (computed, not source-order) becomes canonical.
19
+ * 1. If "site" exists in services, the canonical always gets the site URL.
20
+ * 2. Otherwise, the service whose key sorts first alphabetically (computed, not source-order) becomes canonical.
13
21
  *
14
- * Adding a new provider never changes canonicals unless a "site" entry is introduced.
22
+ * Adding a new service never changes canonicals unless a "site" entry is introduced.
15
23
  *
16
24
  * Pacific timezone support:
17
25
  * - pacificStationId on an East ChannelDefinition triggers auto-generation of a Pacific sibling.
18
26
  * - Manual Pacific definitions (keys ending in "p") can pre-declare overrides (e.g., West-specific channelSelectors).
19
- * - Pacific generation merges inherited providers from the East definition into the Pacific definition, skipping providers whose channelSelector contains
20
- * "East" or "West" and never overwriting existing Pacific providers. See generatePacificDefinitions() for full rules.
27
+ * - Pacific generation merges inherited services from the East definition into the Pacific definition, skipping services whose channelSelector contains
28
+ * "East" or "West" and never overwriting existing Pacific services. See generatePacificDefinitions() for full rules.
21
29
  *
22
- * FAST channels: This list contains only traditional linear TV networks and public broadcasters — no FAST (Free Ad-Supported Streaming Television) channels.
30
+ * FAST channels: This list contains only traditional linear TV networks and public broadcasters - no FAST (Free Ad-Supported Streaming Television) channels.
23
31
  * FAST channels from platforms like Pluto TV or Tubi should not be added here. Users who want FAST content can add them as user-defined channels through the
24
32
  * web UI or user channels file, or preferably use dedicated high-quality integrations such as Plex Channels, Pluto for Channels, or Tubi for Channels.
25
33
  */
@@ -27,7 +35,8 @@ const SITE_KEY = "site";
27
35
  const BASE_CHANNEL_DEFINITIONS = {
28
36
  abc: {
29
37
  name: "ABC",
30
- providers: {
38
+ tags: ["Local"],
39
+ services: {
31
40
  cox: { channelSelector: "ABC", url: "https://watchtv.cox.com/listings" },
32
41
  directv: { channelSelector: "ABC", url: "https://stream.directv.com" },
33
42
  hulu: { channelSelector: "ABC", url: "https://www.hulu.com/live" },
@@ -40,8 +49,9 @@ const BASE_CHANNEL_DEFINITIONS = {
40
49
  },
41
50
  abcnews: {
42
51
  name: "ABC News Live",
52
+ tags: ["News"],
43
53
  stationId: "113380",
44
- providers: {
54
+ services: {
45
55
  cox: { channelSelector: "ABCNL", url: "https://watchtv.cox.com/listings" },
46
56
  directv: { channelSelector: "ABC News Live", url: "https://stream.directv.com" },
47
57
  hulu: { channelSelector: "ABC News Live", url: "https://www.hulu.com/live" },
@@ -52,9 +62,10 @@ const BASE_CHANNEL_DEFINITIONS = {
52
62
  },
53
63
  ae: {
54
64
  name: "A&E",
65
+ tags: ["Documentary", "Entertainment"],
55
66
  pacificStationId: "57439",
56
67
  stationId: "51529",
57
- providers: {
68
+ services: {
58
69
  cox: { channelSelector: "A&E", url: "https://watchtv.cox.com/listings" },
59
70
  directv: { channelSelector: "A&E", url: "https://stream.directv.com" },
60
71
  hulu: { channelSelector: "A&E", url: "https://www.hulu.com/live" },
@@ -67,8 +78,9 @@ const BASE_CHANNEL_DEFINITIONS = {
67
78
  },
68
79
  ahc: {
69
80
  name: "American Heroes",
81
+ tags: ["Documentary"],
70
82
  stationId: "78808",
71
- providers: {
83
+ services: {
72
84
  cox: { channelSelector: "American Heroes", url: "https://watchtv.cox.com/listings" },
73
85
  site: { url: "https://watch.foodnetwork.com/channel/ahc" },
74
86
  spectrum: { channelSelector: "American Heroes Channel", url: "https://watch.spectrum.net/guide" },
@@ -77,9 +89,10 @@ const BASE_CHANNEL_DEFINITIONS = {
77
89
  },
78
90
  amc: {
79
91
  name: "AMC",
92
+ tags: ["Entertainment", "Movies"],
80
93
  pacificStationId: "78836",
81
94
  stationId: "59337",
82
- providers: {
95
+ services: {
83
96
  cox: { channelSelector: "AMC", url: "https://watchtv.cox.com/listings" },
84
97
  directv: { channelSelector: "AMC", url: "https://stream.directv.com" },
85
98
  sling: { channelSelector: "AMC", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
@@ -90,17 +103,19 @@ const BASE_CHANNEL_DEFINITIONS = {
90
103
  },
91
104
  amcthrillers: {
92
105
  name: "AMC Thrillers",
106
+ tags: ["Entertainment", "Movies"],
93
107
  stationId: "115678",
94
- providers: {
108
+ services: {
95
109
  sling: { channelSelector: "AMC Thrillers", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
96
110
  yttv: { channelSelector: "AMC Thrillers", url: "https://tv.youtube.com/live" },
97
111
  },
98
112
  },
99
113
  animal: {
100
114
  name: "Animal Planet",
115
+ tags: ["Documentary"],
101
116
  pacificStationId: "68785",
102
117
  stationId: "57394",
103
- providers: {
118
+ services: {
104
119
  cox: { channelSelector: "Animal Planet", url: "https://watchtv.cox.com/listings" },
105
120
  directv: { channelSelector: "Animal Planet", url: "https://stream.directv.com" },
106
121
  hulu: { channelSelector: "Animal Planet", url: "https://www.hulu.com/live" },
@@ -112,8 +127,9 @@ const BASE_CHANNEL_DEFINITIONS = {
112
127
  },
113
128
  axstv: {
114
129
  name: "AXS TV",
130
+ tags: ["Entertainment", "Sports"],
115
131
  stationId: "28506",
116
- providers: {
132
+ services: {
117
133
  cox: { channelSelector: "AXS TV", url: "https://watchtv.cox.com/listings" },
118
134
  directv: { channelSelector: "AXS TV", url: "https://stream.directv.com" },
119
135
  spectrum: { channelSelector: "AXS TV", url: "https://watch.spectrum.net/guide" },
@@ -122,9 +138,10 @@ const BASE_CHANNEL_DEFINITIONS = {
122
138
  },
123
139
  bbcamerica: {
124
140
  name: "BBC America",
141
+ tags: ["Entertainment"],
125
142
  pacificStationId: "76739",
126
143
  stationId: "64492",
127
- providers: {
144
+ services: {
128
145
  cox: { channelSelector: "BBC America", url: "https://watchtv.cox.com/listings" },
129
146
  directv: { channelSelector: "BBC America", url: "https://stream.directv.com" },
130
147
  sling: { channelSelector: "BBC America", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
@@ -135,8 +152,9 @@ const BASE_CHANNEL_DEFINITIONS = {
135
152
  },
136
153
  bbcnews: {
137
154
  name: "BBC News (North America)",
155
+ tags: ["News"],
138
156
  stationId: "101449",
139
- providers: {
157
+ services: {
140
158
  cox: { channelSelector: "BBC News", url: "https://watchtv.cox.com/listings" },
141
159
  directv: { channelSelector: "BBC News", url: "https://stream.directv.com" },
142
160
  sling: { channelSelector: "BBC News", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
@@ -147,9 +165,10 @@ const BASE_CHANNEL_DEFINITIONS = {
147
165
  },
148
166
  bet: {
149
167
  name: "BET",
168
+ tags: ["Entertainment"],
150
169
  pacificStationId: "64673",
151
170
  stationId: "63236",
152
- providers: {
171
+ services: {
153
172
  cox: { channelSelector: "BET", url: "https://watchtv.cox.com/listings" },
154
173
  directv: { channelSelector: "BET", url: "https://stream.directv.com" },
155
174
  hulu: { channelSelector: "BET", url: "https://www.hulu.com/live" },
@@ -162,9 +181,10 @@ const BASE_CHANNEL_DEFINITIONS = {
162
181
  },
163
182
  bether: {
164
183
  name: "BET Her",
184
+ tags: ["Entertainment"],
165
185
  pacificStationId: "97360",
166
186
  stationId: "63220",
167
- providers: {
187
+ services: {
168
188
  cox: { channelSelector: "BET Her", url: "https://watchtv.cox.com/listings" },
169
189
  directv: { channelSelector: "BET Her", url: "https://stream.directv.com" },
170
190
  spectrum: { channelSelector: "BET Her", url: "https://watch.spectrum.net/guide" },
@@ -174,8 +194,9 @@ const BASE_CHANNEL_DEFINITIONS = {
174
194
  },
175
195
  bigten: {
176
196
  name: "Big 10",
197
+ tags: ["Sports"],
177
198
  stationId: "58321",
178
- providers: {
199
+ services: {
179
200
  cox: { channelSelector: "Big Ten Network", url: "https://watchtv.cox.com/listings" },
180
201
  directv: { channelSelector: "Big Ten", url: "https://stream.directv.com" },
181
202
  foxone: { channelSelector: "BTN", url: "https://www.fox.com/live/channels" },
@@ -188,8 +209,9 @@ const BASE_CHANNEL_DEFINITIONS = {
188
209
  },
189
210
  bloomberg: {
190
211
  name: "Bloomberg Television",
212
+ tags: ["News"],
191
213
  stationId: "71799",
192
- providers: {
214
+ services: {
193
215
  cox: { channelSelector: "Bloomberg", url: "https://watchtv.cox.com/listings" },
194
216
  directv: { channelSelector: "Bloomberg TV", url: "https://stream.directv.com" },
195
217
  hulu: { channelSelector: "Bloomberg Television", url: "https://www.hulu.com/live" },
@@ -201,15 +223,17 @@ const BASE_CHANNEL_DEFINITIONS = {
201
223
  },
202
224
  bloombergoriginals: {
203
225
  name: "Bloomberg Originals",
226
+ tags: ["News"],
204
227
  stationId: "175656",
205
- providers: {
228
+ services: {
206
229
  yttv: { channelSelector: "Bloomberg Originals", url: "https://tv.youtube.com/live" },
207
230
  },
208
231
  },
209
232
  bravo: {
210
233
  name: "Bravo",
234
+ tags: ["Entertainment"],
211
235
  stationId: "58625",
212
- providers: {
236
+ services: {
213
237
  cox: { channelSelector: "Bravo", url: "https://watchtv.cox.com/listings" },
214
238
  directv: { channelSelector: "Bravo", url: "https://stream.directv.com" },
215
239
  hulu: { channelSelector: "Bravo", url: "https://www.hulu.com/live" },
@@ -222,16 +246,18 @@ const BASE_CHANNEL_DEFINITIONS = {
222
246
  },
223
247
  bravop: {
224
248
  name: "Bravo (Pacific)",
249
+ tags: ["Entertainment"],
225
250
  stationId: "73994",
226
- providers: {
251
+ services: {
227
252
  site: { url: "https://www.nbc.com/live?brand=bravo&callsign=bravo_west" },
228
253
  },
229
254
  },
230
255
  cartoon: {
231
256
  name: "Cartoon Network",
257
+ tags: ["Kids"],
232
258
  pacificStationId: "67703",
233
259
  stationId: "60048",
234
- providers: {
260
+ services: {
235
261
  cox: { channelSelector: "Cartoon Network", url: "https://watchtv.cox.com/listings" },
236
262
  directv: { channelSelector: "Cartoon Network", url: "https://stream.directv.com" },
237
263
  hulu: { channelSelector: "Cartoon Network (East)", url: "https://www.hulu.com/live" },
@@ -242,14 +268,16 @@ const BASE_CHANNEL_DEFINITIONS = {
242
268
  },
243
269
  cartoonp: {
244
270
  name: "Cartoon Network (Pacific)",
271
+ tags: ["Kids"],
245
272
  stationId: "67703",
246
- providers: {
273
+ services: {
247
274
  hulu: { channelSelector: "Cartoon Network (West)", url: "https://www.hulu.com/live" },
248
275
  },
249
276
  },
250
277
  cbs: {
251
278
  name: "CBS",
252
- providers: {
279
+ tags: ["Local"],
280
+ services: {
253
281
  cox: { channelSelector: "CBS", url: "https://watchtv.cox.com/listings" },
254
282
  directv: { channelSelector: "CBS", url: "https://stream.directv.com" },
255
283
  hulu: { channelSelector: "CBS", url: "https://www.hulu.com/live" },
@@ -262,16 +290,18 @@ const BASE_CHANNEL_DEFINITIONS = {
262
290
  },
263
291
  cbsnews: {
264
292
  name: "CBS News 24/7",
293
+ tags: ["News"],
265
294
  stationId: "104846",
266
- providers: {
295
+ services: {
267
296
  hulu: { channelSelector: "CBS News 24/7", url: "https://www.hulu.com/live" },
268
297
  sling: { channelSelector: "CBS News 24/7", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
269
298
  },
270
299
  },
271
300
  cbssports: {
272
301
  name: "CBS Sports Network",
302
+ tags: ["Sports"],
273
303
  stationId: "59250",
274
- providers: {
304
+ services: {
275
305
  cox: { channelSelector: "CBS Sports Network", url: "https://watchtv.cox.com/listings" },
276
306
  hulu: { channelSelector: "CBS Sports Network", url: "https://www.hulu.com/live" },
277
307
  spectrum: { channelSelector: "CBS Sports Network", url: "https://watch.spectrum.net/guide" },
@@ -281,9 +311,10 @@ const BASE_CHANNEL_DEFINITIONS = {
281
311
  },
282
312
  cmt: {
283
313
  name: "CMT",
314
+ tags: ["Entertainment"],
284
315
  pacificStationId: "64610",
285
316
  stationId: "59440",
286
- providers: {
317
+ services: {
287
318
  cox: { channelSelector: "CMT", url: "https://watchtv.cox.com/listings" },
288
319
  directv: { channelSelector: "CMT", url: "https://stream.directv.com" },
289
320
  hulu: { channelSelector: "CMT", url: "https://www.hulu.com/live" },
@@ -294,8 +325,9 @@ const BASE_CHANNEL_DEFINITIONS = {
294
325
  },
295
326
  cnbc: {
296
327
  name: "CNBC",
328
+ tags: ["News"],
297
329
  stationId: "58780",
298
- providers: {
330
+ services: {
299
331
  cox: { channelSelector: "CNBC", url: "https://watchtv.cox.com/listings" },
300
332
  directv: { channelSelector: "CNBC", url: "https://stream.directv.com" },
301
333
  hulu: { channelSelector: "CNBC", url: "https://www.hulu.com/live" },
@@ -308,16 +340,18 @@ const BASE_CHANNEL_DEFINITIONS = {
308
340
  },
309
341
  cnbcworld: {
310
342
  name: "CNBC World",
343
+ tags: ["News"],
311
344
  stationId: "26849",
312
- providers: {
345
+ services: {
313
346
  directv: { channelSelector: "CNBC World", url: "https://stream.directv.com" },
314
347
  spectrum: { channelSelector: "CNBC World", url: "https://watch.spectrum.net/guide" },
315
348
  },
316
349
  },
317
350
  cnn: {
318
351
  name: "CNN",
352
+ tags: ["News"],
319
353
  stationId: "58646",
320
- providers: {
354
+ services: {
321
355
  cox: { channelSelector: "CNN", url: "https://watchtv.cox.com/listings" },
322
356
  directv: { channelSelector: "CNN", url: "https://stream.directv.com" },
323
357
  hulu: { channelSelector: "CNN", url: "https://www.hulu.com/live" },
@@ -330,8 +364,9 @@ const BASE_CHANNEL_DEFINITIONS = {
330
364
  },
331
365
  cnni: {
332
366
  name: "CNN International",
367
+ tags: ["News"],
333
368
  stationId: "83110",
334
- providers: {
369
+ services: {
335
370
  directv: { channelSelector: "CNNi HD East", url: "https://stream.directv.com" },
336
371
  hulu: { channelSelector: "CNN International", url: "https://www.hulu.com/live" },
337
372
  site: { url: "https://www.cnn.com/videos/cnn-i" },
@@ -340,9 +375,10 @@ const BASE_CHANNEL_DEFINITIONS = {
340
375
  },
341
376
  comedycentral: {
342
377
  name: "Comedy Central",
378
+ tags: ["Entertainment"],
343
379
  pacificStationId: "64599",
344
380
  stationId: "62420",
345
- providers: {
381
+ services: {
346
382
  cox: { channelSelector: "Comedy Central", url: "https://watchtv.cox.com/listings" },
347
383
  directv: { channelSelector: "Comedy Central", url: "https://stream.directv.com" },
348
384
  hulu: { channelSelector: "Comedy Central", url: "https://www.hulu.com/live" },
@@ -354,8 +390,9 @@ const BASE_CHANNEL_DEFINITIONS = {
354
390
  },
355
391
  cooking: {
356
392
  name: "Cooking",
393
+ tags: ["Lifestyle"],
357
394
  stationId: "68065",
358
- providers: {
395
+ services: {
359
396
  cox: { channelSelector: "Cooking Channel", url: "https://watchtv.cox.com/listings" },
360
397
  directv: { channelSelector: "Cooking Channel", url: "https://stream.directv.com" },
361
398
  site: { url: "https://watch.foodnetwork.com/channel/cooking-channel" },
@@ -365,8 +402,9 @@ const BASE_CHANNEL_DEFINITIONS = {
365
402
  },
366
403
  cspan: {
367
404
  name: "C-SPAN",
405
+ tags: ["News"],
368
406
  stationId: "68344",
369
- providers: {
407
+ services: {
370
408
  cox: { channelSelector: "C-SPAN", url: "https://watchtv.cox.com/listings" },
371
409
  directv: { channelSelector: "C-SPAN", url: "https://stream.directv.com" },
372
410
  hulu: { channelSelector: "C-SPAN", url: "https://www.hulu.com/live" },
@@ -378,8 +416,9 @@ const BASE_CHANNEL_DEFINITIONS = {
378
416
  },
379
417
  cspan2: {
380
418
  name: "C-SPAN 2",
419
+ tags: ["News"],
381
420
  stationId: "68334",
382
- providers: {
421
+ services: {
383
422
  cox: { channelSelector: "CPN2D", url: "https://watchtv.cox.com/listings" },
384
423
  directv: { channelSelector: "C-SPAN2", url: "https://stream.directv.com" },
385
424
  hulu: { channelSelector: "C-SPAN2", url: "https://www.hulu.com/live" },
@@ -391,8 +430,9 @@ const BASE_CHANNEL_DEFINITIONS = {
391
430
  },
392
431
  cspan3: {
393
432
  name: "C-SPAN 3",
433
+ tags: ["News"],
394
434
  stationId: "68332",
395
- providers: {
435
+ services: {
396
436
  cox: { channelSelector: "CPN3H", url: "https://watchtv.cox.com/listings" },
397
437
  hulu: { channelSelector: "C-SPAN3", url: "https://www.hulu.com/live" },
398
438
  site: { url: "https://www.c-span.org/networks/?autoplay=true&channel=c-span-3" },
@@ -403,7 +443,8 @@ const BASE_CHANNEL_DEFINITIONS = {
403
443
  },
404
444
  cw: {
405
445
  name: "CW",
406
- providers: {
446
+ tags: ["Local"],
447
+ services: {
407
448
  cox: { channelSelector: "CW TV", url: "https://watchtv.cox.com/listings" },
408
449
  directv: { channelSelector: "CW", url: "https://stream.directv.com" },
409
450
  hulu: { channelSelector: "CW", url: "https://www.hulu.com/live" },
@@ -412,11 +453,24 @@ const BASE_CHANNEL_DEFINITIONS = {
412
453
  yttv: { channelSelector: "CW", url: "https://tv.youtube.com/live" },
413
454
  },
414
455
  },
456
+ destinationamerica: {
457
+ name: "Destination America",
458
+ tags: ["Documentary"],
459
+ stationId: "60468",
460
+ services: {
461
+ cox: { channelSelector: "Destination America", url: "https://watchtv.cox.com/listings" },
462
+ directv: { channelSelector: "Destination America HD", url: "https://stream.directv.com" },
463
+ site: { url: "https://watch.foodnetwork.com/channel/destination-america" },
464
+ spectrum: { channelSelector: "Destination America", url: "https://watch.spectrum.net/guide" },
465
+ xfinity: { channelSelector: "Destination America", url: "https://www.xfinity.com/stream/listings" },
466
+ },
467
+ },
415
468
  discovery: {
416
469
  name: "Discovery",
470
+ tags: ["Documentary"],
417
471
  pacificStationId: "80399",
418
472
  stationId: "56905",
419
- providers: {
473
+ services: {
420
474
  cox: { channelSelector: "Discovery Channel", url: "https://watchtv.cox.com/listings" },
421
475
  directv: { channelSelector: "Discovery", url: "https://stream.directv.com" },
422
476
  hulu: { channelSelector: "Discovery", url: "https://www.hulu.com/live" },
@@ -429,8 +483,9 @@ const BASE_CHANNEL_DEFINITIONS = {
429
483
  },
430
484
  discoverylife: {
431
485
  name: "Discovery Life",
486
+ tags: ["Documentary"],
432
487
  stationId: "92204",
433
- providers: {
488
+ services: {
434
489
  cox: { channelSelector: "Discovery Life", url: "https://watchtv.cox.com/listings" },
435
490
  directv: { channelSelector: "Discovery Life", url: "https://stream.directv.com" },
436
491
  site: { url: "https://watch.foodnetwork.com/channel/discovery-life" },
@@ -440,8 +495,9 @@ const BASE_CHANNEL_DEFINITIONS = {
440
495
  },
441
496
  discoveryturbo: {
442
497
  name: "Discovery Turbo",
498
+ tags: ["Documentary"],
443
499
  stationId: "31046",
444
- providers: {
500
+ services: {
445
501
  cox: { channelSelector: "Discovery Turbo", url: "https://watchtv.cox.com/listings" },
446
502
  directv: { channelSelector: "Discovery Turbo", url: "https://stream.directv.com" },
447
503
  hulu: { channelSelector: "Discovery Turbo", url: "https://www.hulu.com/live" },
@@ -454,9 +510,10 @@ const BASE_CHANNEL_DEFINITIONS = {
454
510
  },
455
511
  disney: {
456
512
  name: "Disney",
513
+ tags: ["Kids"],
457
514
  pacificStationId: "63320",
458
515
  stationId: "59684",
459
- providers: {
516
+ services: {
460
517
  cox: { channelSelector: "Disney Channel", url: "https://watchtv.cox.com/listings" },
461
518
  directv: { channelSelector: "Disney Channel", url: "https://stream.directv.com" },
462
519
  hulu: { channelSelector: "Disney Channel", url: "https://www.hulu.com/live" },
@@ -469,9 +526,10 @@ const BASE_CHANNEL_DEFINITIONS = {
469
526
  },
470
527
  disneyjr: {
471
528
  name: "Disney Jr.",
529
+ tags: ["Kids"],
472
530
  pacificStationId: "75004",
473
531
  stationId: "74885",
474
- providers: {
532
+ services: {
475
533
  cox: { channelSelector: "Disney Jr.", url: "https://watchtv.cox.com/listings" },
476
534
  directv: { channelSelector: "Disney Junior", url: "https://stream.directv.com" },
477
535
  hulu: { channelSelector: "Disney Junior", url: "https://www.hulu.com/live" },
@@ -483,9 +541,10 @@ const BASE_CHANNEL_DEFINITIONS = {
483
541
  },
484
542
  disneyxd: {
485
543
  name: "Disney XD",
544
+ tags: ["Kids"],
486
545
  pacificStationId: "63322",
487
546
  stationId: "60006",
488
- providers: {
547
+ services: {
489
548
  cox: { channelSelector: "Disney XD", url: "https://watchtv.cox.com/listings" },
490
549
  hulu: { channelSelector: "Disney XD", url: "https://www.hulu.com/live" },
491
550
  site: { url: "https://disneynow.com/watch-live?brand=009" },
@@ -496,8 +555,9 @@ const BASE_CHANNEL_DEFINITIONS = {
496
555
  },
497
556
  e: {
498
557
  name: "E!",
558
+ tags: ["Entertainment"],
499
559
  stationId: "61812",
500
- providers: {
560
+ services: {
501
561
  cox: { channelSelector: "E!", url: "https://watchtv.cox.com/listings" },
502
562
  directv: { channelSelector: "E!", url: "https://stream.directv.com" },
503
563
  hulu: { channelSelector: "E!", url: "https://www.hulu.com/live" },
@@ -510,15 +570,17 @@ const BASE_CHANNEL_DEFINITIONS = {
510
570
  },
511
571
  ep: {
512
572
  name: "E! (Pacific)",
573
+ tags: ["Entertainment"],
513
574
  stationId: "91579",
514
- providers: {
575
+ services: {
515
576
  site: { channelSelector: "E-_West", url: "https://www.usanetwork.com/live" },
516
577
  },
517
578
  },
518
579
  espn: {
519
580
  name: "ESPN",
581
+ tags: ["Sports"],
520
582
  stationId: "32645",
521
- providers: {
583
+ services: {
522
584
  cox: { channelSelector: "ESPN", url: "https://watchtv.cox.com/listings" },
523
585
  directv: { channelSelector: "ESPN", url: "https://stream.directv.com" },
524
586
  disneyplus: { channelSelector: "poster_linear_espn_none", url: "https://www.disneyplus.com/browse/live" },
@@ -532,8 +594,9 @@ const BASE_CHANNEL_DEFINITIONS = {
532
594
  },
533
595
  espn2: {
534
596
  name: "ESPN2",
597
+ tags: ["Sports"],
535
598
  stationId: "45507",
536
- providers: {
599
+ services: {
537
600
  cox: { channelSelector: "ES2HD", url: "https://watchtv.cox.com/listings" },
538
601
  directv: { channelSelector: "ESPN2", url: "https://stream.directv.com" },
539
602
  disneyplus: { channelSelector: "poster_linear_espn2_none", url: "https://www.disneyplus.com/browse/live" },
@@ -547,8 +610,9 @@ const BASE_CHANNEL_DEFINITIONS = {
547
610
  },
548
611
  espnacc: {
549
612
  name: "ACC Network",
613
+ tags: ["Sports"],
550
614
  stationId: "111871",
551
- providers: {
615
+ services: {
552
616
  cox: { channelSelector: "ACC Network", url: "https://watchtv.cox.com/listings" },
553
617
  directv: { channelSelector: "ACC Network", url: "https://stream.directv.com" },
554
618
  disneyplus: { channelSelector: "poster_linear_acc-network_none", url: "https://www.disneyplus.com/browse/live" },
@@ -561,8 +625,9 @@ const BASE_CHANNEL_DEFINITIONS = {
561
625
  },
562
626
  espndeportes: {
563
627
  name: "ESPN Deportes",
628
+ tags: ["Sports"],
564
629
  stationId: "71914",
565
- providers: {
630
+ services: {
566
631
  cox: { channelSelector: "ESPN Deportes", url: "https://watchtv.cox.com/listings" },
567
632
  disneyplus: { channelSelector: "poster_linear_espn-deportes_none", url: "https://www.disneyplus.com/browse/live" },
568
633
  site: { url: "https://www.espn.com/watch/player?network=espndeportes" },
@@ -573,8 +638,9 @@ const BASE_CHANNEL_DEFINITIONS = {
573
638
  },
574
639
  espnews: {
575
640
  name: "ESPNews",
641
+ tags: ["Sports"],
576
642
  stationId: "59976",
577
- providers: {
643
+ services: {
578
644
  cox: { channelSelector: "ESWHD", url: "https://watchtv.cox.com/listings" },
579
645
  directv: { channelSelector: "ESPNews", url: "https://stream.directv.com" },
580
646
  disneyplus: { channelSelector: "poster_linear_espnews_none", url: "https://www.disneyplus.com/browse/live" },
@@ -587,8 +653,9 @@ const BASE_CHANNEL_DEFINITIONS = {
587
653
  },
588
654
  espnsec: {
589
655
  name: "SEC Network",
656
+ tags: ["Sports"],
590
657
  stationId: "89714",
591
- providers: {
658
+ services: {
592
659
  cox: { channelSelector: "SEC", url: "https://watchtv.cox.com/listings" },
593
660
  directv: { channelSelector: "SEC Network", url: "https://stream.directv.com" },
594
661
  disneyplus: { channelSelector: "poster_linear_sec-network_none", url: "https://www.disneyplus.com/browse/live" },
@@ -601,8 +668,9 @@ const BASE_CHANNEL_DEFINITIONS = {
601
668
  },
602
669
  espnu: {
603
670
  name: "ESPNU",
671
+ tags: ["Sports"],
604
672
  stationId: "60696",
605
- providers: {
673
+ services: {
606
674
  cox: { channelSelector: "ESPNU", url: "https://watchtv.cox.com/listings" },
607
675
  directv: { channelSelector: "ESPNU", url: "https://stream.directv.com" },
608
676
  disneyplus: { channelSelector: "poster_linear_espnu_none", url: "https://www.disneyplus.com/browse/live" },
@@ -615,8 +683,9 @@ const BASE_CHANNEL_DEFINITIONS = {
615
683
  },
616
684
  fbc: {
617
685
  name: "Fox Business",
686
+ tags: ["News"],
618
687
  stationId: "58718",
619
- providers: {
688
+ services: {
620
689
  cox: { channelSelector: "Fox Business", url: "https://watchtv.cox.com/listings" },
621
690
  directv: { channelSelector: "Fox Business Network", url: "https://stream.directv.com" },
622
691
  foxone: { channelSelector: "FBN", url: "https://www.fox.com/live/channels" },
@@ -629,8 +698,9 @@ const BASE_CHANNEL_DEFINITIONS = {
629
698
  },
630
699
  fnc: {
631
700
  name: "Fox News",
701
+ tags: ["News"],
632
702
  stationId: "60179",
633
- providers: {
703
+ services: {
634
704
  cox: { channelSelector: "Fox News", url: "https://watchtv.cox.com/listings" },
635
705
  directv: { channelSelector: "Fox News Channel", url: "https://stream.directv.com" },
636
706
  foxone: { channelSelector: "FNC", url: "https://www.fox.com/live/channels" },
@@ -644,9 +714,10 @@ const BASE_CHANNEL_DEFINITIONS = {
644
714
  },
645
715
  food: {
646
716
  name: "Food Network",
717
+ tags: ["Lifestyle"],
647
718
  pacificStationId: "82119",
648
719
  stationId: "50747",
649
- providers: {
720
+ services: {
650
721
  cox: { channelSelector: "Food Network", url: "https://watchtv.cox.com/listings" },
651
722
  directv: { channelSelector: "Food Network", url: "https://stream.directv.com" },
652
723
  hulu: { channelSelector: "Food Network", url: "https://www.hulu.com/live" },
@@ -659,7 +730,8 @@ const BASE_CHANNEL_DEFINITIONS = {
659
730
  },
660
731
  fox: {
661
732
  name: "Fox",
662
- providers: {
733
+ tags: ["Local"],
734
+ services: {
663
735
  cox: { channelSelector: "Fox", url: "https://watchtv.cox.com/listings" },
664
736
  directv: { channelSelector: "FOX", url: "https://stream.directv.com" },
665
737
  foxone: { channelSelector: "FOXD2C", url: "https://www.fox.com/live/channels" },
@@ -672,8 +744,9 @@ const BASE_CHANNEL_DEFINITIONS = {
672
744
  },
673
745
  foxdeportes: {
674
746
  name: "Fox Deportes",
747
+ tags: ["Sports"],
675
748
  stationId: "72189",
676
- providers: {
749
+ services: {
677
750
  cox: { channelSelector: "Fox Deportes", url: "https://watchtv.cox.com/listings" },
678
751
  foxone: { channelSelector: "FOXD", url: "https://www.fox.com/live/channels" },
679
752
  site: { url: "https://www.foxsports.com/live/foxdep" },
@@ -684,32 +757,36 @@ const BASE_CHANNEL_DEFINITIONS = {
684
757
  },
685
758
  foxsoccerplus: {
686
759
  name: "Fox Soccer Plus",
760
+ tags: ["Sports"],
687
761
  stationId: "66879",
688
- providers: {
762
+ services: {
689
763
  site: { url: "https://www.foxsports.com/live/fsp" },
690
764
  yttv: { channelSelector: "FOX Soccer Plus", url: "https://tv.youtube.com/live" },
691
765
  },
692
766
  },
693
767
  france24: {
694
768
  name: "France 24",
769
+ tags: ["News"],
695
770
  stationId: "60961",
696
- providers: {
771
+ services: {
697
772
  site: { url: "https://www.france24.com/en/live" },
698
773
  sling: { channelSelector: "France 24 (English)", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
699
774
  },
700
775
  },
701
776
  france24fr: {
702
777
  name: "France 24 (French)",
778
+ tags: ["News"],
703
779
  stationId: "58685",
704
- providers: {
780
+ services: {
705
781
  site: { url: "https://www.france24.com/fr/direct" },
706
782
  sling: { channelSelector: "France 24", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
707
783
  },
708
784
  },
709
785
  freeform: {
710
786
  name: "Freeform",
787
+ tags: ["Entertainment"],
711
788
  stationId: "59615",
712
- providers: {
789
+ services: {
713
790
  cox: { channelSelector: "Freeform", url: "https://watchtv.cox.com/listings" },
714
791
  directv: { channelSelector: "Freeform HD", url: "https://stream.directv.com" },
715
792
  hulu: { channelSelector: "Freeform", url: "https://www.hulu.com/live" },
@@ -721,15 +798,17 @@ const BASE_CHANNEL_DEFINITIONS = {
721
798
  },
722
799
  freeformp: {
723
800
  name: "Freeform (Pacific)",
801
+ tags: ["Entertainment"],
724
802
  stationId: "63324",
725
- providers: {
803
+ services: {
726
804
  site: { url: "https://www.freeform.com/watch-live/3507c750-e86a-4c0f-8ff4-dd23c4859009" },
727
805
  },
728
806
  },
729
807
  fs1: {
730
808
  name: "FS1",
809
+ tags: ["Sports"],
731
810
  stationId: "82547",
732
- providers: {
811
+ services: {
733
812
  cox: { channelSelector: "FOX Sports 1", url: "https://watchtv.cox.com/listings" },
734
813
  directv: { channelSelector: "FOX Sports 1", url: "https://stream.directv.com" },
735
814
  foxone: { channelSelector: "FS1", url: "https://www.fox.com/live/channels" },
@@ -743,8 +822,9 @@ const BASE_CHANNEL_DEFINITIONS = {
743
822
  },
744
823
  fs2: {
745
824
  name: "FS2",
825
+ tags: ["Sports"],
746
826
  stationId: "59305",
747
- providers: {
827
+ services: {
748
828
  cox: { channelSelector: "FOX Sports 2", url: "https://watchtv.cox.com/listings" },
749
829
  directv: { channelSelector: "FOX Sports 2", url: "https://stream.directv.com" },
750
830
  foxone: { channelSelector: "FS2", url: "https://www.fox.com/live/channels" },
@@ -757,8 +837,9 @@ const BASE_CHANNEL_DEFINITIONS = {
757
837
  },
758
838
  fx: {
759
839
  name: "FX",
840
+ tags: ["Entertainment"],
760
841
  stationId: "58574",
761
- providers: {
842
+ services: {
762
843
  cox: { channelSelector: "FX", url: "https://watchtv.cox.com/listings" },
763
844
  directv: { channelSelector: "FX", url: "https://stream.directv.com" },
764
845
  hulu: { channelSelector: "FX", url: "https://www.hulu.com/live" },
@@ -771,9 +852,10 @@ const BASE_CHANNEL_DEFINITIONS = {
771
852
  },
772
853
  fxm: {
773
854
  name: "FXM",
855
+ tags: ["Movies"],
774
856
  pacificStationId: "98488",
775
857
  stationId: "70253",
776
- providers: {
858
+ services: {
777
859
  cox: { channelSelector: "FXM", url: "https://watchtv.cox.com/listings" },
778
860
  directv: { channelSelector: "FX Movie Channel", url: "https://stream.directv.com" },
779
861
  hulu: { channelSelector: "FXM", url: "https://www.hulu.com/live" },
@@ -785,15 +867,17 @@ const BASE_CHANNEL_DEFINITIONS = {
785
867
  },
786
868
  fxp: {
787
869
  name: "FX (Pacific)",
870
+ tags: ["Entertainment"],
788
871
  stationId: "59814",
789
- providers: {
872
+ services: {
790
873
  site: { url: "https://abc.com/watch-live/2cee3401-f63b-42d0-b32e-962fef610b9e" },
791
874
  },
792
875
  },
793
876
  fxx: {
794
877
  name: "FXX",
878
+ tags: ["Entertainment"],
795
879
  stationId: "66379",
796
- providers: {
880
+ services: {
797
881
  cox: { channelSelector: "FXX", url: "https://watchtv.cox.com/listings" },
798
882
  directv: { channelSelector: "FXX", url: "https://stream.directv.com" },
799
883
  hulu: { channelSelector: "FXX", url: "https://www.hulu.com/live" },
@@ -805,16 +889,18 @@ const BASE_CHANNEL_DEFINITIONS = {
805
889
  },
806
890
  fxxp: {
807
891
  name: "FXX (Pacific)",
892
+ tags: ["Entertainment"],
808
893
  stationId: "82571",
809
- providers: {
894
+ services: {
810
895
  site: { url: "https://abc.com/watch-live/e4c83395-62ed-4a49-829a-c55ab3c33e7d" },
811
896
  },
812
897
  },
813
898
  fyi: {
814
899
  name: "FYI",
900
+ tags: ["Entertainment"],
815
901
  pacificStationId: "92372",
816
902
  stationId: "58988",
817
- providers: {
903
+ services: {
818
904
  cox: { channelSelector: "FYI", url: "https://watchtv.cox.com/listings" },
819
905
  directv: { channelSelector: "FYI", url: "https://stream.directv.com" },
820
906
  hulu: { channelSelector: "FYI", url: "https://www.hulu.com/live" },
@@ -825,9 +911,10 @@ const BASE_CHANNEL_DEFINITIONS = {
825
911
  },
826
912
  gameshow: {
827
913
  name: "Game Show Network",
914
+ tags: ["Entertainment"],
828
915
  pacificStationId: "90210",
829
916
  stationId: "68827",
830
- providers: {
917
+ services: {
831
918
  cox: { channelSelector: "Game Show Network", url: "https://watchtv.cox.com/listings" },
832
919
  directv: { channelSelector: "GSN HD", url: "https://stream.directv.com" },
833
920
  hulu: { channelSelector: "Game Show Network", url: "https://www.hulu.com/live" },
@@ -838,8 +925,9 @@ const BASE_CHANNEL_DEFINITIONS = {
838
925
  },
839
926
  golf: {
840
927
  name: "Golf",
928
+ tags: ["Sports"],
841
929
  stationId: "61854",
842
- providers: {
930
+ services: {
843
931
  cox: { channelSelector: "Golf Channel", url: "https://watchtv.cox.com/listings" },
844
932
  directv: { channelSelector: "Golf Channel", url: "https://stream.directv.com" },
845
933
  hulu: { channelSelector: "Golf Channel", url: "https://www.hulu.com/live" },
@@ -852,9 +940,10 @@ const BASE_CHANNEL_DEFINITIONS = {
852
940
  },
853
941
  hallmark: {
854
942
  name: "Hallmark",
943
+ tags: ["Entertainment"],
855
944
  pacificStationId: "66415",
856
945
  stationId: "66268",
857
- providers: {
946
+ services: {
858
947
  cox: { channelSelector: "Hallmark Channel", url: "https://watchtv.cox.com/listings" },
859
948
  directv: { channelSelector: "Hallmark Channel", url: "https://stream.directv.com" },
860
949
  hulu: { channelSelector: "Hallmark Channel", url: "https://www.hulu.com/live" },
@@ -865,8 +954,9 @@ const BASE_CHANNEL_DEFINITIONS = {
865
954
  },
866
955
  hallmarkfamily: {
867
956
  name: "Hallmark Family",
957
+ tags: ["Entertainment"],
868
958
  stationId: "105723",
869
- providers: {
959
+ services: {
870
960
  cox: { channelSelector: "HFM", url: "https://watchtv.cox.com/listings" },
871
961
  spectrum: { channelSelector: "Hallmark Family", url: "https://watch.spectrum.net/guide" },
872
962
  xfinity: { channelSelector: "HFM", url: "https://www.xfinity.com/stream/listings" },
@@ -875,9 +965,10 @@ const BASE_CHANNEL_DEFINITIONS = {
875
965
  },
876
966
  hallmarkmystery: {
877
967
  name: "Hallmark Mystery",
968
+ tags: ["Entertainment"],
878
969
  pacificStationId: "66412",
879
970
  stationId: "46710",
880
- providers: {
971
+ services: {
881
972
  cox: { channelSelector: "HMYS", url: "https://watchtv.cox.com/listings" },
882
973
  hulu: { channelSelector: "Hallmark Mystery", url: "https://www.hulu.com/live" },
883
974
  spectrum: { channelSelector: "Hallmark Mystery", url: "https://watch.spectrum.net/guide" },
@@ -887,8 +978,9 @@ const BASE_CHANNEL_DEFINITIONS = {
887
978
  },
888
979
  hbo: {
889
980
  name: "HBO",
981
+ tags: ["HBO", "Movies"],
890
982
  stationId: "19548",
891
- providers: {
983
+ services: {
892
984
  cox: { channelSelector: "HBO", url: "https://watchtv.cox.com/listings" },
893
985
  site: { channelSelector: "HBO", url: "https://play.hbomax.com" },
894
986
  xfinity: { channelSelector: "HBO", url: "https://www.xfinity.com/stream/listings" },
@@ -897,8 +989,9 @@ const BASE_CHANNEL_DEFINITIONS = {
897
989
  },
898
990
  hbocomedy: {
899
991
  name: "HBO Comedy",
992
+ tags: ["HBO", "Movies"],
900
993
  stationId: "59839",
901
- providers: {
994
+ services: {
902
995
  cox: { channelSelector: "HBOCH", url: "https://watchtv.cox.com/listings" },
903
996
  site: { channelSelector: "HBO Comedy", url: "https://play.hbomax.com" },
904
997
  xfinity: { channelSelector: "HBOCH", url: "https://www.xfinity.com/stream/listings" },
@@ -907,8 +1000,9 @@ const BASE_CHANNEL_DEFINITIONS = {
907
1000
  },
908
1001
  hbodrama: {
909
1002
  name: "HBO Drama",
1003
+ tags: ["HBO", "Movies"],
910
1004
  stationId: "59363",
911
- providers: {
1005
+ services: {
912
1006
  cox: { channelSelector: "HBOSH", url: "https://watchtv.cox.com/listings" },
913
1007
  site: { channelSelector: "HBO Drama", url: "https://play.hbomax.com" },
914
1008
  xfinity: { channelSelector: "HBOSH", url: "https://www.xfinity.com/stream/listings" },
@@ -917,8 +1011,9 @@ const BASE_CHANNEL_DEFINITIONS = {
917
1011
  },
918
1012
  hbohits: {
919
1013
  name: "HBO Hits",
1014
+ tags: ["HBO", "Movies"],
920
1015
  stationId: "59368",
921
- providers: {
1016
+ services: {
922
1017
  cox: { channelSelector: "HBO2H", url: "https://watchtv.cox.com/listings" },
923
1018
  site: { channelSelector: "HBO Hits", url: "https://play.hbomax.com" },
924
1019
  xfinity: { channelSelector: "HBO2H", url: "https://www.xfinity.com/stream/listings" },
@@ -927,8 +1022,9 @@ const BASE_CHANNEL_DEFINITIONS = {
927
1022
  },
928
1023
  hbomovies: {
929
1024
  name: "HBO Movies",
1025
+ tags: ["HBO", "Movies"],
930
1026
  stationId: "59845",
931
- providers: {
1027
+ services: {
932
1028
  cox: { channelSelector: "HBOZH", url: "https://watchtv.cox.com/listings" },
933
1029
  site: { channelSelector: "HBO Movies", url: "https://play.hbomax.com" },
934
1030
  xfinity: { channelSelector: "HBOZH", url: "https://www.xfinity.com/stream/listings" },
@@ -937,9 +1033,10 @@ const BASE_CHANNEL_DEFINITIONS = {
937
1033
  },
938
1034
  hgtv: {
939
1035
  name: "HGTV",
1036
+ tags: ["Lifestyle"],
940
1037
  pacificStationId: "87317",
941
1038
  stationId: "49788",
942
- providers: {
1039
+ services: {
943
1040
  cox: { channelSelector: "HGTV", url: "https://watchtv.cox.com/listings" },
944
1041
  directv: { channelSelector: "HGTV", url: "https://stream.directv.com" },
945
1042
  hulu: { channelSelector: "HGTV", url: "https://www.hulu.com/live" },
@@ -952,9 +1049,10 @@ const BASE_CHANNEL_DEFINITIONS = {
952
1049
  },
953
1050
  history: {
954
1051
  name: "History",
1052
+ tags: ["Documentary"],
955
1053
  pacificStationId: "88545",
956
1054
  stationId: "57708",
957
- providers: {
1055
+ services: {
958
1056
  cox: { channelSelector: "History", url: "https://watchtv.cox.com/listings" },
959
1057
  directv: { channelSelector: "HISTORY", url: "https://stream.directv.com" },
960
1058
  hulu: { channelSelector: "The HISTORY Channel", url: "https://www.hulu.com/live" },
@@ -966,8 +1064,9 @@ const BASE_CHANNEL_DEFINITIONS = {
966
1064
  },
967
1065
  hln: {
968
1066
  name: "HLN",
1067
+ tags: ["News"],
969
1068
  stationId: "64549",
970
- providers: {
1069
+ services: {
971
1070
  cox: { channelSelector: "HLN", url: "https://watchtv.cox.com/listings" },
972
1071
  directv: { channelSelector: "HLN", url: "https://stream.directv.com" },
973
1072
  hulu: { channelSelector: "HLN", url: "https://www.hulu.com/live" },
@@ -980,9 +1079,10 @@ const BASE_CHANNEL_DEFINITIONS = {
980
1079
  },
981
1080
  id: {
982
1081
  name: "Investigation Discovery",
1082
+ tags: ["Documentary"],
983
1083
  pacificStationId: "80309",
984
1084
  stationId: "65342",
985
- providers: {
1085
+ services: {
986
1086
  cox: { channelSelector: "Investigation Discovery", url: "https://watchtv.cox.com/listings" },
987
1087
  directv: { channelSelector: "Investigation Discovery", url: "https://stream.directv.com" },
988
1088
  hulu: { channelSelector: "Investigation Discovery", url: "https://www.hulu.com/live" },
@@ -995,9 +1095,10 @@ const BASE_CHANNEL_DEFINITIONS = {
995
1095
  },
996
1096
  ifc: {
997
1097
  name: "IFC",
1098
+ tags: ["Entertainment", "Movies"],
998
1099
  pacificStationId: "109735",
999
1100
  stationId: "59444",
1000
- providers: {
1101
+ services: {
1001
1102
  cox: { channelSelector: "IFC", url: "https://watchtv.cox.com/listings" },
1002
1103
  directv: { channelSelector: "IFC", url: "https://stream.directv.com" },
1003
1104
  sling: { channelSelector: "IFC", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
@@ -1008,8 +1109,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1008
1109
  },
1009
1110
  indieplex: {
1010
1111
  name: "IndiePlex",
1112
+ tags: ["Movies", "Starz"],
1011
1113
  stationId: "65795",
1012
- providers: {
1114
+ services: {
1013
1115
  hulu: { channelSelector: "IndiePlex (East)", url: "https://www.hulu.com/live" },
1014
1116
  sling: { channelSelector: "IndiePlex", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
1015
1117
  spectrum: { channelSelector: "IndiePlex", url: "https://watch.spectrum.net/guide" },
@@ -1017,16 +1119,18 @@ const BASE_CHANNEL_DEFINITIONS = {
1017
1119
  },
1018
1120
  indieplexp: {
1019
1121
  name: "IndiePlex (Pacific)",
1122
+ tags: ["Movies", "Starz"],
1020
1123
  stationId: "65796",
1021
- providers: {
1124
+ services: {
1022
1125
  hulu: { channelSelector: "IndiePlex (West)", url: "https://www.hulu.com/live" },
1023
1126
  },
1024
1127
  },
1025
1128
  lifetime: {
1026
1129
  name: "Lifetime",
1130
+ tags: ["Entertainment"],
1027
1131
  pacificStationId: "60250",
1028
1132
  stationId: "60150",
1029
- providers: {
1133
+ services: {
1030
1134
  cox: { channelSelector: "Lifetime", url: "https://watchtv.cox.com/listings" },
1031
1135
  directv: { channelSelector: "Lifetime", url: "https://stream.directv.com" },
1032
1136
  hulu: { channelSelector: "Lifetime", url: "https://www.hulu.com/live" },
@@ -1038,9 +1142,10 @@ const BASE_CHANNEL_DEFINITIONS = {
1038
1142
  },
1039
1143
  lmn: {
1040
1144
  name: "Lifetime Movie Network",
1145
+ tags: ["Entertainment", "Movies"],
1041
1146
  pacificStationId: "92373",
1042
1147
  stationId: "55887",
1043
- providers: {
1148
+ services: {
1044
1149
  cox: { channelSelector: "Lifetime Movies", url: "https://watchtv.cox.com/listings" },
1045
1150
  directv: { channelSelector: "Lifetime Movie Network", url: "https://stream.directv.com" },
1046
1151
  hulu: { channelSelector: "LMN", url: "https://www.hulu.com/live" },
@@ -1050,9 +1155,10 @@ const BASE_CHANNEL_DEFINITIONS = {
1050
1155
  },
1051
1156
  magnolia: {
1052
1157
  name: "Magnolia Network",
1158
+ tags: ["Lifestyle"],
1053
1159
  pacificStationId: "122081",
1054
1160
  stationId: "67375",
1055
- providers: {
1161
+ services: {
1056
1162
  cox: { channelSelector: "Magnolia Network", url: "https://watchtv.cox.com/listings" },
1057
1163
  directv: { channelSelector: "Magnolia Network", url: "https://stream.directv.com" },
1058
1164
  hulu: { channelSelector: "Magnolia Network", url: "https://www.hulu.com/live" },
@@ -1064,9 +1170,10 @@ const BASE_CHANNEL_DEFINITIONS = {
1064
1170
  },
1065
1171
  mgmplus: {
1066
1172
  name: "MGM+",
1173
+ tags: ["Movies"],
1067
1174
  pacificStationId: "95927",
1068
1175
  stationId: "65687",
1069
- providers: {
1176
+ services: {
1070
1177
  cox: { channelSelector: "MGM+", url: "https://watchtv.cox.com/listings" },
1071
1178
  directv: { channelSelector: "MGM+", url: "https://stream.directv.com" },
1072
1179
  xfinity: { channelSelector: "MGM+", url: "https://www.xfinity.com/stream/listings" },
@@ -1074,8 +1181,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1074
1181
  },
1075
1182
  mlb: {
1076
1183
  name: "MLB Network",
1184
+ tags: ["Sports"],
1077
1185
  stationId: "62081",
1078
- providers: {
1186
+ services: {
1079
1187
  cox: { channelSelector: "MLB Network", url: "https://watchtv.cox.com/listings" },
1080
1188
  directv: { channelSelector: "MLB Network", url: "https://stream.directv.com" },
1081
1189
  hulu: { channelSelector: "MLB Network", url: "https://www.hulu.com/live" },
@@ -1085,8 +1193,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1085
1193
  },
1086
1194
  movieplex: {
1087
1195
  name: "MoviePlex",
1196
+ tags: ["Movies", "Starz"],
1088
1197
  stationId: "83075",
1089
- providers: {
1198
+ services: {
1090
1199
  hulu: { channelSelector: "MoviePlex (East)", url: "https://www.hulu.com/live" },
1091
1200
  sling: { channelSelector: "MoviePlex", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
1092
1201
  spectrum: { channelSelector: "Movieplex", url: "https://watch.spectrum.net/guide" },
@@ -1094,29 +1203,33 @@ const BASE_CHANNEL_DEFINITIONS = {
1094
1203
  },
1095
1204
  movieplexp: {
1096
1205
  name: "MoviePlex (Pacific)",
1206
+ tags: ["Movies", "Starz"],
1097
1207
  stationId: "105963",
1098
- providers: {
1208
+ services: {
1099
1209
  hulu: { channelSelector: "MoviePlex (West)", url: "https://www.hulu.com/live" },
1100
1210
  },
1101
1211
  },
1102
1212
  msg: {
1103
1213
  name: "MSG",
1214
+ tags: ["Sports"],
1104
1215
  stationId: "35402",
1105
- providers: {
1216
+ services: {
1106
1217
  directv: { channelSelector: "MSG", url: "https://stream.directv.com" },
1107
1218
  },
1108
1219
  },
1109
1220
  msgsn: {
1110
1221
  name: "MSG Sportsnet",
1222
+ tags: ["Sports"],
1111
1223
  stationId: "35383",
1112
- providers: {
1224
+ services: {
1113
1225
  directv: { channelSelector: "MSG Sportsnet HD 635", url: "https://stream.directv.com" },
1114
1226
  },
1115
1227
  },
1116
1228
  msnow: {
1117
1229
  name: "MS NOW",
1230
+ tags: ["News"],
1118
1231
  stationId: "64241",
1119
- providers: {
1232
+ services: {
1120
1233
  cox: { channelSelector: "MS NOW", url: "https://watchtv.cox.com/listings" },
1121
1234
  directv: { channelSelector: "MS Now", url: "https://stream.directv.com" },
1122
1235
  hulu: { channelSelector: "MS NOW", url: "https://www.hulu.com/live" },
@@ -1130,9 +1243,10 @@ const BASE_CHANNEL_DEFINITIONS = {
1130
1243
  },
1131
1244
  mtv: {
1132
1245
  name: "MTV",
1246
+ tags: ["Entertainment"],
1133
1247
  pacificStationId: "64630",
1134
1248
  stationId: "60964",
1135
- providers: {
1249
+ services: {
1136
1250
  cox: { channelSelector: "MTV", url: "https://watchtv.cox.com/listings" },
1137
1251
  directv: { channelSelector: "MTV", url: "https://stream.directv.com" },
1138
1252
  hulu: { channelSelector: "MTV", url: "https://www.hulu.com/live" },
@@ -1143,9 +1257,10 @@ const BASE_CHANNEL_DEFINITIONS = {
1143
1257
  },
1144
1258
  mtv2: {
1145
1259
  name: "MTV2",
1260
+ tags: ["Entertainment"],
1146
1261
  pacificStationId: "75506",
1147
1262
  stationId: "75077",
1148
- providers: {
1263
+ services: {
1149
1264
  cox: { channelSelector: "MTV2", url: "https://watchtv.cox.com/listings" },
1150
1265
  directv: { channelSelector: "MTV2", url: "https://stream.directv.com" },
1151
1266
  spectrum: { channelSelector: "MTV2", url: "https://watch.spectrum.net/guide" },
@@ -1154,8 +1269,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1154
1269
  },
1155
1270
  mtvclassic: {
1156
1271
  name: "MTV Classic",
1272
+ tags: ["Entertainment"],
1157
1273
  stationId: "92240",
1158
- providers: {
1274
+ services: {
1159
1275
  cox: { channelSelector: "MTV Classic", url: "https://watchtv.cox.com/listings" },
1160
1276
  directv: { channelSelector: "MTV Classic", url: "https://stream.directv.com" },
1161
1277
  spectrum: { channelSelector: "MTV Classic", url: "https://watch.spectrum.net/guide" },
@@ -1164,8 +1280,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1164
1280
  },
1165
1281
  natgeo: {
1166
1282
  name: "National Geographic",
1283
+ tags: ["Documentary"],
1167
1284
  stationId: "49438",
1168
- providers: {
1285
+ services: {
1169
1286
  cox: { channelSelector: "Nat Geo", url: "https://watchtv.cox.com/listings" },
1170
1287
  directv: { channelSelector: "National Geographic Channel", url: "https://stream.directv.com" },
1171
1288
  hulu: { channelSelector: "National Geographic", url: "https://www.hulu.com/live" },
@@ -1178,15 +1295,17 @@ const BASE_CHANNEL_DEFINITIONS = {
1178
1295
  },
1179
1296
  natgeop: {
1180
1297
  name: "National Geographic (Pacific)",
1298
+ tags: ["Documentary"],
1181
1299
  stationId: "71601",
1182
- providers: {
1300
+ services: {
1183
1301
  site: { url: "https://www.nationalgeographic.com/tv/watch-live/91456580-f32f-417c-8e1a-9f82640832a7" },
1184
1302
  },
1185
1303
  },
1186
1304
  natgeowild: {
1187
1305
  name: "Nat Geo Wild",
1306
+ tags: ["Documentary"],
1188
1307
  stationId: "67331",
1189
- providers: {
1308
+ services: {
1190
1309
  cox: { channelSelector: "National Geographic WILD", url: "https://watchtv.cox.com/listings" },
1191
1310
  directv: { channelSelector: "Nat Geo WILD", url: "https://stream.directv.com" },
1192
1311
  hulu: { channelSelector: "Nat Geo WILD", url: "https://www.hulu.com/live" },
@@ -1198,8 +1317,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1198
1317
  },
1199
1318
  nba: {
1200
1319
  name: "NBA TV",
1320
+ tags: ["Sports"],
1201
1321
  stationId: "45526",
1202
- providers: {
1322
+ services: {
1203
1323
  cox: { channelSelector: "NBA TV", url: "https://watchtv.cox.com/listings" },
1204
1324
  directv: { channelSelector: "NBA TV", url: "https://stream.directv.com" },
1205
1325
  site: { url: "https://www.nba.com/watch/nba-tv" },
@@ -1210,7 +1330,8 @@ const BASE_CHANNEL_DEFINITIONS = {
1210
1330
  },
1211
1331
  nbc: {
1212
1332
  name: "NBC",
1213
- providers: {
1333
+ tags: ["Local"],
1334
+ services: {
1214
1335
  cox: { channelSelector: "NBC", url: "https://watchtv.cox.com/listings" },
1215
1336
  directv: { channelSelector: "NBC", url: "https://stream.directv.com" },
1216
1337
  hulu: { channelSelector: "NBC", url: "https://www.hulu.com/live" },
@@ -1223,8 +1344,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1223
1344
  },
1224
1345
  nbcnews: {
1225
1346
  name: "NBC News Now",
1347
+ tags: ["News"],
1226
1348
  stationId: "114174",
1227
- providers: {
1349
+ services: {
1228
1350
  cox: { channelSelector: "NBC News NOW", url: "https://watchtv.cox.com/listings" },
1229
1351
  directv: { channelSelector: "NBC News Now", url: "https://stream.directv.com" },
1230
1352
  hulu: { channelSelector: "NBC News NOW", url: "https://www.hulu.com/live" },
@@ -1236,50 +1358,57 @@ const BASE_CHANNEL_DEFINITIONS = {
1236
1358
  },
1237
1359
  nbcsbayarea: {
1238
1360
  name: "NBC Sports Bay Area",
1361
+ tags: ["Sports"],
1239
1362
  stationId: "63138",
1240
- providers: {
1363
+ services: {
1241
1364
  site: { url: "https://www.nbc.com/live?brand=rsn-bay-area&callsign=nbcsbayarea" },
1242
1365
  },
1243
1366
  },
1244
1367
  nbcsboston: {
1245
1368
  name: "NBC Sports Boston",
1369
+ tags: ["Sports"],
1246
1370
  stationId: "49198",
1247
- providers: {
1371
+ services: {
1248
1372
  site: { url: "https://www.nbc.com/live?brand=rsn-boston&callsign=nbcsboston" },
1249
1373
  },
1250
1374
  },
1251
1375
  nbcscalifornia: {
1252
1376
  name: "NBC Sports California",
1377
+ tags: ["Sports"],
1253
1378
  stationId: "45540",
1254
- providers: {
1379
+ services: {
1255
1380
  site: { url: "https://www.nbc.com/live?brand=rsn-california&callsign=nbcscalifornia" },
1256
1381
  },
1257
1382
  },
1258
1383
  nbcsn: {
1259
1384
  name: "NBC Sports Network",
1385
+ tags: ["Sports"],
1260
1386
  stationId: "194412",
1261
- providers: {
1387
+ services: {
1262
1388
  yttv: { channelSelector: "NBC Sports Network", url: "https://tv.youtube.com/live" },
1263
1389
  },
1264
1390
  },
1265
1391
  nbcsphiladelphia: {
1266
1392
  name: "NBC Sports Philadelphia",
1393
+ tags: ["Sports"],
1267
1394
  stationId: "32571",
1268
- providers: {
1395
+ services: {
1269
1396
  site: { url: "https://www.nbc.com/live?brand=rsn-philadelphia&callsign=nbcsphiladelphia" },
1270
1397
  },
1271
1398
  },
1272
1399
  necn: {
1273
1400
  name: "NECN",
1401
+ tags: ["News"],
1274
1402
  stationId: "66278",
1275
- providers: {
1403
+ services: {
1276
1404
  site: { url: "https://www.nbc.com/live?brand=necn&callsign=necn" },
1277
1405
  },
1278
1406
  },
1279
1407
  nfl: {
1280
1408
  name: "NFL Network",
1409
+ tags: ["Sports"],
1281
1410
  stationId: "45399",
1282
- providers: {
1411
+ services: {
1283
1412
  cox: { channelSelector: "NFL Network", url: "https://watchtv.cox.com/listings" },
1284
1413
  directv: { channelSelector: "NFL Network", url: "https://stream.directv.com" },
1285
1414
  hulu: { channelSelector: "NFL Network", url: "https://www.hulu.com/live" },
@@ -1291,8 +1420,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1291
1420
  },
1292
1421
  nhl: {
1293
1422
  name: "NHL Network",
1423
+ tags: ["Sports"],
1294
1424
  stationId: "58690",
1295
- providers: {
1425
+ services: {
1296
1426
  cox: { channelSelector: "NHL Network", url: "https://watchtv.cox.com/listings" },
1297
1427
  directv: { channelSelector: "NHL Network HD", url: "https://stream.directv.com" },
1298
1428
  spectrum: { channelSelector: "NHL Network", url: "https://watch.spectrum.net/guide" },
@@ -1301,8 +1431,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1301
1431
  },
1302
1432
  own: {
1303
1433
  name: "OWN",
1434
+ tags: ["Lifestyle"],
1304
1435
  stationId: "70388",
1305
- providers: {
1436
+ services: {
1306
1437
  cox: { channelSelector: "OWN", url: "https://watchtv.cox.com/listings" },
1307
1438
  directv: { channelSelector: "OWN", url: "https://stream.directv.com" },
1308
1439
  hulu: { channelSelector: "Oprah Winfrey Network", url: "https://www.hulu.com/live" },
@@ -1314,8 +1445,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1314
1445
  },
1315
1446
  oxygen: {
1316
1447
  name: "Oxygen",
1448
+ tags: ["Entertainment"],
1317
1449
  stationId: "70522",
1318
- providers: {
1450
+ services: {
1319
1451
  cox: { channelSelector: "Oxygen True Crime", url: "https://watchtv.cox.com/listings" },
1320
1452
  directv: { channelSelector: "Oxygen True Crime", url: "https://stream.directv.com" },
1321
1453
  hulu: { channelSelector: "Oxygen True Crime", url: "https://www.hulu.com/live" },
@@ -1327,15 +1459,17 @@ const BASE_CHANNEL_DEFINITIONS = {
1327
1459
  },
1328
1460
  oxygenp: {
1329
1461
  name: "Oxygen (Pacific)",
1462
+ tags: ["Entertainment"],
1330
1463
  stationId: "74032",
1331
- providers: {
1464
+ services: {
1332
1465
  site: { channelSelector: "Oxygen_West", url: "https://www.usanetwork.com/live" },
1333
1466
  },
1334
1467
  },
1335
1468
  paramount: {
1336
1469
  name: "Paramount Network",
1470
+ tags: ["Entertainment"],
1337
1471
  stationId: "59186",
1338
- providers: {
1472
+ services: {
1339
1473
  cox: { channelSelector: "Paramount Network", url: "https://watchtv.cox.com/listings" },
1340
1474
  hulu: { channelSelector: "Paramount Network", url: "https://www.hulu.com/live" },
1341
1475
  spectrum: { channelSelector: "Paramount Network", url: "https://watch.spectrum.net/guide" },
@@ -1345,14 +1479,16 @@ const BASE_CHANNEL_DEFINITIONS = {
1345
1479
  },
1346
1480
  paramountp: {
1347
1481
  name: "Paramount (Pacific)",
1482
+ tags: ["Entertainment"],
1348
1483
  stationId: "64593",
1349
- providers: {
1484
+ services: {
1350
1485
  yttv: { channelSelector: "Paramount Network", url: "https://tv.youtube.com/live" },
1351
1486
  },
1352
1487
  },
1353
1488
  pbs: {
1354
1489
  name: "PBS",
1355
- providers: {
1490
+ tags: ["Local"],
1491
+ services: {
1356
1492
  cox: { channelSelector: "PBS", url: "https://watchtv.cox.com/listings" },
1357
1493
  directv: { channelSelector: "PBS", url: "https://stream.directv.com" },
1358
1494
  hulu: { channelSelector: "PBS", url: "https://www.hulu.com/live" },
@@ -1363,24 +1499,27 @@ const BASE_CHANNEL_DEFINITIONS = {
1363
1499
  },
1364
1500
  pbschicago: {
1365
1501
  name: "PBS Chicago (WTTW)",
1502
+ tags: ["Local"],
1366
1503
  stationId: "30415",
1367
- providers: {
1504
+ services: {
1368
1505
  hulu: { channelSelector: "PBS", url: "https://www.hulu.com/live" },
1369
1506
  site: { url: "https://www.wttw.com/wttw-live-stream" },
1370
1507
  },
1371
1508
  },
1372
1509
  pbslakeshore: {
1373
1510
  name: "PBS Lakeshore (WYIN)",
1511
+ tags: ["Local"],
1374
1512
  stationId: "49237",
1375
- providers: {
1513
+ services: {
1376
1514
  hulu: { channelSelector: "Lakeshore PBS", url: "https://www.hulu.com/live" },
1377
1515
  site: { url: "https://video.lakeshorepbs.org/livestream" },
1378
1516
  },
1379
1517
  },
1380
1518
  retroplex: {
1381
1519
  name: "RetroPlex",
1520
+ tags: ["Movies", "Starz"],
1382
1521
  stationId: "65791",
1383
- providers: {
1522
+ services: {
1384
1523
  hulu: { channelSelector: "RetroPlex (East)", url: "https://www.hulu.com/live" },
1385
1524
  sling: { channelSelector: "RetroPlex", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
1386
1525
  spectrum: { channelSelector: "RetroPlex", url: "https://watch.spectrum.net/guide" },
@@ -1388,15 +1527,17 @@ const BASE_CHANNEL_DEFINITIONS = {
1388
1527
  },
1389
1528
  retroplexp: {
1390
1529
  name: "RetroPlex (Pacific)",
1530
+ tags: ["Movies", "Starz"],
1391
1531
  stationId: "65793",
1392
- providers: {
1532
+ services: {
1393
1533
  hulu: { channelSelector: "RetroPlex (West)", url: "https://www.hulu.com/live" },
1394
1534
  },
1395
1535
  },
1396
1536
  science: {
1397
1537
  name: "Science",
1538
+ tags: ["Documentary"],
1398
1539
  stationId: "57390",
1399
- providers: {
1540
+ services: {
1400
1541
  cox: { channelSelector: "Science Channel", url: "https://watchtv.cox.com/listings" },
1401
1542
  directv: { channelSelector: "Science", url: "https://stream.directv.com" },
1402
1543
  site: { url: "https://watch.foodnetwork.com/channel/science" },
@@ -1406,8 +1547,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1406
1547
  },
1407
1548
  showtime: {
1408
1549
  name: "Showtime",
1550
+ tags: ["Movies", "Showtime"],
1409
1551
  stationId: "91620",
1410
- providers: {
1552
+ services: {
1411
1553
  cox: { channelSelector: "PSHOh", url: "https://watchtv.cox.com/listings" },
1412
1554
  paramountplus: { url: "https://www.paramountplus.com/live-tv/stream/showtime-east" },
1413
1555
  xfinity: { channelSelector: "PSHOh", url: "https://www.xfinity.com/stream/listings" },
@@ -1416,16 +1558,18 @@ const BASE_CHANNEL_DEFINITIONS = {
1416
1558
  },
1417
1559
  showtimep: {
1418
1560
  name: "Showtime (Pacific)",
1561
+ tags: ["Movies", "Showtime"],
1419
1562
  stationId: "91621",
1420
- providers: {
1563
+ services: {
1421
1564
  paramountplus: { url: "https://www.paramountplus.com/live-tv/stream/showtime-west" },
1422
1565
  },
1423
1566
  },
1424
1567
  smithsonian: {
1425
1568
  name: "Smithsonian Channel",
1569
+ tags: ["Documentary"],
1426
1570
  pacificStationId: "82695",
1427
1571
  stationId: "58532",
1428
- providers: {
1572
+ services: {
1429
1573
  cox: { channelSelector: "Smithsonian", url: "https://watchtv.cox.com/listings" },
1430
1574
  directv: { channelSelector: "Smithsonian Channel HD", url: "https://stream.directv.com" },
1431
1575
  hulu: { channelSelector: "Smithsonian Channel", url: "https://www.hulu.com/live" },
@@ -1436,15 +1580,17 @@ const BASE_CHANNEL_DEFINITIONS = {
1436
1580
  },
1437
1581
  sny: {
1438
1582
  name: "SportsNet New York",
1583
+ tags: ["Sports"],
1439
1584
  stationId: "50038",
1440
- providers: {
1585
+ services: {
1441
1586
  directv: { channelSelector: "SportsNet New York HD 639", url: "https://stream.directv.com" },
1442
1587
  },
1443
1588
  },
1444
1589
  starz: {
1445
1590
  name: "Starz",
1591
+ tags: ["Movies", "Starz"],
1446
1592
  stationId: "34941",
1447
- providers: {
1593
+ services: {
1448
1594
  cox: { channelSelector: "STARZ", url: "https://watchtv.cox.com/listings" },
1449
1595
  hulu: { channelSelector: "STARZ (East)", url: "https://www.hulu.com/live" },
1450
1596
  site: { url: "https://www.starz.com/us/en/play/2" },
@@ -1454,53 +1600,60 @@ const BASE_CHANNEL_DEFINITIONS = {
1454
1600
  },
1455
1601
  starzcinema: {
1456
1602
  name: "Starz Cinema",
1603
+ tags: ["Movies", "Starz"],
1457
1604
  stationId: "67236",
1458
- providers: {
1605
+ services: {
1459
1606
  hulu: { channelSelector: "STARZ Cinema (East)", url: "https://www.hulu.com/live" },
1460
1607
  sling: { channelSelector: "Starz Cinema", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
1461
1608
  },
1462
1609
  },
1463
1610
  starzcinemap: {
1464
1611
  name: "Starz Cinema (Pacific)",
1612
+ tags: ["Movies", "Starz"],
1465
1613
  stationId: "67365",
1466
- providers: {
1614
+ services: {
1467
1615
  hulu: { channelSelector: "STARZ Cinema (West)", url: "https://www.hulu.com/live" },
1468
1616
  },
1469
1617
  },
1470
1618
  starzcomedy: {
1471
1619
  name: "Starz Comedy",
1620
+ tags: ["Movies", "Starz"],
1472
1621
  stationId: "57569",
1473
- providers: {
1622
+ services: {
1474
1623
  hulu: { channelSelector: "STARZ Comedy (East)", url: "https://www.hulu.com/live" },
1475
1624
  sling: { channelSelector: "Starz Comedy", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
1476
1625
  },
1477
1626
  },
1478
1627
  starzcomedyp: {
1479
1628
  name: "Starz Comedy (Pacific)",
1629
+ tags: ["Movies", "Starz"],
1480
1630
  stationId: "57575",
1481
- providers: {
1631
+ services: {
1482
1632
  hulu: { channelSelector: "STARZ Comedy (West)", url: "https://www.hulu.com/live" },
1483
1633
  },
1484
1634
  },
1485
1635
  starzedge: {
1486
1636
  name: "Starz Edge",
1637
+ tags: ["Movies", "Starz"],
1487
1638
  stationId: "57573",
1488
- providers: {
1639
+ services: {
1489
1640
  hulu: { channelSelector: "STARZ Edge (East)", url: "https://www.hulu.com/live" },
1490
1641
  sling: { channelSelector: "Starz Edge", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
1491
1642
  },
1492
1643
  },
1493
1644
  starzedgep: {
1494
1645
  name: "Starz Edge (Pacific)",
1646
+ tags: ["Movies", "Starz"],
1495
1647
  stationId: "57578",
1496
- providers: {
1648
+ services: {
1497
1649
  hulu: { channelSelector: "STARZ Edge (West)", url: "https://www.hulu.com/live" },
1498
1650
  },
1499
1651
  },
1500
1652
  starzencore: {
1501
1653
  name: "Starz Encore",
1654
+ tags: ["Movies", "Starz"],
1502
1655
  stationId: "36225",
1503
- providers: {
1656
+ services: {
1504
1657
  cox: { channelSelector: "STZEH", url: "https://watchtv.cox.com/listings" },
1505
1658
  hulu: { channelSelector: "STARZ Encore (East)", url: "https://www.hulu.com/live" },
1506
1659
  sling: { channelSelector: "Starz Encore", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
@@ -1509,8 +1662,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1509
1662
  },
1510
1663
  starzencoreaction: {
1511
1664
  name: "Starz Encore Action",
1665
+ tags: ["Movies", "Starz"],
1512
1666
  stationId: "72015",
1513
- providers: {
1667
+ services: {
1514
1668
  cox: { channelSelector: "STZAH", url: "https://watchtv.cox.com/listings" },
1515
1669
  hulu: { channelSelector: "STARZ Encore Action (East)", url: "https://www.hulu.com/live" },
1516
1670
  sling: { channelSelector: "Starz Encore Action", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
@@ -1519,15 +1673,17 @@ const BASE_CHANNEL_DEFINITIONS = {
1519
1673
  },
1520
1674
  starzencoreactionp: {
1521
1675
  name: "Starz Encore Action (Pacific)",
1676
+ tags: ["Movies", "Starz"],
1522
1677
  stationId: "103833",
1523
- providers: {
1678
+ services: {
1524
1679
  hulu: { channelSelector: "STARZ Encore Action (West)", url: "https://www.hulu.com/live" },
1525
1680
  },
1526
1681
  },
1527
1682
  starzencoreblack: {
1528
1683
  name: "Starz Encore Black",
1684
+ tags: ["Movies", "Starz"],
1529
1685
  stationId: "72014",
1530
- providers: {
1686
+ services: {
1531
1687
  cox: { channelSelector: "STZBH", url: "https://watchtv.cox.com/listings" },
1532
1688
  hulu: { channelSelector: "STARZ Encore Black (East)", url: "https://www.hulu.com/live" },
1533
1689
  sling: { channelSelector: "Starz Encore Black", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
@@ -1536,137 +1692,155 @@ const BASE_CHANNEL_DEFINITIONS = {
1536
1692
  },
1537
1693
  starzencoreblackp: {
1538
1694
  name: "Starz Encore Black (Pacific)",
1695
+ tags: ["Movies", "Starz"],
1539
1696
  stationId: "103834",
1540
- providers: {
1697
+ services: {
1541
1698
  hulu: { channelSelector: "STARZ Encore Black (West)", url: "https://www.hulu.com/live" },
1542
1699
  },
1543
1700
  },
1544
1701
  starzencoreclassic: {
1545
1702
  name: "Starz Encore Classic",
1703
+ tags: ["Movies", "Starz"],
1546
1704
  stationId: "83404",
1547
- providers: {
1705
+ services: {
1548
1706
  hulu: { channelSelector: "STARZ Encore Classic (East)", url: "https://www.hulu.com/live" },
1549
1707
  sling: { channelSelector: "Starz Encore Classic", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
1550
1708
  },
1551
1709
  },
1552
1710
  starzencoreclassicp: {
1553
1711
  name: "Starz Encore Classic (Pacific)",
1712
+ tags: ["Movies", "Starz"],
1554
1713
  stationId: "97233",
1555
- providers: {
1714
+ services: {
1556
1715
  hulu: { channelSelector: "STARZ Encore Classic (West)", url: "https://www.hulu.com/live" },
1557
1716
  },
1558
1717
  },
1559
1718
  starzencoreespanol: {
1560
1719
  name: "Starz Encore Español",
1720
+ tags: ["Movies", "Starz"],
1561
1721
  stationId: "72016",
1562
- providers: {
1722
+ services: {
1563
1723
  hulu: { channelSelector: "STARZ Encore Español (East)", url: "https://www.hulu.com/live" },
1564
1724
  sling: { channelSelector: "Starz Encore Español", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
1565
1725
  },
1566
1726
  },
1567
1727
  starzencoreespanolp: {
1568
1728
  name: "Starz Encore Español (Pacific)",
1729
+ tags: ["Movies", "Starz"],
1569
1730
  stationId: "104730",
1570
- providers: {
1731
+ services: {
1571
1732
  hulu: { channelSelector: "STARZ Encore Español (West)", url: "https://www.hulu.com/live" },
1572
1733
  },
1573
1734
  },
1574
1735
  starzencorefamily: {
1575
1736
  name: "Starz Encore Family",
1737
+ tags: ["Kids", "Movies", "Starz"],
1576
1738
  stationId: "14886",
1577
- providers: {
1739
+ services: {
1578
1740
  hulu: { channelSelector: "STARZ Encore Family (East)", url: "https://www.hulu.com/live" },
1579
1741
  sling: { channelSelector: "Starz Encore Family", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
1580
1742
  },
1581
1743
  },
1582
1744
  starzencorefamilyp: {
1583
1745
  name: "Starz Encore Family (Pacific)",
1746
+ tags: ["Kids", "Movies", "Starz"],
1584
1747
  stationId: "103829",
1585
- providers: {
1748
+ services: {
1586
1749
  hulu: { channelSelector: "STARZ Encore Family (West)", url: "https://www.hulu.com/live" },
1587
1750
  },
1588
1751
  },
1589
1752
  starzencorep: {
1590
1753
  name: "Starz Encore (Pacific)",
1754
+ tags: ["Movies", "Starz"],
1591
1755
  stationId: "67237",
1592
- providers: {
1756
+ services: {
1593
1757
  hulu: { channelSelector: "STARZ Encore (West)", url: "https://www.hulu.com/live" },
1594
1758
  sling: { channelSelector: "Starz Encore West", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
1595
1759
  },
1596
1760
  },
1597
1761
  starzencoresuspense: {
1598
1762
  name: "Starz Encore Suspense",
1763
+ tags: ["Movies", "Starz"],
1599
1764
  stationId: "83076",
1600
- providers: {
1765
+ services: {
1601
1766
  hulu: { channelSelector: "STARZ Encore Suspense (East)", url: "https://www.hulu.com/live" },
1602
1767
  sling: { channelSelector: "Starz Encore Suspense", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
1603
1768
  },
1604
1769
  },
1605
1770
  starzencoresuspensep: {
1606
1771
  name: "Starz Encore Suspense (Pacific)",
1772
+ tags: ["Movies", "Starz"],
1607
1773
  stationId: "103836",
1608
- providers: {
1774
+ services: {
1609
1775
  hulu: { channelSelector: "STARZ Encore Suspense (West)", url: "https://www.hulu.com/live" },
1610
1776
  },
1611
1777
  },
1612
1778
  starzencorewesterns: {
1613
1779
  name: "Starz Encore Westerns",
1780
+ tags: ["Movies", "Starz"],
1614
1781
  stationId: "14765",
1615
- providers: {
1782
+ services: {
1616
1783
  hulu: { channelSelector: "STARZ Encore Westerns (East)", url: "https://www.hulu.com/live" },
1617
1784
  sling: { channelSelector: "Starz Encore Westerns", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
1618
1785
  },
1619
1786
  },
1620
1787
  starzencorewesternsp: {
1621
1788
  name: "Starz Encore Westerns (Pacific)",
1789
+ tags: ["Movies", "Starz"],
1622
1790
  stationId: "103856",
1623
- providers: {
1791
+ services: {
1624
1792
  hulu: { channelSelector: "STARZ Encore Westerns (West)", url: "https://www.hulu.com/live" },
1625
1793
  },
1626
1794
  },
1627
1795
  starzinblack: {
1628
1796
  name: "Starz in Black",
1797
+ tags: ["Movies", "Starz"],
1629
1798
  stationId: "67235",
1630
- providers: {
1799
+ services: {
1631
1800
  hulu: { channelSelector: "STARZ in Black (East)", url: "https://www.hulu.com/live" },
1632
1801
  sling: { channelSelector: "Starz in Black", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
1633
1802
  },
1634
1803
  },
1635
1804
  starzinblackp: {
1636
1805
  name: "Starz in Black (Pacific)",
1806
+ tags: ["Movies", "Starz"],
1637
1807
  stationId: "67367",
1638
- providers: {
1808
+ services: {
1639
1809
  hulu: { channelSelector: "STARZ in Black (West)", url: "https://www.hulu.com/live" },
1640
1810
  },
1641
1811
  },
1642
1812
  starzkids: {
1643
1813
  name: "Starz Kids",
1814
+ tags: ["Kids", "Starz"],
1644
1815
  stationId: "57581",
1645
- providers: {
1816
+ services: {
1646
1817
  hulu: { channelSelector: "STARZ Kids (East)", url: "https://www.hulu.com/live" },
1647
1818
  sling: { channelSelector: "Starz Kids", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
1648
1819
  },
1649
1820
  },
1650
1821
  starzkidsp: {
1651
1822
  name: "Starz Kids (Pacific)",
1823
+ tags: ["Kids", "Starz"],
1652
1824
  stationId: "57583",
1653
- providers: {
1825
+ services: {
1654
1826
  hulu: { channelSelector: "STARZ Kids (West)", url: "https://www.hulu.com/live" },
1655
1827
  },
1656
1828
  },
1657
1829
  starzp: {
1658
1830
  name: "Starz (Pacific)",
1831
+ tags: ["Movies", "Starz"],
1659
1832
  stationId: "34949",
1660
- providers: {
1833
+ services: {
1661
1834
  hulu: { channelSelector: "STARZ (West)", url: "https://www.hulu.com/live" },
1662
1835
  sling: { channelSelector: "Starz West", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
1663
1836
  },
1664
1837
  },
1665
1838
  sundancetv: {
1666
1839
  name: "SundanceTV",
1840
+ tags: ["Movies"],
1667
1841
  pacificStationId: "78806",
1668
1842
  stationId: "71280",
1669
- providers: {
1843
+ services: {
1670
1844
  cox: { channelSelector: "SundanceTV", url: "https://watchtv.cox.com/listings" },
1671
1845
  directv: { channelSelector: "Sundance TV", url: "https://stream.directv.com" },
1672
1846
  spectrum: { channelSelector: "SundanceTV", url: "https://watch.spectrum.net/guide" },
@@ -1676,8 +1850,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1676
1850
  },
1677
1851
  syfy: {
1678
1852
  name: "Syfy",
1853
+ tags: ["Entertainment"],
1679
1854
  stationId: "58623",
1680
- providers: {
1855
+ services: {
1681
1856
  cox: { channelSelector: "SYFY", url: "https://watchtv.cox.com/listings" },
1682
1857
  directv: { channelSelector: "Syfy", url: "https://stream.directv.com" },
1683
1858
  hulu: { channelSelector: "SYFY", url: "https://www.hulu.com/live" },
@@ -1690,15 +1865,17 @@ const BASE_CHANNEL_DEFINITIONS = {
1690
1865
  },
1691
1866
  syfyp: {
1692
1867
  name: "Syfy (Pacific)",
1868
+ tags: ["Entertainment"],
1693
1869
  stationId: "65626",
1694
- providers: {
1870
+ services: {
1695
1871
  site: { channelSelector: "Syfy_West", url: "https://www.usanetwork.com/live" },
1696
1872
  },
1697
1873
  },
1698
1874
  tbs: {
1699
1875
  name: "TBS",
1876
+ tags: ["Entertainment"],
1700
1877
  stationId: "58515",
1701
- providers: {
1878
+ services: {
1702
1879
  cox: { channelSelector: "TBS", url: "https://watchtv.cox.com/listings" },
1703
1880
  directv: { channelSelector: "TBS", url: "https://stream.directv.com" },
1704
1881
  hulu: { channelSelector: "TBS (East)", url: "https://www.hulu.com/live" },
@@ -1711,16 +1888,18 @@ const BASE_CHANNEL_DEFINITIONS = {
1711
1888
  },
1712
1889
  tbsp: {
1713
1890
  name: "TBS (Pacific)",
1891
+ tags: ["Entertainment"],
1714
1892
  stationId: "67890",
1715
- providers: {
1893
+ services: {
1716
1894
  hulu: { channelSelector: "TBS (West)", url: "https://www.hulu.com/live" },
1717
1895
  site: { url: "https://www.tbs.com/watchtbs/west" },
1718
1896
  },
1719
1897
  },
1720
1898
  tcm: {
1721
1899
  name: "TCM",
1900
+ tags: ["Movies"],
1722
1901
  stationId: "64312",
1723
- providers: {
1902
+ services: {
1724
1903
  cox: { channelSelector: "TCM", url: "https://watchtv.cox.com/listings" },
1725
1904
  directv: { channelSelector: "TCM", url: "https://stream.directv.com" },
1726
1905
  hulu: { channelSelector: "TCM (East)", url: "https://www.hulu.com/live" },
@@ -1731,16 +1910,18 @@ const BASE_CHANNEL_DEFINITIONS = {
1731
1910
  },
1732
1911
  tcmp: {
1733
1912
  name: "TCM (Pacific)",
1913
+ tags: ["Movies"],
1734
1914
  stationId: "64312",
1735
1915
  tvgShift: 3,
1736
- providers: {
1916
+ services: {
1737
1917
  hulu: { channelSelector: "TCM (West)", url: "https://www.hulu.com/live" },
1738
1918
  },
1739
1919
  },
1740
1920
  tennis: {
1741
1921
  name: "Tennis Channel",
1922
+ tags: ["Sports"],
1742
1923
  stationId: "60316",
1743
- providers: {
1924
+ services: {
1744
1925
  cox: { channelSelector: "Tennis Channel", url: "https://watchtv.cox.com/listings" },
1745
1926
  directv: { channelSelector: "Tennis Channel HD", url: "https://stream.directv.com" },
1746
1927
  spectrum: { channelSelector: "Tennis Channel", url: "https://watch.spectrum.net/guide" },
@@ -1750,8 +1931,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1750
1931
  },
1751
1932
  tennis2: {
1752
1933
  name: "Tennis Channel 2",
1934
+ tags: ["Sports"],
1753
1935
  stationId: "137752",
1754
- providers: {
1936
+ services: {
1755
1937
  cox: { channelSelector: "T2", url: "https://watchtv.cox.com/listings" },
1756
1938
  hulu: { channelSelector: "Tennis Channel 2", url: "https://www.hulu.com/live" },
1757
1939
  sling: { channelSelector: "T2", url: "https://watch.sling.com/dashboard/grid_guide/grid_guide_a_z" },
@@ -1761,9 +1943,10 @@ const BASE_CHANNEL_DEFINITIONS = {
1761
1943
  },
1762
1944
  tlc: {
1763
1945
  name: "TLC",
1946
+ tags: ["Lifestyle"],
1764
1947
  pacificStationId: "79911",
1765
1948
  stationId: "57391",
1766
- providers: {
1949
+ services: {
1767
1950
  cox: { channelSelector: "TLC", url: "https://watchtv.cox.com/listings" },
1768
1951
  directv: { channelSelector: "TLC", url: "https://stream.directv.com" },
1769
1952
  hulu: { channelSelector: "TLC", url: "https://www.hulu.com/live" },
@@ -1776,8 +1959,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1776
1959
  },
1777
1960
  tnt: {
1778
1961
  name: "TNT",
1962
+ tags: ["Entertainment"],
1779
1963
  stationId: "42642",
1780
- providers: {
1964
+ services: {
1781
1965
  cox: { channelSelector: "TNT", url: "https://watchtv.cox.com/listings" },
1782
1966
  directv: { channelSelector: "TNT", url: "https://stream.directv.com" },
1783
1967
  hulu: { channelSelector: "TNT (East)", url: "https://www.hulu.com/live" },
@@ -1790,17 +1974,19 @@ const BASE_CHANNEL_DEFINITIONS = {
1790
1974
  },
1791
1975
  tntp: {
1792
1976
  name: "TNT (Pacific)",
1977
+ tags: ["Entertainment"],
1793
1978
  stationId: "61340",
1794
- providers: {
1979
+ services: {
1795
1980
  hulu: { channelSelector: "TNT (West)", url: "https://www.hulu.com/live" },
1796
1981
  site: { url: "https://www.tntdrama.com/watchtnt/west" },
1797
1982
  },
1798
1983
  },
1799
1984
  travel: {
1800
1985
  name: "Travel",
1986
+ tags: ["Lifestyle"],
1801
1987
  pacificStationId: "64525",
1802
1988
  stationId: "59303",
1803
- providers: {
1989
+ services: {
1804
1990
  cox: { channelSelector: "Travel Channel", url: "https://watchtv.cox.com/listings" },
1805
1991
  directv: { channelSelector: "Travel Channel", url: "https://stream.directv.com" },
1806
1992
  hulu: { channelSelector: "Travel Channel", url: "https://www.hulu.com/live" },
@@ -1813,9 +1999,10 @@ const BASE_CHANNEL_DEFINITIONS = {
1813
1999
  },
1814
2000
  trutv: {
1815
2001
  name: "truTV",
2002
+ tags: ["Entertainment"],
1816
2003
  pacificStationId: "65717",
1817
2004
  stationId: "64490",
1818
- providers: {
2005
+ services: {
1819
2006
  cox: { channelSelector: "truTV", url: "https://watchtv.cox.com/listings" },
1820
2007
  directv: { channelSelector: "truTV", url: "https://stream.directv.com" },
1821
2008
  hulu: { channelSelector: "truTV (East)", url: "https://www.hulu.com/live" },
@@ -1828,16 +2015,18 @@ const BASE_CHANNEL_DEFINITIONS = {
1828
2015
  },
1829
2016
  trutvp: {
1830
2017
  name: "truTV (Pacific)",
2018
+ tags: ["Entertainment"],
1831
2019
  stationId: "65717",
1832
- providers: {
2020
+ services: {
1833
2021
  hulu: { channelSelector: "truTV (West)", url: "https://www.hulu.com/live" },
1834
2022
  },
1835
2023
  },
1836
2024
  tvland: {
1837
2025
  name: "TV Land",
2026
+ tags: ["Entertainment"],
1838
2027
  pacificStationId: "74134",
1839
2028
  stationId: "73541",
1840
- providers: {
2029
+ services: {
1841
2030
  cox: { channelSelector: "TV Land", url: "https://watchtv.cox.com/listings" },
1842
2031
  directv: { channelSelector: "TV Land", url: "https://stream.directv.com" },
1843
2032
  hulu: { channelSelector: "TV Land", url: "https://www.hulu.com/live" },
@@ -1848,8 +2037,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1848
2037
  },
1849
2038
  usa: {
1850
2039
  name: "USA Network",
2040
+ tags: ["Entertainment"],
1851
2041
  stationId: "58452",
1852
- providers: {
2042
+ services: {
1853
2043
  cox: { channelSelector: "USA", url: "https://watchtv.cox.com/listings" },
1854
2044
  directv: { channelSelector: "USA Network", url: "https://stream.directv.com" },
1855
2045
  hulu: { channelSelector: "USA", url: "https://www.hulu.com/live" },
@@ -1862,16 +2052,18 @@ const BASE_CHANNEL_DEFINITIONS = {
1862
2052
  },
1863
2053
  usap: {
1864
2054
  name: "USA Network (Pacific)",
2055
+ tags: ["Entertainment"],
1865
2056
  stationId: "74030",
1866
- providers: {
2057
+ services: {
1867
2058
  site: { channelSelector: "USA_West", url: "https://www.usanetwork.com/live" },
1868
2059
  },
1869
2060
  },
1870
2061
  vh1: {
1871
2062
  name: "VH1",
2063
+ tags: ["Entertainment"],
1872
2064
  pacificStationId: "64634",
1873
2065
  stationId: "60046",
1874
- providers: {
2066
+ services: {
1875
2067
  cox: { channelSelector: "VH1", url: "https://watchtv.cox.com/listings" },
1876
2068
  directv: { channelSelector: "VH1", url: "https://stream.directv.com" },
1877
2069
  hulu: { channelSelector: "VH1", url: "https://www.hulu.com/live" },
@@ -1883,9 +2075,10 @@ const BASE_CHANNEL_DEFINITIONS = {
1883
2075
  },
1884
2076
  vice: {
1885
2077
  name: "Vice",
2078
+ tags: ["Entertainment"],
1886
2079
  pacificStationId: "92375",
1887
2080
  stationId: "65732",
1888
- providers: {
2081
+ services: {
1889
2082
  cox: { channelSelector: "VICE", url: "https://watchtv.cox.com/listings" },
1890
2083
  directv: { channelSelector: "VICE", url: "https://stream.directv.com" },
1891
2084
  hulu: { channelSelector: "Vice", url: "https://www.hulu.com/live" },
@@ -1896,8 +2089,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1896
2089
  },
1897
2090
  weather: {
1898
2091
  name: "The Weather Channel",
2092
+ tags: ["News"],
1899
2093
  stationId: "58812",
1900
- providers: {
2094
+ services: {
1901
2095
  cox: { channelSelector: "Weather Channel", url: "https://watchtv.cox.com/listings" },
1902
2096
  directv: { channelSelector: "The Weather Channel HD", url: "https://stream.directv.com" },
1903
2097
  hulu: { channelSelector: "The Weather Channel", url: "https://www.hulu.com/live" },
@@ -1908,9 +2102,10 @@ const BASE_CHANNEL_DEFINITIONS = {
1908
2102
  },
1909
2103
  wetv: {
1910
2104
  name: "WE tv",
2105
+ tags: ["Entertainment"],
1911
2106
  pacificStationId: "108192",
1912
2107
  stationId: "59296",
1913
- providers: {
2108
+ services: {
1914
2109
  cox: { channelSelector: "WE tv", url: "https://watchtv.cox.com/listings" },
1915
2110
  directv: { channelSelector: "WE TV", url: "https://stream.directv.com" },
1916
2111
  spectrum: { channelSelector: "WE tv", url: "https://watch.spectrum.net/guide" },
@@ -1920,8 +2115,9 @@ const BASE_CHANNEL_DEFINITIONS = {
1920
2115
  },
1921
2116
  yes: {
1922
2117
  name: "YES Network",
2118
+ tags: ["Sports"],
1923
2119
  stationId: "63558",
1924
- providers: {
2120
+ services: {
1925
2121
  directv: { channelSelector: "Yes Network HD", url: "https://stream.directv.com" },
1926
2122
  spectrum: { channelSelector: "YES Network", url: "https://watch.spectrum.net/guide" },
1927
2123
  },
@@ -1930,36 +2126,36 @@ const BASE_CHANNEL_DEFINITIONS = {
1930
2126
  /* eslint-enable @hjdhjd/blank-line-after-open-brace, @stylistic/comma-dangle, sort-keys */
1931
2127
  // Pacific channel auto-generation.
1932
2128
  /* PrismCast automatically generates Pacific timezone channel definitions to reduce manual maintenance. Generation runs at module load, producing definitions
1933
- * that are functionally identical to hand-written ones. Generated definitions never override manually-defined ones — if a key already exists in
2129
+ * that are functionally identical to hand-written ones. Generated definitions never override manually-defined ones - if a key already exists in
1934
2130
  * BASE_CHANNEL_DEFINITIONS, the manual definition takes precedence.
1935
2131
  *
1936
- * Step 1 — Generate Pacific ChannelDefinitions from East entries with pacificStationId:
2132
+ * Step 1 - Generate Pacific ChannelDefinitions from East entries with pacificStationId:
1937
2133
  *
1938
2134
  * When an East definition has a pacificStationId field and no "{key}p" entry exists in BASE_CHANNEL_DEFINITIONS, a new Pacific ChannelDefinition is created
1939
- * with the Pacific station ID, " (Pacific)" appended to the name, and an empty providers map (to be filled by Step 2).
2135
+ * with the Pacific station ID, " (Pacific)" appended to the name, and an empty services map (to be filled by Step 2).
1940
2136
  *
1941
- * Example — adding pacificStationId to the East definition:
1942
- * animal: { name: "Animal Planet", pacificStationId: "68785", stationId: "57394", providers: { ... } }
2137
+ * Example - adding pacificStationId to the East definition:
2138
+ * animal: { name: "Animal Planet", pacificStationId: "68785", stationId: "57394", services: { ... } }
1943
2139
  * Auto-generates:
1944
- * animalp: { name: "Animal Planet (Pacific)", stationId: "68785", providers: {} }
2140
+ * animalp: { name: "Animal Planet (Pacific)", stationId: "68785", services: {} }
1945
2141
  *
1946
- * Step 2 — Merge East providers into Pacific definitions:
2142
+ * Step 2 - Merge East services into Pacific definitions:
1947
2143
  *
1948
- * For every Pacific definition "{key}p" (manual or generated), if a corresponding East definition "{key}" exists, its providers are merged into the Pacific
1949
- * definition. Providers are skipped if: (a) they already exist in the Pacific definition, or (b) their channelSelector contains "East" or "West" (these have
2144
+ * For every Pacific definition "{key}p" (manual or generated), if a corresponding East definition "{key}" exists, its services are merged into the Pacific
2145
+ * definition. Services are skipped if: (a) they already exist in the Pacific definition, or (b) their channelSelector contains "East" or "West" (these have
1950
2146
  * timezone-specific entries and need manual Pacific definitions with the correct West selector).
1951
2147
  *
1952
- * Example — East providers merged into auto-generated Pacific:
1953
- * animal's cox provider: { channelSelector: "Animal Planet", url: "https://watchtv.cox.com/listings" }
2148
+ * Example - East services merged into auto-generated Pacific:
2149
+ * animal's cox service: { channelSelector: "Animal Planet", url: "https://watchtv.cox.com/listings" }
1954
2150
  * Merges into animalp as:
1955
- * animalp's cox provider: { channelSelector: "Animal Planet", url: "https://watchtv.cox.com/listings" }
2151
+ * animalp's cox service: { channelSelector: "Animal Planet", url: "https://watchtv.cox.com/listings" }
1956
2152
  *
1957
2153
  * Adding a new channel with Pacific support:
1958
2154
  *
1959
2155
  * 1. Look up both East and Pacific HD station IDs in Gracenote (http://localhost:8089/tms/stations/<search>).
1960
- * 2. Add the East definition with both IDs: mychannel: { name: "...", pacificStationId: "PACIFIC_ID", stationId: "EAST_ID", providers: { ... } }
1961
- * 3. The system auto-generates mychannelp (Pacific definition) and merges all compatible providers.
1962
- * 4. If the Pacific version needs a different URL or channelSelector for specific providers, define mychannelp manually with those overrides.
2156
+ * 2. Add the East definition with both IDs: mychannel: { name: "...", pacificStationId: "PACIFIC_ID", stationId: "EAST_ID", services: { ... } }
2157
+ * 3. The system auto-generates mychannelp (Pacific definition) and merges all compatible services.
2158
+ * 4. If the Pacific version needs a different URL or channelSelector for specific services, define mychannelp manually with those overrides.
1963
2159
  */
1964
2160
  function generatePacificDefinitions(definitions) {
1965
2161
  const eastWestPattern = /east|west/i;
@@ -1976,14 +2172,15 @@ function generatePacificDefinitions(definitions) {
1976
2172
  }
1977
2173
  generated[pacificKey] = {
1978
2174
  name: def.name + " (Pacific)",
1979
- providers: {},
1980
- stationId: def.pacificStationId
2175
+ services: {},
2176
+ stationId: def.pacificStationId,
2177
+ ...(def.tags ? { tags: def.tags } : {})
1981
2178
  };
1982
2179
  }
1983
2180
  // Merge base and generated for Pacific lookup in Step 2.
1984
2181
  const allDefinitions = { ...definitions, ...generated };
1985
- // Step 2: Merge East providers into Pacific definitions (both manual and generated). For manually-defined Pacific entries, we create a copy with a fresh
1986
- // providers map to avoid mutating the input definitions.
2182
+ // Step 2: Merge East services into Pacific definitions (both manual and generated). For manually-defined Pacific entries, we create a copy with a fresh
2183
+ // services map to avoid mutating the input definitions.
1987
2184
  for (const [pacKey, originalPacDef] of Object.entries(allDefinitions)) {
1988
2185
  // Only process Pacific keys (ending in "p" with a corresponding East key).
1989
2186
  if (!pacKey.endsWith("p")) {
@@ -1995,20 +2192,20 @@ function generatePacificDefinitions(definitions) {
1995
2192
  if (!eastDef) {
1996
2193
  continue;
1997
2194
  }
1998
- // Create a copy with a fresh providers map so we never mutate the input definitions (which are the module-level BASE_CHANNEL_DEFINITIONS).
1999
- const pacDef = { ...originalPacDef, providers: { ...originalPacDef.providers } };
2000
- // Merge each East provider into the Pacific definition, skipping existing and East/West-specific selectors.
2001
- for (const [slug, variant] of Object.entries(eastDef.providers)) {
2002
- // Don't overwrite existing Pacific providers (manual overrides take precedence).
2003
- if (slug in pacDef.providers) {
2195
+ // Create a copy with a fresh services map so we never mutate the input definitions (which are the module-level BASE_CHANNEL_DEFINITIONS).
2196
+ const pacDef = { ...originalPacDef, services: { ...originalPacDef.services } };
2197
+ // Merge each East service into the Pacific definition, skipping existing and East/West-specific selectors.
2198
+ for (const [slug, variant] of Object.entries(eastDef.services)) {
2199
+ // Don't overwrite existing Pacific services (manual overrides take precedence).
2200
+ if (slug in pacDef.services) {
2004
2201
  continue;
2005
2202
  }
2006
- // Skip providers with timezone-specific channelSelectors — these need manual Pacific entries.
2203
+ // Skip services with timezone-specific channelSelectors - these need manual Pacific entries.
2007
2204
  if (variant.channelSelector && eastWestPattern.test(variant.channelSelector)) {
2008
2205
  continue;
2009
2206
  }
2010
- // Copy the provider variant. We spread to create a new object so the East and Pacific definitions don't share references.
2011
- pacDef.providers[slug] = { ...variant };
2207
+ // Copy the service variant. We spread to create a new object so the East and Pacific definitions don't share references.
2208
+ pacDef.services[slug] = { ...variant };
2012
2209
  }
2013
2210
  generated[pacKey] = pacDef;
2014
2211
  }
@@ -2016,41 +2213,41 @@ function generatePacificDefinitions(definitions) {
2016
2213
  }
2017
2214
  // Channel definition flattener.
2018
2215
  /* The flattener compiles nested ChannelDefinition entries into the flat ChannelMap consumed by the rest of the codebase. For each definition, it produces a
2019
- * canonical flat entry (keyed by the definition key) and variant flat entries (keyed as "{definitionKey}-{providerSlug}").
2216
+ * canonical flat entry (keyed by the definition key) and variant flat entries (keyed as "{definitionKey}-{serviceSlug}").
2020
2217
  *
2021
2218
  * Canonical resolution:
2022
- * 1. If "site" exists in providers, the site provider populates the canonical entry. No "{key}-site" variant is emitted.
2023
- * 2. Otherwise, providers are sorted alphabetically by key. The first provider populates the canonical entry. No variant key is emitted for it.
2024
- * 3. All remaining providers produce variant entries keyed as "{key}-{slug}".
2219
+ * 1. If "site" exists in services, the site service populates the canonical entry. No "{key}-site" variant is emitted.
2220
+ * 2. Otherwise, services are sorted alphabetically by key. The first service populates the canonical entry. No variant key is emitted for it.
2221
+ * 3. All remaining services produce variant entries keyed as "{key}-{slug}".
2025
2222
  *
2026
- * Identity fields (name, stationId, channelNumber, tvgShift) are set on the canonical entry and inherited by all variants. Provider-specific fields
2027
- * (channelSelector, url, profile, etc.) come from each ProviderVariant. ProviderVariant fields override ChannelDefinition fields when both are set.
2223
+ * Identity fields (name, stationId, channelNumber, tvgShift) are set on the canonical entry and inherited by all variants. Service-specific fields
2224
+ * (channelSelector, url, profile, etc.) come from each ServiceVariant. ServiceVariant fields override ChannelDefinition fields when both are set.
2028
2225
  */
2029
2226
  function flattenChannelDefinitions(definitions) {
2030
2227
  const channels = {};
2031
2228
  for (const [key, def] of Object.entries(definitions)) {
2032
- const slugs = Object.keys(def.providers).sort();
2229
+ const slugs = Object.keys(def.services).sort();
2033
2230
  if (slugs.length === 0) {
2034
2231
  continue;
2035
2232
  }
2036
- // Determine the canonical provider: "site" wins, otherwise first alphabetically.
2233
+ // Determine the canonical service: "site" wins, otherwise first alphabetically.
2037
2234
  const canonicalSlug = slugs.includes(SITE_KEY) ? SITE_KEY : slugs[0];
2038
- const canonicalVariant = def.providers[canonicalSlug];
2039
- // Build the canonical flat entry with identity fields + canonical provider's fields. pacificStationId is set only on the canonical entry — it drives Pacific
2040
- // auto-generation and is not meaningful on provider variants.
2235
+ const canonicalVariant = def.services[canonicalSlug];
2236
+ // Build the canonical flat entry with identity fields + canonical service's fields. pacificStationId is set only on the canonical entry - it drives Pacific
2237
+ // auto-generation and is not meaningful on service variants.
2041
2238
  const canonicalEntry = buildFlatEntry(def, canonicalVariant);
2042
2239
  if (def.pacificStationId) {
2043
2240
  canonicalEntry.pacificStationId = def.pacificStationId;
2044
2241
  }
2045
2242
  channels[key] = canonicalEntry;
2046
- // Build variant entries for all non-canonical providers. Each variant gets canonicalKey set to the definition key so that buildProviderGroups can group
2047
- // channels by a single mechanism — scanning canonicalKey — regardless of whether the channel is predefined or user-defined.
2243
+ // Build variant entries for all non-canonical services. Each variant gets canonicalKey set to the definition key so that buildServiceGroups can group
2244
+ // channels by a single mechanism - scanning canonicalKey - regardless of whether the channel is predefined or user-defined.
2048
2245
  for (const slug of slugs) {
2049
2246
  if (slug === canonicalSlug) {
2050
2247
  continue;
2051
2248
  }
2052
2249
  const variantKey = key + "-" + slug;
2053
- const variant = def.providers[slug];
2250
+ const variant = def.services[slug];
2054
2251
  const variantEntry = buildFlatEntry(def, variant);
2055
2252
  variantEntry.canonicalKey = key;
2056
2253
  channels[variantKey] = variantEntry;
@@ -2059,10 +2256,10 @@ function flattenChannelDefinitions(definitions) {
2059
2256
  return channels;
2060
2257
  }
2061
2258
  /**
2062
- * Builds a flat Channel entry by merging a ChannelDefinition's identity fields with a ProviderVariant's provider-specific fields. ProviderVariant fields
2259
+ * Builds a flat Channel entry by merging a ChannelDefinition's identity fields with a ServiceVariant's service-specific fields. ServiceVariant fields
2063
2260
  * override ChannelDefinition fields when both are set.
2064
2261
  * @param def - The parent ChannelDefinition with identity fields.
2065
- * @param variant - The ProviderVariant with provider-specific fields.
2262
+ * @param variant - The ServiceVariant with service-specific fields.
2066
2263
  * @returns A flat Channel entry.
2067
2264
  */
2068
2265
  function buildFlatEntry(def, variant) {
@@ -2079,37 +2276,26 @@ function buildFlatEntry(def, variant) {
2079
2276
  if (channelNumber !== undefined) {
2080
2277
  entry.channelNumber = channelNumber;
2081
2278
  }
2279
+ // Tags from definition only (identity field, inherited by all variants).
2280
+ if (def.tags) {
2281
+ entry.tags = def.tags.slice();
2282
+ }
2082
2283
  // tvgShift from definition only (not overridable per-variant).
2083
2284
  if (def.tvgShift !== undefined) {
2084
2285
  entry.tvgShift = def.tvgShift;
2085
2286
  }
2086
- // Provider-specific fields from ProviderVariant.
2087
- if (variant.channelSelector) {
2088
- entry.channelSelector = variant.channelSelector;
2089
- }
2090
- if (variant.dismissSelector) {
2091
- entry.dismissSelector = variant.dismissSelector;
2092
- }
2093
- if (variant.profile) {
2094
- entry.profile = variant.profile;
2095
- }
2096
- if (variant.provider) {
2097
- entry.provider = variant.provider;
2098
- }
2099
- if (variant.scrollSelector) {
2100
- entry.scrollSelector = variant.scrollSelector;
2101
- }
2102
- if (variant.scrollTarget) {
2103
- entry.scrollTarget = variant.scrollTarget;
2104
- }
2105
- if (variant.scrollToBottom !== undefined) {
2106
- entry.scrollToBottom = variant.scrollToBottom;
2287
+ // Service-specific fields from ServiceVariant.
2288
+ const variantKeys = ["channelSelector", "dismissSelector", "profile", "scrollSelector", "scrollTarget", "scrollToBottom", "service"];
2289
+ for (const key of variantKeys) {
2290
+ if (variant[key] !== undefined) {
2291
+ entry[key] = variant[key];
2292
+ }
2107
2293
  }
2108
2294
  return entry;
2109
2295
  }
2110
2296
  // Compile the nested definitions into flat output.
2111
2297
  // Pacific-generated entries take precedence over base entries because Step 2 of Pacific generation produces enhanced copies of manual Pacific definitions
2112
- // (e.g., cartoonp with merged East providers). Base entries for non-Pacific keys are unaffected since they don't appear in the generated map.
2298
+ // (e.g., cartoonp with merged East services). Base entries for non-Pacific keys are unaffected since they don't appear in the generated map.
2113
2299
  const allDefinitions = { ...BASE_CHANNEL_DEFINITIONS, ...generatePacificDefinitions(BASE_CHANNEL_DEFINITIONS) };
2114
2300
  const CHANNELS = flattenChannelDefinitions(allDefinitions);
2115
2301
  export { CHANNELS, CHANNELS as PREDEFINED_CHANNELS };