This commit is contained in:
freearhey 2023-10-09 07:15:34 +03:00
parent b6e7d1e947
commit 50365756f7
64 changed files with 122 additions and 89 deletions

11
api.sh Executable file
View file

@ -0,0 +1,11 @@
#!/bin/bash
mkdir -p src/data
curl -L -o src/data/blocklist.json https://iptv-org.github.io/api/blocklist.json
curl -L -o src/data/categories.json https://iptv-org.github.io/api/categories.json
curl -L -o src/data/channels.json https://iptv-org.github.io/api/channels.json
curl -L -o src/data/streams.json https://iptv-org.github.io/api/streams.json
curl -L -o src/data/countries.json https://iptv-org.github.io/api/countries.json
curl -L -o src/data/languages.json https://iptv-org.github.io/api/languages.json
curl -L -o src/data/regions.json https://iptv-org.github.io/api/regions.json
curl -L -o src/data/subdivisions.json https://iptv-org.github.io/api/subdivisions.json

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View file

@ -1 +1 @@
import{I as d,s as w}from"./index.33dbc0d8.js";const u=[];function p(e,t=d){let n;const o=new Set;function r(s){if(w(e,s)&&(e=s,n)){const l=!u.length;for(const i of o)i[1](),u.push(i,e);if(l){for(let i=0;i<u.length;i+=2)u[i][0](u[i+1]);u.length=0}}}function c(s){r(s(e))}function a(s,l=d){const i=[s,l];return o.add(i),o.size===1&&(n=t(r)||d),s(e),()=>{o.delete(i),o.size===0&&(n(),n=null)}}return{set:r,update:c,subscribe:a}}var g;const x=((g=globalThis.__sveltekit_it7xqx)==null?void 0:g.base)??"";var k;const E=((k=globalThis.__sveltekit_it7xqx)==null?void 0:k.assets)??x,A="1696552312143",T="sveltekit:snapshot",y="sveltekit:scroll",O="sveltekit:index",_={tap:1,hover:2,viewport:3,eager:4,off:-1};function U(e){let t=e.baseURI;if(!t){const n=e.getElementsByTagName("base");t=n.length?n[0].href:e.URL}return t}function q(){return{x:pageXOffset,y:pageYOffset}}function f(e,t){return e.getAttribute(`data-sveltekit-${t}`)}const b={..._,"":_.hover};function m(e){let t=e.assignedSlot??e.parentNode;return(t==null?void 0:t.nodeType)===11&&(t=t.host),t}function L(e,t){for(;e&&e!==t;){if(e.nodeName.toUpperCase()==="A"&&e.hasAttribute("href"))return e;e=m(e)}}function N(e,t){let n;try{n=new URL(e instanceof SVGAElement?e.href.baseVal:e.href,document.baseURI)}catch{}const o=e instanceof SVGAElement?e.target.baseVal:e.target,r=!n||!!o||R(n,t)||(e.getAttribute("rel")||"").split(/\s+/).includes("external"),c=(n==null?void 0:n.origin)===location.origin&&e.hasAttribute("download");return{url:n,external:r,target:o,download:c}}function P(e){let t=null,n=null,o=null,r=null,c=null,a=null,s=e;for(;s&&s!==document.documentElement;)o===null&&(o=f(s,"preload-code")),r===null&&(r=f(s,"preload-data")),t===null&&(t=f(s,"keepfocus")),n===null&&(n=f(s,"noscroll")),c===null&&(c=f(s,"reload")),a===null&&(a=f(s,"replacestate")),s=m(s);function l(i){switch(i){case"":case"true":return!0;case"off":case"false":return!1;default:return null}}return{preload_code:b[o??"off"],preload_data:b[r??"off"],keep_focus:l(t),noscroll:l(n),reload:l(c),replace_state:l(a)}}function h(e){const t=p(e);let n=!0;function o(){n=!0,t.update(a=>a)}function r(a){n=!1,t.set(a)}function c(a){let s;return t.subscribe(l=>{(s===void 0||n&&l!==s)&&a(s=l)})}return{notify:o,set:r,subscribe:c}}function I(){const{set:e,subscribe:t}=p(!1);let n;async function o(){clearTimeout(n);try{const r=await fetch(`${E}/_app/version.json`,{headers:{pragma:"no-cache","cache-control":"no-cache"}});if(!r.ok)return!1;const a=(await r.json()).version!==A;return a&&(e(!0),clearTimeout(n)),a}catch{return!1}}return{subscribe:t,check:o}}function R(e,t){return e.origin!==location.origin||!e.pathname.startsWith(t)}let v;function V(e){v=e.client}function Y(e){return(...t)=>v[e](...t)}const j={url:h({}),page:h({}),navigating:p(null),updated:I()};export{O as I,_ as P,y as S,T as a,N as b,P as c,j as d,x as e,L as f,U as g,V as h,R as i,Y as j,q as s,p as w};
import{I as d,s as w}from"./index.33dbc0d8.js";const u=[];function p(e,t=d){let n;const o=new Set;function r(s){if(w(e,s)&&(e=s,n)){const i=!u.length;for(const l of o)l[1](),u.push(l,e);if(i){for(let l=0;l<u.length;l+=2)u[l][0](u[l+1]);u.length=0}}}function c(s){r(s(e))}function a(s,i=d){const l=[s,i];return o.add(l),o.size===1&&(n=t(r)||d),s(e),()=>{o.delete(l),o.size===0&&(n(),n=null)}}return{set:r,update:c,subscribe:a}}var g;const E=((g=globalThis.__sveltekit_fudz0b)==null?void 0:g.base)??"";var k;const A=((k=globalThis.__sveltekit_fudz0b)==null?void 0:k.assets)??E,I="1696824804235",y="sveltekit:snapshot",x="sveltekit:scroll",O="sveltekit:index",_={tap:1,hover:2,viewport:3,eager:4,off:-1};function U(e){let t=e.baseURI;if(!t){const n=e.getElementsByTagName("base");t=n.length?n[0].href:e.URL}return t}function L(){return{x:pageXOffset,y:pageYOffset}}function f(e,t){return e.getAttribute(`data-sveltekit-${t}`)}const b={..._,"":_.hover};function m(e){let t=e.assignedSlot??e.parentNode;return(t==null?void 0:t.nodeType)===11&&(t=t.host),t}function N(e,t){for(;e&&e!==t;){if(e.nodeName.toUpperCase()==="A"&&e.hasAttribute("href"))return e;e=m(e)}}function z(e,t){let n;try{n=new URL(e instanceof SVGAElement?e.href.baseVal:e.href,document.baseURI)}catch{}const o=e instanceof SVGAElement?e.target.baseVal:e.target,r=!n||!!o||S(n,t)||(e.getAttribute("rel")||"").split(/\s+/).includes("external"),c=(n==null?void 0:n.origin)===location.origin&&e.hasAttribute("download");return{url:n,external:r,target:o,download:c}}function P(e){let t=null,n=null,o=null,r=null,c=null,a=null,s=e;for(;s&&s!==document.documentElement;)o===null&&(o=f(s,"preload-code")),r===null&&(r=f(s,"preload-data")),t===null&&(t=f(s,"keepfocus")),n===null&&(n=f(s,"noscroll")),c===null&&(c=f(s,"reload")),a===null&&(a=f(s,"replacestate")),s=m(s);function i(l){switch(l){case"":case"true":return!0;case"off":case"false":return!1;default:return null}}return{preload_code:b[o??"off"],preload_data:b[r??"off"],keep_focus:i(t),noscroll:i(n),reload:i(c),replace_state:i(a)}}function h(e){const t=p(e);let n=!0;function o(){n=!0,t.update(a=>a)}function r(a){n=!1,t.set(a)}function c(a){let s;return t.subscribe(i=>{(s===void 0||n&&i!==s)&&a(s=i)})}return{notify:o,set:r,subscribe:c}}function R(){const{set:e,subscribe:t}=p(!1);let n;async function o(){clearTimeout(n);try{const r=await fetch(`${A}/_app/version.json`,{headers:{pragma:"no-cache","cache-control":"no-cache"}});if(!r.ok)return!1;const a=(await r.json()).version!==I;return a&&(e(!0),clearTimeout(n)),a}catch{return!1}}return{subscribe:t,check:o}}function S(e,t){return e.origin!==location.origin||!e.pathname.startsWith(t)}let v;function V(e){v=e.client}function Y(e){return(...t)=>v[e](...t)}const j={url:h({}),page:h({}),navigating:p(null),updated:R()};export{O as I,_ as P,x as S,y as a,z as b,P as c,j as d,E as e,N as f,U as g,V as h,S as i,Y as j,L as s,p as w};

Binary file not shown.

Binary file not shown.

View file

@ -1 +1 @@
import"./index.33dbc0d8.js";import{d as e}from"./singletons.7472e3f8.js";const r=()=>{const s=e;return{page:{subscribe:s.page.subscribe},navigating:{subscribe:s.navigating.subscribe},updated:s.updated}},b={subscribe(s){return r().page.subscribe(s)}};export{b as p};
import"./index.33dbc0d8.js";import{d as e}from"./singletons.8071cb2e.js";const r=()=>{const s=e;return{page:{subscribe:s.page.subscribe},navigating:{subscribe:s.navigating.subscribe},updated:s.updated}},b={subscribe(s){return r().page.subscribe(s)}};export{b as p};

View file

@ -0,0 +1,2 @@
 `DÑ9£©3+D}ÛÆÞ‚"z\8ŠßxѨñ¤³:¿àû<C3A0>)Ê{|.e ƒ‰Ê[îoyš©¹+· ÄáËI²£ˆN¼÷iÜdWu´ Z²¦y'kÄrQüÕê7MôKñ¿Øîor29ˆo”Æ
\„ 'Ï âˆiÔ3³ÛaÐVÆj‚â^^LÉ

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View file

@ -1 +1 @@
import{S as x,i as S,s as g,k as u,q as h,a as k,l as d,m as v,r as E,h as m,c as y,b as _,E as b,u as $,I as q,J as C}from"../chunks/index.33dbc0d8.js";import{p as H}from"../chunks/stores.b56ccc8c.js";function I(l){var f;let a,t=l[0].status+"",r,o,n,p=((f=l[0].error)==null?void 0:f.message)+"",c;return{c(){a=u("h1"),r=h(t),o=k(),n=u("p"),c=h(p)},l(e){a=d(e,"H1",{});var s=v(a);r=E(s,t),s.forEach(m),o=y(e),n=d(e,"P",{});var i=v(n);c=E(i,p),i.forEach(m)},m(e,s){_(e,a,s),b(a,r),_(e,o,s),_(e,n,s),b(n,c)},p(e,[s]){var i;s&1&&t!==(t=e[0].status+"")&&$(r,t),s&1&&p!==(p=((i=e[0].error)==null?void 0:i.message)+"")&&$(c,p)},i:q,o:q,d(e){e&&m(a),e&&m(o),e&&m(n)}}}function J(l,a,t){let r;return C(l,H,o=>t(0,r=o)),[r]}class w extends x{constructor(a){super(),S(this,a,J,I,g,{})}}export{w as component};
import{S as x,i as S,s as g,k as u,q as h,a as k,l as d,m as v,r as E,h as m,c as y,b as _,E as b,u as $,I as q,J as C}from"../chunks/index.33dbc0d8.js";import{p as H}from"../chunks/stores.a09c62bd.js";function I(l){var f;let a,t=l[0].status+"",r,o,n,p=((f=l[0].error)==null?void 0:f.message)+"",c;return{c(){a=u("h1"),r=h(t),o=k(),n=u("p"),c=h(p)},l(e){a=d(e,"H1",{});var s=v(a);r=E(s,t),s.forEach(m),o=y(e),n=d(e,"P",{});var i=v(n);c=E(i,p),i.forEach(m)},m(e,s){_(e,a,s),b(a,r),_(e,o,s),_(e,n,s),b(n,c)},p(e,[s]){var i;s&1&&t!==(t=e[0].status+"")&&$(r,t),s&1&&p!==(p=((i=e[0].error)==null?void 0:i.message)+"")&&$(c,p)},i:q,o:q,d(e){e&&m(a),e&&m(o),e&&m(n)}}}function J(l,a,t){let r;return C(l,H,o=>t(0,r=o)),[r]}class w extends x{constructor(a){super(),S(this,a,J,I,g,{})}}export{w as component};

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View file

@ -1 +1 @@
{"version":"1696552312143"}
{"version":"1696824804235"}

Binary file not shown.

Binary file not shown.

View file

@ -8,14 +8,14 @@
<link href="./_app/immutable/assets/0.039b7214.css" rel="stylesheet">
<link href="./_app/immutable/assets/EditButton.0d24e5da.css" rel="stylesheet">
<link rel="modulepreload" href="./_app/immutable/entry/start.a461f483.js">
<link rel="modulepreload" href="./_app/immutable/entry/start.d80b9438.js">
<link rel="modulepreload" href="./_app/immutable/chunks/index.33dbc0d8.js">
<link rel="modulepreload" href="./_app/immutable/chunks/singletons.7472e3f8.js">
<link rel="modulepreload" href="./_app/immutable/entry/app.e1f5bfa5.js">
<link rel="modulepreload" href="./_app/immutable/chunks/singletons.8071cb2e.js">
<link rel="modulepreload" href="./_app/immutable/entry/app.9b602d9d.js">
<link rel="modulepreload" href="./_app/immutable/nodes/0.1654e388.js">
<link rel="modulepreload" href="./_app/immutable/nodes/3.dd846bcd.js">
<link rel="modulepreload" href="./_app/immutable/chunks/EditButton.0d8ca4d9.js">
<link rel="modulepreload" href="./_app/immutable/chunks/stores.b56ccc8c.js"><title>iptv-org</title><!-- HEAD_svelte-bjnlvt_START --><script>if (document) {
<link rel="modulepreload" href="./_app/immutable/nodes/3.5f07a693.js">
<link rel="modulepreload" href="./_app/immutable/chunks/EditButton.36510adc.js">
<link rel="modulepreload" href="./_app/immutable/chunks/stores.a09c62bd.js"><title>iptv-org</title><!-- HEAD_svelte-bjnlvt_START --><script>if (document) {
let mode = localStorage.theme || 'light'
if (mode === 'dark' || window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.classList.add('dark')
@ -57,7 +57,7 @@
<script>
{
__sveltekit_it7xqx = {
__sveltekit_fudz0b = {
base: new URL(".", location).pathname.slice(0, -1),
env: {}
};
@ -67,8 +67,8 @@
const data = [null,null];
Promise.all([
import("./_app/immutable/entry/start.a461f483.js"),
import("./_app/immutable/entry/app.e1f5bfa5.js")
import("./_app/immutable/entry/start.d80b9438.js"),
import("./_app/immutable/entry/app.9b602d9d.js")
]).then(([kit, app]) => {
kit.start(app, element, {
node_ids: [0, 3],

Binary file not shown.

Binary file not shown.

View file

@ -9,14 +9,14 @@
<link href="./_app/immutable/assets/0.039b7214.css" rel="stylesheet">
<link href="./_app/immutable/assets/2.dfa854c9.css" rel="stylesheet">
<link href="./_app/immutable/assets/EditButton.0d24e5da.css" rel="stylesheet">
<link rel="modulepreload" href="./_app/immutable/entry/start.a461f483.js">
<link rel="modulepreload" href="./_app/immutable/entry/start.d80b9438.js">
<link rel="modulepreload" href="./_app/immutable/chunks/index.33dbc0d8.js">
<link rel="modulepreload" href="./_app/immutable/chunks/singletons.7472e3f8.js">
<link rel="modulepreload" href="./_app/immutable/entry/app.e1f5bfa5.js">
<link rel="modulepreload" href="./_app/immutable/chunks/singletons.8071cb2e.js">
<link rel="modulepreload" href="./_app/immutable/entry/app.9b602d9d.js">
<link rel="modulepreload" href="./_app/immutable/nodes/0.1654e388.js">
<link rel="modulepreload" href="./_app/immutable/nodes/2.5eb75e1b.js">
<link rel="modulepreload" href="./_app/immutable/chunks/EditButton.0d8ca4d9.js">
<link rel="modulepreload" href="./_app/immutable/chunks/stores.b56ccc8c.js"><title>iptv-org</title><!-- HEAD_svelte-bjnlvt_START --><script>if (document) {
<link rel="modulepreload" href="./_app/immutable/nodes/2.d7f1ad4d.js">
<link rel="modulepreload" href="./_app/immutable/chunks/EditButton.36510adc.js">
<link rel="modulepreload" href="./_app/immutable/chunks/stores.a09c62bd.js"><title>iptv-org</title><!-- HEAD_svelte-bjnlvt_START --><script>if (document) {
let mode = localStorage.theme || 'light'
if (mode === 'dark' || window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.classList.add('dark')
@ -69,7 +69,7 @@
<script>
{
__sveltekit_it7xqx = {
__sveltekit_fudz0b = {
base: new URL(".", location).pathname.slice(0, -1),
env: {}
};
@ -79,8 +79,8 @@
const data = [null,null];
Promise.all([
import("./_app/immutable/entry/start.a461f483.js"),
import("./_app/immutable/entry/app.e1f5bfa5.js")
import("./_app/immutable/entry/start.d80b9438.js"),
import("./_app/immutable/entry/app.9b602d9d.js")
]).then(([kit, app]) => {
kit.start(app, element, {
node_ids: [0, 2],

Binary file not shown.

Binary file not shown.

View file

@ -1,23 +1,23 @@
const s = /* @__PURE__ */ location.pathname.split("/").slice(0, -1).join("/"), h = [
s + "/_app/immutable/entry/app.e1f5bfa5.js",
s + "/_app/immutable/entry/app.9b602d9d.js",
s + "/_app/immutable/assets/0.039b7214.css",
s + "/_app/immutable/nodes/0.1654e388.js",
s + "/_app/immutable/nodes/1.15979b07.js",
s + "/_app/immutable/nodes/1.681ee3dc.js",
s + "/_app/immutable/assets/2.dfa854c9.css",
s + "/_app/immutable/nodes/2.5eb75e1b.js",
s + "/_app/immutable/nodes/3.dd846bcd.js",
s + "/_app/immutable/nodes/2.d7f1ad4d.js",
s + "/_app/immutable/nodes/3.5f07a693.js",
s + "/_app/immutable/assets/EditButton.0d24e5da.css",
s + "/_app/immutable/chunks/EditButton.0d8ca4d9.js",
s + "/_app/immutable/chunks/EditButton.36510adc.js",
s + "/_app/immutable/chunks/index.33dbc0d8.js",
s + "/_app/immutable/chunks/singletons.7472e3f8.js",
s + "/_app/immutable/chunks/stores.b56ccc8c.js",
s + "/_app/immutable/entry/start.a461f483.js"
], m = [
s + "/_app/immutable/chunks/singletons.8071cb2e.js",
s + "/_app/immutable/chunks/stores.a09c62bd.js",
s + "/_app/immutable/entry/start.d80b9438.js"
], d = [
s + "/.nojekyll",
s + "/favicon.png",
s + "/logo_512.png",
s + "/manifest.json"
], i = "1696552312143", l = `cache_${i}`, p = h.concat(m), d = new Set(p);
], i = "1696824804235", l = `cache_${i}`, p = h.concat(d), m = new Set(p);
self.addEventListener("install", (t) => {
t.waitUntil(
caches.open(l).then((e) => e.addAll(p)).then(() => {
@ -49,7 +49,7 @@ async function u(t) {
self.addEventListener("fetch", (t) => {
if (t.request.method !== "GET" || t.request.headers.has("range"))
return;
const e = new URL(t.request.url), a = e.protocol.startsWith("http"), c = e.hostname === self.location.hostname && e.port !== self.location.port, n = e.host === self.location.host, o = n && d.has(e.pathname), r = t.request.cache === "only-if-cached" && !o;
const e = new URL(t.request.url), a = e.protocol.startsWith("http"), c = e.hostname === self.location.hostname && e.port !== self.location.port, n = e.host === self.location.host, o = n && m.has(e.pathname), r = t.request.cache === "only-if-cached" && !o;
a && n && !c && !r && t.respondWith(
(async () => o && await caches.match(t.request) || u(t.request))()
);

Binary file not shown.

Binary file not shown.

1
src/data/blocklist.json Normal file

File diff suppressed because one or more lines are too long

1
src/data/categories.json Normal file
View file

@ -0,0 +1 @@
[{"id":"auto","name":"Auto"},{"id":"animation","name":"Animation"},{"id":"business","name":"Business"},{"id":"classic","name":"Classic"},{"id":"comedy","name":"Comedy"},{"id":"cooking","name":"Cooking"},{"id":"culture","name":"Culture"},{"id":"documentary","name":"Documentary"},{"id":"education","name":"Education"},{"id":"entertainment","name":"Entertainment"},{"id":"family","name":"Family"},{"id":"general","name":"General"},{"id":"kids","name":"Kids"},{"id":"legislative","name":"Legislative"},{"id":"lifestyle","name":"Lifestyle"},{"id":"movies","name":"Movies"},{"id":"music","name":"Music"},{"id":"news","name":"News"},{"id":"outdoor","name":"Outdoor"},{"id":"relax","name":"Relax"},{"id":"religious","name":"Religious"},{"id":"series","name":"Series"},{"id":"science","name":"Science"},{"id":"shop","name":"Shop"},{"id":"sports","name":"Sports"},{"id":"travel","name":"Travel"},{"id":"weather","name":"Weather"},{"id":"xxx","name":"XXX"}]

1
src/data/channels.json Normal file

File diff suppressed because one or more lines are too long

1
src/data/countries.json Normal file

File diff suppressed because one or more lines are too long

1
src/data/languages.json Normal file

File diff suppressed because one or more lines are too long

1
src/data/regions.json Normal file

File diff suppressed because one or more lines are too long

1
src/data/streams.json Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -2,6 +2,14 @@ import { writable, get } from 'svelte/store'
import { Playlist, Link } from 'iptv-playlist-generator'
import sj from '@freearhey/search-js'
import _ from 'lodash'
import api_channels from '~/data/channels.json'
import api_regions from '~/data/regions.json'
import api_countries from '~/data/countries.json'
import api_languages from '~/data/languages.json'
import api_streams from '~/data/streams.json'
import api_subdivisions from '~/data/subdivisions.json'
import api_blocklist from '~/data/blocklist.json'
import api_categories from '~/data/categories.json'
export const query = writable('')
export const hasQuery = writable(false)
@ -104,6 +112,30 @@ export function setPageTitle(value) {
async function loadAPI() {
const api = {}
api.countries = _.keyBy(
api_countries.map(i => {
i.expanded = false
return i
}),
'code'
)
api.regions = _.keyBy(api_regions, 'code')
api.subdivisions = _.keyBy(api_subdivisions, 'code')
api.languages = _.keyBy(api_languages, 'code')
api.categories = _.keyBy(api_categories, 'id')
api.streams = _.keyBy(api_streams, 'channel')
api.blocklist = _.keyBy(api_blocklist, 'channel')
api.guides = {}
api.channels = api_channels
return api
}
async function _loadAPI() {
const api = {}
api.countries = await fetch('https://iptv-org.github.io/api/countries.json')
.then(r => r.json())
.then(data => (data.length ? data : []))
@ -153,11 +185,6 @@ async function loadAPI() {
.catch(console.error)
api.guides = {}
// api.guides = await fetch('https://iptv-org.github.io/api/guides.json')
// .then(r => r.json())
// .then(data => (data.length ? data : []))
// .then(data => _.groupBy(data, 'channel'))
// .catch(console.error)
api.channels = await fetch('https://iptv-org.github.io/api/channels.json')
.then(r => r.json())
@ -169,18 +196,6 @@ async function loadAPI() {
return api
}
function getGuides() {
let guides = {}
get(selected).forEach(channel => {
let guide = channel._guides.length ? channel._guides[0] : null
if (guide && !guides[guide.url]) {
guides[guide.url] = guide.url
}
})
return Object.values(guides)
}
function getStreams() {
let streams = []
get(selected).forEach(channel => {
@ -212,9 +227,6 @@ function getStreams() {
export function createPlaylist() {
const playlist = new Playlist()
// let guides = getGuides()
// playlist.header = { 'x-tvg-url': guides.sort().join(',') }
let streams = getStreams()
streams.forEach(stream => {
const link = new Link(stream.url)