diff --git a/.gitignore b/.gitignore index 14fd2b8..1ce6283 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ toolchains/ /src/google.golang.org/ /toolchain/ /test/ +/server/web/pages/template/pages/msx diff --git a/build-all.sh b/build-all.sh index cdbf18d..bae13b4 100755 --- a/build-all.sh +++ b/build-all.sh @@ -83,20 +83,27 @@ done ### Android build section ##### -declare -A COMPILERS=( - ["arm7"]="armv7a-linux-androideabi21-clang" - ["arm64"]="aarch64-linux-android21-clang" - ["386"]="i686-linux-android21-clang" - ["amd64"]="x86_64-linux-android21-clang" +if [ -z "$NDK_TOOLCHAIN" ]; then + echo "NDK_TOOLCHAIN is not defined. Android builds was skipped" + exit +fi + +declare -a COMPILERS=( + "arm7:armv7a-linux-androideabi21-clang" + "arm64:aarch64-linux-android21-clang" + "386:i686-linux-android21-clang" + "amd64:x86_64-linux-android21-clang" ) export NDK_TOOLCHAIN=$ROOT/toolchain GOOS=android -for GOARCH in "${!COMPILERS[@]}"; do - export CC="$NDK_TOOLCHAIN/bin/${COMPILERS[$GOARCH]}" - export CXX="$NDK_TOOLCHAIN/bin/${COMPILERS[$GOARCH]}++" +for V in "${COMPILERS[@]}"; do + GOARCH=${V%:*} + COMPILER=${V#*:} + export CC="$NDK_TOOLCHAIN/bin/$COMPILER" + export CXX="$NDK_TOOLCHAIN/bin/$COMPILER++" set_goarm "$GOARCH" BIN_FILENAME="${OUTPUT}-${GOOS}-${GOARCH}${GOARM}" CMD="GOOS=${GOOS} GOARCH=${GOARCH} ${GO_ARM} CGO_ENABLED=1 ${GOBIN} build ${BUILD_FLAGS} -o ${BIN_FILENAME} ./cmd" diff --git a/gen_web.go b/gen_web.go index 76dc4f1..0338b07 100644 --- a/gen_web.go +++ b/gen_web.go @@ -34,7 +34,7 @@ func main() { filepath.WalkDir(srcGo+"template/pages/", func(path string, d fs.DirEntry, err error) error { if !d.IsDir() { name := strings.TrimPrefix(path, srcGo+"template/") - if !strings.HasPrefix(name, ".") { + if !strings.HasPrefix(filepath.Base(name), ".") { files = append(files, name) } } diff --git a/server/go.mod b/server/go.mod index bca1c92..04de445 100644 --- a/server/go.mod +++ b/server/go.mod @@ -2,7 +2,7 @@ module server go 1.17 -replace github.com/anacrolix/dms v1.2.2 => github.com/tsynik/dms v0.0.0-20210911171915-d3d89ee99163 +replace github.com/anacrolix/dms v1.3.0 => github.com/tsynik/dms v0.0.0-20210911171915-d3d89ee99163 exclude ( github.com/willf/bitset v1.2.0 @@ -11,7 +11,7 @@ exclude ( require ( github.com/alexflint/go-arg v1.4.2 - github.com/anacrolix/dms v1.2.2 + github.com/anacrolix/dms v1.3.0 github.com/anacrolix/missinggo v1.3.0 github.com/anacrolix/torrent v1.31.1-0.20210912041407-4691b0b8d194 github.com/gin-contrib/cors v1.3.1 diff --git a/server/torr/apihelper.go b/server/torr/apihelper.go index a190914..a2a58ca 100644 --- a/server/torr/apihelper.go +++ b/server/torr/apihelper.go @@ -193,12 +193,12 @@ func SetSettings(set *sets.BTSets) { if sets.ReadOnly { return } + sets.SetBTSets(set) log.TLogln("drop all torrents") dropAllTorrent() time.Sleep(time.Second * 2) log.TLogln("disconect") bts.Disconnect() - sets.SetBTSets(set) log.TLogln("connect") bts.Connect() time.Sleep(time.Second * 2) @@ -209,12 +209,12 @@ func SetDefSettings() { if sets.ReadOnly { return } + sets.SetDefault() log.TLogln("drop all torrents") dropAllTorrent() time.Sleep(time.Second * 2) log.TLogln("disconect") bts.Disconnect() - sets.SetDefault() log.TLogln("connect") bts.Connect() time.Sleep(time.Second * 2) diff --git a/server/web/msx/html.go b/server/web/msx/html.go new file mode 100644 index 0000000..394bbb6 --- /dev/null +++ b/server/web/msx/html.go @@ -0,0 +1,12 @@ +package msx + +import _ "embed" + +//go:embed pages/tizen.html +var Msxtizenhtml []byte + +//go:embed pages/tizen.js +var Msxtizenjs []byte + +//go:embed pages/tvx-plugin.min.js +var Msxtvxpluginminjs []byte diff --git a/server/web/msx/msx.go b/server/web/msx/msx.go index 3891d73..912f90a 100644 --- a/server/web/msx/msx.go +++ b/server/web/msx/msx.go @@ -16,11 +16,12 @@ import ( ) type msxMenu struct { - Logo string `json:"logo,omitempty"` - Reuse bool `json:"reuse"` - Cache bool `json:"cache"` - Restore bool `json:"restore"` - Menu []msxMenuItem `json:"menu"` + Logo string `json:"logo,omitempty"` + Reuse bool `json:"reuse"` + Cache bool `json:"cache"` + Restore bool `json:"restore"` + Reference string `json:"reference,omitempty"` + Menu []msxMenuItem `json:"menu"` } type msxMenuItem struct { @@ -29,13 +30,24 @@ type msxMenuItem struct { Data msxData `json:"data,omitempty"` } +type msxTemplate struct { + Type string `json:"type,omitempty"` + Layout string `json:"layout,omitempty"` + Color string `json:"color,omitempty"` + Icon string `json:"icon,omitempty"` + IconSize string `json:"iconSize,omitempty"` + BadgeColor string `json:"badgeColor,omitempty"` + TagColor string `json:"tagColor,omitempty"` + Properties gin.H `json:"properties,omitempty"` +} + type msxData struct { - Type string `json:"type,omitempty"` - Headline string `json:"headline,omitempty"` - Action string `json:"action,omitempty"` - Template gin.H `json:"template,omitempty"` - Items []msxItem `json:"items,omitempty"` - Pages []msxPage `json:"pages,omitempty"` + Type string `json:"type,omitempty"` + Headline string `json:"headline,omitempty"` + Action string `json:"action,omitempty"` + Template msxTemplate `json:"template,omitempty"` + Items []msxItem `json:"items,omitempty"` + Pages []msxPage `json:"pages,omitempty"` } type msxItem struct { @@ -47,6 +59,7 @@ type msxItem struct { Icon string `json:"icon,omitempty"` Badge string `json:"badge,omitempty"` Tag string `json:"tag,omitempty"` + Data gin.H `json:"data,omitempty"` } type msxPage struct { @@ -71,18 +84,20 @@ func msxTorrents(c *gin.Context) { for i, tor := range torrs { item := msxItem{ - Title: tor.Title, - Image: tor.Poster, - Action: "content:" + host + "/msx/playlist/" + url.PathEscape(tor.Title) + "?hash=" + tor.TorrentSpec.InfoHash.HexString(), + Title: tor.Title, + Image: tor.Poster, + Action: "content:" + host + "/msx/playlist/" + url.PathEscape(tor.Title) + + "?hash=" + tor.TorrentSpec.InfoHash.HexString() + "&platform={PLATFORM}", } list[i] = item } c.JSON(200, msxMenu{ - Logo: logo, - Cache: false, - Reuse: false, - Restore: false, + Logo: logo, + Cache: false, + Reuse: false, + Restore: false, + Reference: host + "/msx/torrents", Menu: []msxMenuItem{ // Main page { @@ -90,11 +105,11 @@ func msxTorrents(c *gin.Context) { Label: "Torrents", Data: msxData{ Type: "pages", - Template: gin.H{ - "type": "separate", - "layout": "0,0,2,4", - "icon": "msx-white-soft:movie", - "color": "msx-glass", + Template: msxTemplate{ + Type: "separate", + Layout: "0,0,2,4", + Icon: "msx-white-soft:movie", + Color: "msx-glass", }, Items: list, }, @@ -134,6 +149,7 @@ func msxPlaylist(c *gin.Context) { }) return } + platform, _ := c.GetQuery("platform") tor := torr.GetTorrent(hash) if tor == nil { @@ -166,11 +182,40 @@ func msxPlaylist(c *gin.Context) { continue } name := filepath.Base(f.Path) + uri := host + "/stream/" + url.PathEscape(name) + "?link=" + hash + "&index=" + fmt.Sprint(f.Id) + "&play" item := msxItem{ Label: name, PlayerLabel: strings.TrimSuffix(name, filepath.Ext(name)), - Action: action + ":" + host + "/stream/" + url.PathEscape(name) + "?link=" + hash + "&index=" + fmt.Sprint(f.Id) + "&play", + Action: action + ":" + uri, } + + if platform == "android" || platform == "firetv" { + item.Action = "system:tvx:launch" + item.Data = gin.H{ + "id": hash + "-" + fmt.Sprint(f.Id), + "uri": uri, + "type": mime, + } + } else if platform == "lg" { + // TODO - custom player needed + //item.Action = "system:lg:launch:com.webos.app.mediadiscovery" + //item.Data = gin.H{ + // "properties": gin.H{ + // "videoList": gin.H{ + // "result": [1]gin.H{ + // gin.H{ + // "url": uri, + // "thumbnail": tor.Poster, + // }, + // }, + // }, + // }, + //} + } else if platform == "ios" || platform == "mac" { + // TODO - for iOS and Mac the application must be defined in scheme but we don't know what user has installed + item.Action = "system:tvx:launch:vlc://" + uri + } + if isViewed(viewed, f.Id) { item.Tag = " " } @@ -190,18 +235,30 @@ func msxPlaylist(c *gin.Context) { res := msxData{ Headline: tor.Title, Type: "list", - Template: gin.H{ - "type": "control", - "layout": "0,2,12,1", - "color": "msx-glass", - "icon": "msx-white-soft:movie", - "iconSize": "medium", - "badgeColor": "msx-yellow", - "tagColor": "msx-yellow", + Template: msxTemplate{ + Type: "control", + Layout: "0,2,12,1", + Color: "msx-glass", + Icon: "msx-white-soft:movie", + IconSize: "medium", + BadgeColor: "msx-yellow", + TagColor: "msx-yellow", }, Items: list, } + if platform == "tizen" { + res.Template.Properties = gin.H{ + "button:content:icon": "tune", + "button:content:action": "content:request:interaction:init@" + host + "/msx/tizen.html", + } + } else if platform == "netcast" { + res.Template.Properties = gin.H{ + "button:content:icon": "tune", + "button:content:action": "system:netcast:menu", + } + } + // If only one item start to play immediately but it not works // if (len(list) == 1) { // res.Action = "execute:" + list[0].Action diff --git a/server/web/msx/pages/tizen.html b/server/web/msx/pages/tizen.html new file mode 100644 index 0000000..d4b31cc --- /dev/null +++ b/server/web/msx/pages/tizen.html @@ -0,0 +1,14 @@ + + + + Tizen Interaction Plugin + + + + + + + + + + \ No newline at end of file diff --git a/server/web/msx/pages/tizen.js b/server/web/msx/pages/tizen.js new file mode 100644 index 0000000..306b752 --- /dev/null +++ b/server/web/msx/pages/tizen.js @@ -0,0 +1,365 @@ +/******************************************************************************/ +//Tizen Interaction Plugin v0.0.1 +//(c) 2021 Benjamin Zachey +//Action syntax example: +//- "content:request:interaction:init@http://msx.benzac.de/interaction/tizen.html" +/******************************************************************************/ + +/******************************************************************************/ +//TizenPlayer +/******************************************************************************/ +function TizenPlayer() { + var pushToArray = function(array, items) { + if (array != null && items != null) { + if (Array.isArray(items)) { + for (var i = 0; i < items.length; i++) { + array.push(items[i]); + } + } else { + array.push(items); + } + } + }; + var getValueLabel = function(value) { + if (typeof value == "string") { + return TVXTools.strFullCheck(value, "-"); + } + return value != null ? TVXTools.strValue(value) : "-"; + }; + var getPropertyLabel = function(value, unit) { + if (TVXTools.isFullStr(value) && value.indexOf("|") >= 0) { + return value.split("|")[0]; + } + if (value != null) { + if (unit != null) { + return value + " " + unit; + } + return TVXTools.strValue(value); + } + return "Unknown"; + }; + var getPropertyValue = function(value) { + if (TVXTools.isFullStr(value) && value.indexOf("|") >= 0) { + value = value.split("|")[1]; + } + if (TVXTools.isFullStr(value) && value.indexOf("num:") == 0) { + return TVXTools.strToNum(value.substr(4)); + } + return value; + }; + var getTrackLabel = function(track) { + if (track != null) { + var prefix = "Track " + track.index; + var suffix = track.info != null ? track.info.language : null;//Audio track + if (suffix == null) { + suffix = track.info != null ? track.info.track_lang : null;//Text track + } + return TVXTools.isFullStr(suffix) ? prefix + " (" + suffix + ")" : prefix; + } + return "None"; + }; + var createPropertyControls = function(y, propertyIcon, propertyLabel, propertyKey, propertyValue, propertyUnit, availableValues, nextButton) { + var panelItems = []; + var selectedPropertyLabel = getPropertyLabel(propertyValue, propertyUnit); + var firstPropertyValue = null; + var nextPropertyValue = null; + var selectNext = false; + if (availableValues != null) { + for (var i = 0; i < availableValues.length; i++) { + var value = getPropertyValue(availableValues[i]); + var label = getPropertyLabel(availableValues[i], propertyUnit); + var selected = value === propertyValue; + if (firstPropertyValue == null) { + firstPropertyValue = value; + } + if (selected) { + selectNext = true; + selectedPropertyLabel = label; + } else if (selectNext) { + selectNext = false; + nextPropertyValue = value; + } + panelItems.push({ + focus: selected, + extensionIcon: selected ? "check" : "blank", + label: label, + action: selected ? "back" : "[invalidate:content|back|player:commit]", + data: { + key: propertyKey, + value: value, + action: "reload:content" + } + }); + } + } + if (nextPropertyValue == null) { + nextPropertyValue = firstPropertyValue; + } + return [{ + enable: panelItems.length > 0, + type: "control", + layout: "0," + y + "," + (nextButton ? "7,1" : "8,1"), + icon: propertyIcon, + label: propertyLabel, + extensionLabel: selectedPropertyLabel, + action: "panel:data", + data: { + headline: propertyLabel, + compress: panelItems.length > 6, + template: { + type: "control", + enumerate: false, + layout: panelItems.length > 8 ? "0,0,5,1" : panelItems.length > 6 ? "0,0,10,1" : "0,0,8,1" + }, + items: panelItems + } + }, { + display: nextButton, + enable: nextPropertyValue != null, + type: "button", + icon: "navigate-next", + iconSize: "small", + layout: "7," + y + ",1,1", + action: "[invalidate:content|player:commit]", + data: { + key: propertyKey, + value: nextPropertyValue, + action: "reload:content" + } + }]; + }; + var createTrackControl = function(y, propertyIcon, propertyLabel, propertyKey, currentTrack, availableTracks) { + var panelItems = []; + if (availableTracks != null) { + for (var i = 0; i < availableTracks.length; i++) { + var track = availableTracks[i]; + var selected = track.index === (currentTrack != null ? currentTrack.index : -1); + panelItems.push({ + focus: selected, + extensionIcon: selected ? "check" : "blank", + label: getTrackLabel(track), + action: selected ? "back" : "[invalidate:content|back|player:commit]", + data: { + key: propertyKey, + value: track.index, + action: "reload:content" + } + }); + } + } + return { + enable: panelItems.length > 0, + type: "control", + layout: "0," + y + ",8,1", + icon: propertyIcon, + label: propertyLabel, + extensionLabel: getTrackLabel(currentTrack), + action: "panel:data", + data: { + headline: propertyLabel, + compress: panelItems.length > 6, + template: { + type: "control", + enumerate: false, + layout: panelItems.length > 8 ? "0,0,5,1" : panelItems.length > 6 ? "0,0,10,1" : "0,0,8,1" + }, + items: panelItems + } + }; + }; + var createControlItems = function(infoData) { + var items = []; + pushToArray(items, createPropertyControls(0, "featured-video", "Display Area", "tizen:display:area", + infoData && infoData.display != null ? infoData.display.area : null, null, [ + "21x9|0,0.119,1,0.762", + "16x9 (Default)|0,0,1,1", + "4x3|0.125,0,0.75,1" + ], true)); + pushToArray(items, createPropertyControls(1, "aspect-ratio", "Display Mode", "tizen:display:mode", + infoData != null && infoData.display != null ? infoData.display.mode : null, null, [ + "Fit Screen (Default)|PLAYER_DISPLAY_MODE_LETTER_BOX", + "Fill Screen|PLAYER_DISPLAY_MODE_FULL_SCREEN", + "Auto Aspect Ratio|PLAYER_DISPLAY_MODE_AUTO_ASPECT_RATIO" + ], true)); + pushToArray(items, createPropertyControls(2, "av-timer", "Buffer Timeout", "tizen:buffer:timeout", + infoData != null && infoData.buffer != null ? infoData.buffer.timeout : null, "sec", [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, "20 sec (Default)|num:20", 25, 30, 40 + ], false)); + pushToArray(items, createPropertyControls(3, "timelapse", "Buffer Size (Init)", "tizen:buffer:size:init", + infoData != null && infoData.buffer != null && infoData.buffer.size != null ? infoData.buffer.size.init : null, "sec", null, false)); + pushToArray(items, createPropertyControls(4, "timelapse", "Buffer Size (Resume)", "tizen:buffer:size:resume", + infoData != null && infoData.buffer != null && infoData.buffer.size != null ? infoData.buffer.size.resume : null, "sec", null, false)); + pushToArray(items, createTrackControl(5, "audiotrack", "Audio Track", "tizen:track:audio", + infoData != null && infoData.stream != null ? infoData.stream.audio : null, + infoData != null && infoData.tracks != null ? infoData.tracks.audio : null)); + pushToArray(items, createTrackControl(6, "subtitles", "Text Track", "tizen:track:text", + infoData != null && infoData.stream != null ? infoData.stream.text : null, + infoData != null && infoData.tracks != null ? infoData.tracks.text : null)); + return items; + }; + var createInfoItems = function(infoData) { + var infoKeys = "-"; + var infoValues = "-"; + if (infoData != null) { + infoKeys = "Version:{br}State:{br}{br}"; + infoValues = getValueLabel(infoData.version) + "{br}" + + getValueLabel(infoData.state) + "{br}{br}"; + if (infoData.stream != null) { + if (infoData.stream.video != null && infoData.stream.video.info != null) { + for (var key in infoData.stream.video.info) { + infoKeys += "Video [" + key + "]:{br}"; + infoValues += getValueLabel(infoData.stream.video.info[key]) + "{br}"; + } + infoKeys += "{br}"; + infoValues += "{br}"; + } + if (infoData.stream.audio != null && infoData.stream.audio.info != null) { + for (var key in infoData.stream.audio.info) { + infoKeys += "Audio [" + key + "]:{br}"; + infoValues += getValueLabel(infoData.stream.audio.info[key]) + "{br}"; + } + infoKeys += "{br}"; + infoValues += "{br}"; + } + if (infoData.stream.text != null && infoData.stream.text.info != null) { + for (var key in infoData.stream.text.info) { + infoKeys += "Text [" + key + "]:{br}"; + infoValues += getValueLabel(infoData.stream.text.info[key]) + "{br}"; + } + } + } + } + return [{ + type: "space", + layout: "8,0,3,8", + offset: "0.25,0,0,0", + truncation: "text", + text: infoKeys + }, { + type: "space", + layout: "11,0,5,8", + offset: "0.25,0,-0.25,0", + truncation: "text", + text: "{col:msx-white}" + infoValues, + live: { + type: "airtime", + duration: 2000, + over: { + action: "reload:content" + } + } + }]; + }; + var createContentItems = function(infoData) { + var items = []; + pushToArray(items, createControlItems(infoData)); + pushToArray(items, createInfoItems(infoData)); + return items; + }; + var createContent = function(infoData) { + return { + cache: false, + compress: true, + type: "pages", + headline: "Tizen Player", + extension: "{ico:msx-white:timer} " + TVXDateTools.getTimestamp(), + pages: [{ + items: createContentItems(infoData) + }] + }; + }; + var createWarningContent = function(playerInfo) { + return { + type: "pages", + headline: "Tizen Player", + pages: [{ + items: [{ + type: "default", + layout: "0,0,12,6", + color: "msx-glass", + headline: "{ico:msx-yellow:warning} Player Not Available", + text: "Tizen player is required for this plugin. Current player is: {txt:msx-white:" + playerInfo + "}." + }] + }] + }; + }; + var createDummyData = function() { + return { + version: "1.0", + state: "PLAYING", + display: { + area: "0,0,1,1", + mode: "PLAYER_DISPLAY_MODE_LETTER_BOX" + }, + buffer: { + timeout: 20, + size: { + init: 10, + resume: 10 + } + }, + stream: { + video: { + index: 0, + info: { + fourCC: "h264", + Width: 1280, + Height: 720, + Bit_rate: 128000 + } + } + } + }; + }; + this.handleRequest = function(playerInfo, dataId, callback) { + if (dataId == "init") { + if (TVXTools.isFullStr(playerInfo) && (playerInfo == "tizen" || playerInfo.indexOf("tizen/") == 0)) { + TVXInteractionPlugin.requestPlayerResponse("tizen:info", function(data) { + callback(createContent(data.response != null && data.response.tizen != null ? data.response.tizen.info : null)); + }); + } else { + callback(createWarningContent(playerInfo)); + } + return true; + } else if (dataId == "dummy") { + callback(createContent(createDummyData())); + return true; + } + return false; + }; +} +/******************************************************************************/ + +/******************************************************************************/ +//TizenHandler +/******************************************************************************/ +function TizenHandler() { + var playerInfo = null; + var readyService = new TVXBusyService(); + var player = new TizenPlayer(); + + this.ready = function() { + readyService.start(); + TVXInteractionPlugin.requestData("info:base", function(data) { + playerInfo = TVXTools.strFullCheck(data.info != null ? data.info.player : null, "unknown"); + readyService.stop(); + }); + }; + this.handleRequest = function(dataId, data, callback) { + readyService.onReady(function() { + if (!player.handleRequest(playerInfo, dataId, callback)) { + callback(); + } + }); + }; +} +/******************************************************************************/ + +/******************************************************************************/ +//Setup +/******************************************************************************/ +window.onload = function() { + TVXInteractionPlugin.setupHandler(new TizenHandler()); + TVXInteractionPlugin.init(); +}; +/******************************************************************************/ \ No newline at end of file diff --git a/server/web/msx/pages/tvx-plugin.min.js b/server/web/msx/pages/tvx-plugin.min.js new file mode 100644 index 0000000..a500a03 --- /dev/null +++ b/server/web/msx/pages/tvx-plugin.min.js @@ -0,0 +1,88 @@ +/* + * TVX Plugin v0.0.54 + * (c) 2021 Benjamin Zachey + */ +(function(e,m){var k={NAME:"TVX Framework",SHORTCUT:"TVX",VERSION:"0.1.26",SUFFIX:null,DUMMY_DATE:null,TIME_OFFSET:0,TIME_ZONE_OFFSET:0,ANIMATION_DURATION:300,ANIMATION_EASE:"easeOutQuad",AFK_DELAY:8000,SCREEN_WIDTH:1280,SCREEN_HEIGHT:720,SCREEN_FACTOR:1,ZOOM_FACTOR:1,PLATFORM:null,ANIMATE:0,TRANSFORM:0,INPUT:0,REMOTE:0,LAYOUT:null,SCALE:null,ZOOM:null,CENTER:0,BACKGROUND:0,LEAVE:0,EXIT:0,BACK:0,VOLUME:0,BUSY:0,SPEED:0,PLAYBACK:0,FULLSCREEN:0,SUSPEND:0,SECURE:0,APP:null};var l={COMMON:{IMAGE:{DEFAULT:"img/default.png"},ICON:{DEFAULT:"blank"},TEXT:{DEFAULT:""},COLOR:{WHITE:"rgb(255,255,255)",WHITE_SOFT:"rgba(255,255,255,0.5)",BLACK:"rgb(0,0,0)",BLACK_SOFT:"rgba(0,0,0,0.5)",GRAY:"rgb(51,51,51)",GRAY_SOFT:"rgba(51,51,51,0.5)",RED:"rgb(201,48,44)",GREEN:"rgb(68,157,68)",YELLOW:"rgb(236,151,31)",BLUE:"rgb(49,176,213)",GLASS:"rgba(255,255,255,0.1)"},CSS:{CLASS_SELECTED:"selected",CLASS_TRIGGER:"trigger",CLASS_FOCUSED:"focused",CLASS_DISABLED:"disabled",CLASS_INVALIDATED:"invalidated",CLASS_HOVER:"hover",CLASS_ROOT:"tvx-root",CLASS_TOP_LAYER:"tvx-top-layer",CLASS_BOTTOM_LAYER:"tvx-bottom-layer",CLASS_FULLSCREEN:"tvx-fullscreen",CLASS_VIDEO:"tvx-video",CLASS_VIDEO_ON:"tvx-video-on",CLASS_CENTER_OFF:"tvx-center-off",CLASS_BACKGROUND_OFF:"tvx-background-off",CLASS_CLICK_THROUGH:"tvx-click-through",CLASS_CURSOR_OFF:"tvx-cursor-off",CLASS_FILLER:"tvx-filler",CLASS_FILLER_WIDTH_TOP:"tvx-filler-width-top",CLASS_FILLER_WIDTH_BOTTOM:"tvx-filler-width-bottom",CLASS_FILLER_WIDTH_CENTER:"tvx-filler-width-center",CLASS_FILLER_HEIGHT_LEFT:"tvx-filler-height-left",CLASS_FILLER_HEIGHT_RIGHT:"tvx-filler-height-right",CLASS_FILLER_HEIGHT_CENTER:"tvx-filler-height-center",CLASS_FILLER_FIT:"tvx-filler-fit",CLASS_FILLER_COVER:"tvx-filler-cover",CLASS_FILLER_SMART:"tvx-filler-smart",CLASS_ICON:"tvx-icon tvx-icon-{ICON}",CLASS_ICON_INLINE:"tvx-icon-inline tvx-icon-{ICON}",CLASS_TEXT:"tvx-text",CLASS_TEXT_INLINE:"tvx-text-inline"},HTML:{BREAK:"
",SPACE:" ",TAB:"   ",CANVAS:"",IFRAME:"",ICON:"",ICON_STYLED:"",TEXT:"{TEXT}",TEXT_STYLED:"{TEXT}",TEXT_START:"",TEXT_START_STYLED:"",TEXT_END:""}},LOGGER:{CSS:{CLASS_DEBUG:"tvx-debug",CLASS_INFO:"tvx-info",CLASS_WARN:"tvx-warn",CLASS_ERROR:"tvx-error"},HTML:{LINE:"{MESSAGE}"}},RENDERER:{CSS:{CLASS_TRANSFORM:"tvx-transform",CLASS_TRANSFORM_ZERO:"tvx-transform-zero",CLASS_TRANSFORM_3D:"tvx-transform-3d",CLASS_TRANSFORM_3D_ZERO:"tvx-transform-3d-zero"},STATE:{SHOW:{visible:true},HIDE:{visible:false},FADE_IN_FROM:{opacity:0},FADE_IN_TO:{opacity:1,visible:true},FADE_OUT_FROM:{opacity:1},FADE_OUT_TO:{opacity:0,visible:false}}},REMOTE:{CSS:{CLASS_BUTTON:"tvx-button",CLASS_SUBCONTROL_LEFT:"tvx-subcontrol-left",CLASS_SUBCONTROL_RIGHT:"tvx-subcontrol-right"}},APP:null}; +var a=new function(){var Q=/\\/g;var ad=/"/g;var S=/'/g;var ax=/\n/g;var av=/\r/g;var O=/\r\n/g;var at=/\t/g;var X=/\s/g;var aa=/-/g;var ab=/^[A-Za-z0-9._-]+$/;var al=/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/;var ar=/"(\\.|[^"\\])*"/g;var au=/^\s+|\s+$/g;var ae=/\s{0,}>\s{0,}/g;var ag=/\s{0,}\/>/g;var af=/\s{0,}<\s{0,}/g;var ai=ax;var ah=av;var ak=/\s{2,}/g;var K=/&/g;var W=ad;var P=S;var ac=//g;var ao=/"/g;var an=/'/g;var am=/</g;var aq=/>/g;var ap=/&/g;var L=/\+/g;var N=/\//g;var M=/=/g;var R=/[^A-Za-z0-9\+\/\=]/g;var T=aa;var aj=/_/g;var ay=/,/g;var Y=/\./g;var V="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";var Z=e.location.protocol==="https:";var aw=function(az,aB){if(az&&aB){var aA=e.location.pathname;aA=aA.substring(0,aA.lastIndexOf("/"));return e.location.protocol+"//"+e.location.host+aA}else{if(az){return e.location.protocol+"//"+e.location.host}}return e.location.protocol+"//"};this.createVersion=function(aB){if(this.isFullStr(aB)){var aD=aB.split("."); +if(aD.length==3){var aA=this.strToNum(aD[0],-1);var az=this.strToNum(aD[1],-1);var aC=this.strToNum(aD[2],-1);if(aA>=0&&az>=0&&aC>=0){return{major:aA,minor:az,patch:aC}}}}return null};this.checkVersion=function(aC,aB){var aA=this.createVersion(aB);if(aA!=null){var az=this.createVersion(aC);if(az!=null){if(az.major==aA.major){if(az.minor==aA.minor){return az.patch>=aA.patch}return az.minor>aA.minor}return az.major>aA.major}return false}return true};this.createKey=function(aD,aB){if(aD==null){aD=4}if(aB==null){aB=10}var aA="";for(var aC=0;aC=0&&az<=9){aA+=""+az}if(az>=10&&az<=35){aA+=String.fromCharCode(az+55)}if(az>=36&&az<=61){aA+=String.fromCharCode(az+61)}}return aA};this.isFullStr=function(az){return az!=null&&typeof az=="string"&&az.length>0 +};this.isBool=function(az){if(az!=null&&typeof az=="boolean"){return true}return this.isFullStr(az)};this.isNum=function(az){if(az!=null&&typeof az=="number"){return true}return this.isFullStr(az)&&isFinite(az)};this.isArray=function(az){if(az!=null){return Array.isArray(az)}return false};this.isEmpty=function(aA){if(aA!=null){if(typeof aA=="string"){return aA.length==0}var az;for(az in aA){return false}}return true};this.isValid=function(aA,az){if(aA!=null){if(az===true){if(typeof aA=="string"){return aA.length>0}}return true}return false};this.isId=function(az){return this.isFullStr(az)&&ab.test(az)};this.isJson=function(az){return this.isFullStr(az)&&!al.test(az.replace(ar,""))};this.isHttpUrl=function(az){return this.isFullStr(az)&&(az.indexOf("http://")==0||az.indexOf("https://")==0)};this.strValue=function(az){if(az!=null){if(typeof az=="string"){return az}else{return""+az}}return null};this.strFullCheck=function(aA,az){return this.isFullStr(aA)?aA:az};this.strTrim=function(az){return this.isFullStr(az)?az.replace(au,""):"" +};this.strClear=function(az){return this.isFullStr(az)?az.replace(X,""):""};this.strTruncate=function(az,aA){return this.isFullStr(az)&&aA>0&&az.length>aA?az.substr(0,aA)+"...":az};this.strShuffle=function(az){return this.isFullStr(az)?az.split("").sort(function(){return 0.5-Math.random()}).join(""):""};this.strReplace=function(aA,aB,az){if(this.isFullStr(aA)&&this.isFullStr(aB)){return aA.replace(aB,function(){return az!=null?az:""})}return aA};this.strReplaceMap=function(aA,aB){if(this.isFullStr(aA)&&aB!=null){for(var az in aB){aA=this.strReplace(aA,az,aB[az])}}return aA};this.strToBool=function(aA,az){if(aA!=null&&typeof aA=="boolean"){return aA}return this.isFullStr(aA)?aA=="true":az};this.strToNum=function(aA,az){if(aA!=null&&typeof aA=="number"){return aA}return this.isFullStr(aA)&&isFinite(aA)?aA*1:az};this.strToAction=function(az){return this.isFullStr(az)?az.toUpperCase().replace(aa,"_"):""};this.strToJsonStr=function(az){return this.isFullStr(az)?az.replace(ad,'\\"'):""};this.strToUrlStr=function(az){return this.isFullStr(az)?encodeURIComponent(az):"" +};this.strContainsToken=function(aB,aC,az,aD){if(this.isFullStr(aB)&&this.isFullStr(aC)){var aA=aB.indexOf(aC);if(az==null){az=0}if(aD==null){aD=aB.length}return aA>=az&&aA=0){aB=aA}while(aB>=0&&aB=0){aB+=aD.length;if(aE==null||aB").replace(ag,"/>").replace(af,"<").replace(ai," ").replace(ah," ").replace(ak," ")):""};this.htmlEscape=function(az){return this.isFullStr(az)?az.replace(K,"&").replace(W,""").replace(P,"'").replace(ac,"<").replace(U,">"):""};this.htmlUnescape=function(az){return this.isFullStr(az)?az.replace(ao,'"').replace(an,"'").replace(am,"<").replace(aq,">").replace(ap,"&"):""};this.htmlAttrEscape=function(az){return this.isFullStr(az)?az.replace(W,""").replace(P,"'"):"" +};this.htmlAttrUnescape=function(az){return this.isFullStr(az)?az.replace(ao,'"').replace(an,"'"):""};this.htmlTextEscape=function(az){return this.isFullStr(az)?this.htmlEscape(az).replace(ax,l.COMMON.HTML.BREAK).replace(at,l.COMMON.HTML.TAB):""};this.base64Encode=function(aH){var aC="";if(this.isFullStr(aH)){var aI,aD,aF;var aB,aG,aA,aE;var az=0;aH=this.utf8Encode(aH);while(az>2;aG=((aI&3)<<4)|(aD>>4);aA=((aD&15)<<2)|(aF>>6);aE=aF&63;if(isNaN(aD)){aA=aE=64}else{if(isNaN(aF)){aE=64}}aC+=V.charAt(aB)+V.charAt(aG)+V.charAt(aA)+V.charAt(aE)}}return aC};this.base64EncodeUrl=function(az){return this.isFullStr(az)?this.base64Encode(az).replace(L,"-").replace(N,"_").replace(M,","):""};this.base64EncodeId=function(az){return this.isFullStr(az)?this.base64Encode(az).replace(L,"-").replace(N,"_").replace(M,"."):""};this.base64Decode=function(aH){var aC="";if(this.isFullStr(aH)){var aI,aD,aF;var aB,aG,aA,aE;var az=0; +aH=aH.replace(R,"");while(az>4);aD=((aG&15)<<4)|(aA>>2);aF=((aA&3)<<6)|aE;aC+=String.fromCharCode(aI);if(aA!=64){aC+=String.fromCharCode(aD)}if(aE!=64){aC+=String.fromCharCode(aF)}}}return this.utf8Decode(aC)};this.base64DecodeUrl=function(az){return this.isFullStr(az)?this.base64Decode(az.replace(T,"+").replace(aj,"/").replace(ay,"=")):""};this.base64DecodeId=function(az){return this.isFullStr(az)?this.base64Decode(az.replace(T,"+").replace(aj,"/").replace(Y,"=")):""};this.utf8Encode=function(aC){var aA="";if(this.isFullStr(aC)){aC=aC.replace(O,"\n");for(var az=0;az127)&&(aB<2048)){aA+=String.fromCharCode((aB>>6)|192);aA+=String.fromCharCode((aB&63)|128)}else{aA+=String.fromCharCode((aB>>12)|224);aA+=String.fromCharCode(((aB>>6)&63)|128);aA+=String.fromCharCode((aB&63)|128) +}}}}return aA};this.utf8Decode=function(aD){var aA="";if(this.isFullStr(aD)){var aE=0;var aB,aC,aF,az;aB=aC=aF=az=0;while(aE191)&&(aB<224)){aF=aD.charCodeAt(aE+1);aA+=String.fromCharCode(((aB&31)<<6)|(aF&63));aE+=2}else{aF=aD.charCodeAt(aE+1);az=aD.charCodeAt(aE+2);aA+=String.fromCharCode(((aB&15)<<12)|((aF&63)<<6)|(az&63));aE+=3}}}}return aA};this.createHash=function(aB,aA){var az=0;if(this.isFullStr(aB)){if(aA===true){for(var aC=aB.length;aC>=0;aC--){az=((az<<5)-az)+aB.charCodeAt(aC);az&=az}}else{for(var aC=0;aC0){aE+=","}aE+=aA;aC++}}aE+="]"}else{if(aB=="object"){aE="{"; +var aC=0;for(var aF in az){var aA=this.serialize(az[aF],aF);if(aA!=null){if(aC>0){aE+=","}aE+=aA;aC++}}aE+="}"}else{if(aB=="string"){aE='"'+az.replace(Q,"\\\\").replace(ad,'\\"').replace(ax,"\\n")+'"'}else{if(aB=="number"||aB=="boolean"){aE=""+az}}}}if(aE!=null){if(aD!=null){return'"'+aD+'":'+aE}else{return aE}}return null};this.deserialize=function(az){try{if(e.JSON!=null&&typeof JSON.parse=="function"){return this.isFullStr(az)?JSON.parse(az):null}else{return this.isJson(az)?new Function("return "+az)():null}}catch(aA){return null}};this.isSecureContext=function(){return Z};this.secureUrl=function(az){return this.isFullStr(az)?az.replace("http://","https://"):az};this.getPrefixUrl=function(az){return aw(false,false)+this.strFullCheck(az,"")};this.getHostUrl=function(az){return aw(true,false)+"/"+this.strFullCheck(az,"")};this.getPathUrl=function(az){return aw(true,true)+"/"+this.strFullCheck(az,"")};this.getAbsoluteUrl=function(az){if(this.isFullStr(az)&&!this.isHttpUrl(az)){if(az.indexOf("/")==0){return aw(true,false)+az +}else{return aw(true,true)+"/"+az}}return az};this.getRootPath=function(az,aD){if(this.isFullStr(az)){var aC=e.location.pathname;var aB=aC.indexOf(az);if(aB>0){var aA=aC.substr(0,aB);if(aD===true){if(aA.indexOf("/")==0){aA=aA.substr(1)}if(aA.lastIndexOf("/")==aA.length-1){aA=aA.substr(0,aA.length-1)}}else{if(aA.indexOf("/")!=0){aA="/"+aA}if(aA.lastIndexOf("/")!=aA.length-1){aA+="/"}}return aA}}return aD===true?"":"/"};this.exprEscape=function(aG,aF,aL,aM,aH,aK,aC){if(this.isFullStr(aG)&&typeof aM=="function"){if(this.isFullStr(aF)&&this.isFullStr(aL)&&typeof aH=="function"){if(aG.indexOf(aF)>=0&&aG.indexOf(aL)>=0){var az="";var aA=aF.length;var aE=aL.length;var aI=aG.length;var aJ=0;var aD=0;var aB=0;while(aD>=0){aD=aG.indexOf(aF,aJ);if(aD>=0){aB=aG.indexOf(aL,aD);if(aB>0){if(aJ=0&&ao<0){return ax.replace("DD",T[aj])}else{if(ah>=0&&ao<0){return ax.replace("D",ac[aj]) +}else{if(ag>=0&&ah<0){return ax.replace("MM",W[ak])}else{if(ao>=0&&ah<0){return ax.replace("M",ab[ak])}else{if(ah>=0&&ao>=0){var al=null;var av=null;var an=null;if(ap>=0){al=ax.substring(0,ap);av=T[aj];an=ax.substring(ap+2,ax.length)}else{if(ah>=0){al=ax.substring(0,ah);av=ac[aj];an=ax.substring(ah+1,ax.length)}}if(ah>ao){if(al.indexOf("MM")>=0){al=al.replace("MM",W[ak])}else{if(al.indexOf("M")>=0){al=al.replace("M",ab[ak])}}}else{if(an.indexOf("MM")>=0){an=an.replace("MM",W[ak])}else{if(an.indexOf("M")>=0){an=an.replace("M",ab[ak])}}}return al+av+an}}}}}return ax};this.getDayStr=function(ah,ag,af,ai){return this.getFormattedDateStr(ah,V,ag,af,ai)};this.getDayLongStr=function(ah,ag,af,ai){return this.getFormattedDateStr(ah,L,ag,af,ai)};this.getDayFullStr=function(ah,ag,af,ai){return this.getFormattedDateStr(ah,R,ag,af,ai)};this.getDateStr=function(ah,ag,af,ai){return this.getFormattedDateStr(ah,K,ag,af,ai)};this.getDateLongStr=function(ah,ag,af,ai){return this.getFormattedDateStr(ah,N,ag,af,ai) +};this.getFormattedTimeStr=function(ah,an,ao,ai,aj){var am=0;var ak=0;var af=0;if(ah==null){am=ao!=null?ao*1:0;ak=ai!=null?ai*1:0;af=aj!=null?aj*1:0}else{if(typeof ah=="number"){ah=new Date(ah)}am=ah.getHours();ak=ah.getMinutes();af=ah.getSeconds()}var al=null;var ag=an.indexOf("/ampm");if(ag>0){an=an.substr(0,ag);al=X;if(am>12){al=ad;am-=12}}return an.replace("hh",(am<10?"0":"")+am).replace("mm",(ak<10?"0":"")+ak).replace("ss",(af<10?"0":"")+af).replace("h",am).replace("m",ak).replace("s",af)+(al!=null?al:"")};this.getTimeStr=function(ah,ai,af,ag){return this.getFormattedTimeStr(ah,P,ai,af,ag)};this.getTimeLongStr=function(ah,ai,af,ag){return this.getFormattedTimeStr(ah,U,ai,af,ag)};this.getRecordingStr=function(af){if(typeof af=="number"){af=new Date(af)}return this.getDayLongStr(af)+M+this.getTimeStr(af)};this.getFormattedDurationStr=function(ag,aj){var af=Math.floor(ag/3600000);var ai=Math.floor((ag%3600000)/60000);var ah=Math.floor((ag%60000)/1000);aj=a.exprEscape(aj,"[","]",function(ak){return ak +},function(ak){if(ak.indexOf("h")==0||ak.indexOf("H")==0){return af>0?ak:""}else{if(ak.indexOf("m")==0||ak.indexOf("M")==0){return af>0||ai>0?ak:""}else{if(ak.indexOf("s")==0||ak.indexOf("S")==0){return af>0||ai>0||ah>0?ak:""}}}});return aj.replace("H","h").replace("M",(af>0?"mm":"m")).replace("S",(af>0||ai>0?"ss":"s")).replace("hh",(af<10?"0":"")+af).replace("mm",((ai<10)?"0":"")+ai).replace("ss",((ah<10)?"0":"")+ah).replace("h",af).replace("m",ai).replace("s",ah)};this.getDurationStr=function(ak,aw){if(aw==null){aw="dhms"}var av=aw.indexOf("D")!=-1;var an=aw.indexOf("H")!=-1;var ar=aw.indexOf("M")!=-1;var au=aw.indexOf("S")!=-1;aw=aw.toLowerCase();var aq=aw.indexOf("d")!=-1;var ai=aw.indexOf("h")!=-1;var af=aw.indexOf("m")!=-1;var ah=aw.indexOf("s")!=-1;if(aw.indexOf("~")==0){if(ak<60000){if(ah){aw="s"}}else{if(ak<3600000){if(af){aw="m"}else{if(ah){aw="s"}}}else{if(ak<86400000){if(ai){aw="h"}else{if(af){aw="m"}else{if(ah){aw="s"}}}}else{if(aq){aw="d"}else{if(ai){aw="h"}else{if(af){aw="m" +}else{if(ah){aw="s"}}}}}}}}if(aw=="d"){var ao=Math.round(ak/86400000);return ao==1?ao+Z:ao+Y}if(aw=="h"){return Math.round(ak/3600000)+S}if(aw=="m"){return Math.round(ak/60000)+Q}if(aw=="s"){return Math.round(ak/1000)+O}var aj=ak;var at=ai||af||ah;var ao=aq?(at?Math.floor(aj/86400000):Math.ceil(aj/86400000)):0;if(aq){aj=ak%86400000}at=af||ah;var ap=ai?(at?Math.floor(aj/3600000):Math.ceil(aj/3600000)):0;if(ai){aj=ak%3600000}at=ah;var al=af?(at?Math.floor(aj/60000):Math.ceil(aj/60000)):0;if(af){aj=ak%60000}var ag=ah?Math.floor(aj/1000):0;var am="";if(aq&&(ao>0||av)){am+=ao+(ao==1?Z:Y)}if(ai&&(ap>0||an)){if(am.length>0){am+=" "}am+=ap+S}if(af&&(al>0||ar)){if(am.length>0){am+=" "}am+=al+Q}if(ah&&(ag>0||au)){if(am.length>0){am+=" "}am+=ag+O}if(ah&&am.length==0){return ag+O}if(af&&am.length==0){return al+Q}if(ai&&am.length==0){return ap+S}return am};this.getVideoStr=function(ah,ai){if(ai==null){ai=3}var ag=ai>2?Math.floor(ah/3600000):0;var aj=ai>1?Math.floor((ah%3600000)/60000):0;var af=ai>0?Math.floor(ah%60000/1000):0; +if(ai>2){return(ag<10?"0":"")+ag+":"+(aj<10?"0":"")+aj+":"+(af<10?"0":"")+af}else{if(ai>1){return(aj<10?"0":"")+aj+":"+(af<10?"0":"")+af}else{if(ai>0){return(af<10?"0":"")+af}}}return""}};var H=new function(){this.toTimeStr=function(K){return g.getTimeStr(K)};this.toTimeLongStr=function(K){return g.getTimeLongStr(K)};this.toTimeDayStr=function(K){return g.getFormattedDateStr(K,"D")+g.getFormatSeparator()+g.getTimeStr(K)};this.toTimeDayLongStr=function(K){return g.getFormattedDateStr(K,"D")+g.getFormatSeparator()+g.getTimeLongStr(K)};this.toDayStr=function(K){return g.getDayStr(K)};this.toDayLongStr=function(K){return g.getDayLongStr(K)};this.toDayFullStr=function(K){return g.getDayFullStr(K)};this.toDateStr=function(K){return g.getDateStr(K)};this.toDateLongStr=function(K){return g.getDateLongStr(K)};this.toRecordingStr=function(K){return g.getRecordingStr(K)};this.toDayTimeStr=function(K){return g.getDayStr(K)+g.getFormatSeparator()+g.getTimeStr(K)};this.toDayTimeLongStr=function(K){return g.getDayLongStr(K)+g.getFormatSeparator()+g.getTimeStr(K) +};this.toDayTimeFullStr=function(K){return g.getDayFullStr(K)+g.getFormatSeparator()+g.getTimeStr(K)};this.toDateTimeStr=function(K){return g.getDateStr(K)+g.getFormatSeparator()+g.getTimeStr(K)};this.toDateTimeLongStr=function(K){return g.getDateLongStr(K)+g.getFormatSeparator()+g.getTimeStr(K)}};var F=new function(){this.foreach=function(P,L){if(P!=null&&P.properties!=null&&typeof L=="function"){var N=P.properties;if(Array.isArray(N)){for(var O=0;O0){if(L==decodeURIComponent(a.strTrim(M.substr(0,O)))){return decodeURIComponent(M.substr(O+1))}}}}return Q!=null?Q:null};this.getFullStr=function(L,M){return a.strFullCheck(this.get(L),M)};this.getNum=function(L,M){return a.strToNum(this.get(L),M)};this.getBool=function(L,M){return a.strToBool(this.get(L),M)};this.has=function(L,M){return a.isValid(this.get(L),M)};this.foreach=function(R){if(typeof R=="function"){var N=m.cookie.split(";");for(var P=0;P0){var Q=decodeURIComponent(a.strTrim(M.substr(0,L))); +var O=decodeURIComponent(M.substr(L+1));if(R(Q,O)===true){break}}}}};this.remove=function(L){if(a.isFullStr(L)){this.set(L,"",K)}};this.clear=function(){var L=this;this.foreach(function(M){L.set(M,"",K)})}}function d(){var M="exp:";var L=new J();var K=function(O,P){if(P!=null){P*=1;return P>=0&&P=0){localStorage.setItem(M+O,P)}else{localStorage.removeItem(M+O)}}else{L.set(O,R,Q) +}}};this.get=function(O,R){if(a.isFullStr(O)){if(e.localStorage!=null){var Q=false;var P=localStorage.getItem(M+O);if(P!=null){if(K(g.getTimestamp(),P)){Q=true;localStorage.removeItem(O);localStorage.removeItem(M+O)}}if(!Q){var S=localStorage.getItem(O);if(S!=null){return S}}}else{return L.get(O,R)}}return R!=null?R:null};this.getFullStr=function(O,P){return a.strFullCheck(this.get(O),P)};this.getNum=function(O,P){return a.strToNum(this.get(O),P)};this.getBool=function(O,P){return a.strToBool(this.get(O),P)};this.has=function(O,P){return a.isValid(this.get(O),P)};this.foreach=function(Q){if(typeof Q=="function"){if(e.localStorage!=null){N();for(var P=0;P=0){var O=Q.substr(T+1).split("&");for(var M=0;M0){var S=R.substr(0,N);var U=R.substr(N+1);P[decodeURIComponent(S)]=decodeURIComponent(U)}else{P[decodeURIComponent(R)]=""}}}}}return P}; +this.build=function(P,O){var Q=0;var M="";if(K!=null){for(var N in K){var R=a.strValue(K[N]);if(Q>0){M+=(O!=null?O:"&")}if(a.isFullStr(R)){M+=(P===false?N:encodeURIComponent(N))+"="+(P===false?R:encodeURIComponent(R))}else{M+=(P===false?N:encodeURIComponent(N))}Q++}}return M};if(L!=null){K=this.create(L)}else{K=this.create(m.URL)}}function C(K,L){this.getValue=function(M){if(a.isFullStr(M)){if(K!=null&&K[M]!=null){return K[M]}if(L!=null&&L[M]!=null){return L[M]}}return null};this.get=function(M){return a.strValue(this.getValue(M))};this.getFullStr=function(M){return a.strFullCheck(this.get(M),null)};this.getNum=function(M){return a.strToNum(this.getValue(M),0)};this.getBool=function(M){return a.strToBool(this.getValue(M),false)};this.has=function(M,N){return a.isValid(this.get(M),N)}}function h(){var K={};this.hasObserver=function(L){return a.isFullStr(L)&&K[L]!=null};this.hasObservers=function(){var L;for(L in K){return true}return false};this.addObserver=function(L,M){if(a.isFullStr(L)&&typeof M=="function"){K[L]=M +}};this.removeObserver=function(L){if(a.isFullStr(L)){delete K[L]}};this.onEvent=function(L,M){if(a.isFullStr(L)){if(typeof M=="function"){this.addObserver(L,M)}else{this.removeObserver(L)}}};this.notifyObserver=function(L,M){if(a.isFullStr(L)&&K[L]!=null){K[L](M)}};this.notifyObservers=function(M){for(var L in K){K[L](M)}};this.clear=function(){K={}}}function I(){var K={};this.hasObserver=function(M,L){return a.isFullStr(M)&&a.isFullStr(L)&&K[M]!=null&&K[M][L]!=null};this.hasObservers=function(M){if(a.isFullStr(M)&&K[M]!=null){var L;for(L in K[M]){return true}}return false};this.addObserver=function(M,L,N){if(a.isFullStr(M)&&a.isFullStr(L)&&typeof N=="function"){if(K[M]==null){K[M]={}}K[M][L]=N}};this.removeObserver=function(M,L){if(a.isFullStr(M)&&a.isFullStr(L)&&K[M]!=null){delete K[M][L];if(!this.hasObservers(M)){delete K[M]}}};this.onEvent=function(M,L,N){if(a.isFullStr(M)&&a.isFullStr(L)){if(typeof N=="function"){this.addObserver(M,L,N)}else{this.removeObserver(M,L)}}};this.notifyObserver=function(M,L,N){if(a.isFullStr(M)&&a.isFullStr(L)&&K[M]!=null&&K[M][L]!=null){K[M][L](N) +}};this.notifyObservers=function(M,N){if(a.isFullStr(M)&&K[M]!=null){for(var L in K[M]){K[M][L](N)}}};this.clear=function(L){if(a.isFullStr(L)){if(K[L]!=null){K[L]={}}}else{K={}}}}function x(){var L=null;var M=[];var K=null;var N=false;this.delegate=null;this.execute=function(){if(L!=null){clearTimeout(L);L=null}if(K!=null){if(typeof K.action=="function"){K.action()}else{if(this.delegate!=null&&typeof this.delegate.executeQueueAction=="function"){this.delegate.executeQueueAction(K.action)}}K=null;this.process()}};this.process=function(){if(K==null&&M.length>0){K=M.shift();if(K.action==="stop"&&K.delay==null){N=true;K=null}else{if(K.delay!=null&&K.delay>0){var O=this;L=setTimeout(function(){L=null;O.execute()},K.delay)}else{this.execute()}}}};this.reset=function(){M=[];K=null;N=false;if(L!=null){clearTimeout(L);L=null}};this.push=function(O,P){if(O!=null){if(O==="reset"&&P==null){this.reset()}else{if(O==="execute"&&P==null){this.execute()}else{if(O==="clear"&&P==null){M=[]}else{if(O==="continue"&&P==null){N=false +}else{M.push({action:O,delay:P})}}}}if(!N){this.process()}}};this.isBusy=function(){return L!=null}}function c(K,O){var M=null;var N=[];var L=0;this.size=K!=null?K:0;this.delay=O!=null?O:0;this.work=function(){if(M==null&&this.delay>0){var P=this;M=setTimeout(function(){M=null;L=0;P.process()},this.delay)}};this.process=function(){if(M==null&&N.length>0){if(L0){M=setTimeout(function(){P.finish()},this.delay)}else{P.finish()}};this.restart=function(){this.start(L)};this.stop=function(){if(M!=null){clearTimeout(M);M=null}};this.finish=function(){this.stop();if(!K){K=true; +if(typeof L=="function"){L()}}};this.isBusy=function(){return M!=null}}function E(){var M=300;var N=0;var K=0;var L=null;this.click=function(O){var P=g.getTimestamp();if(L===O&&N>0&&P-N<=M){K++}else{K=1}L=O;N=P;return K}}function j(){var K="application/json";var P="application/xml";var M="text/plain";var S="text/html";var R="application/x-www-form-urlencoded";var N=function(V){var U=null;try{U=new XMLHttpRequest()}catch(T){if(V!=null&&typeof V.error=="function"){V.error("Create XML HTTP request failed: "+T)}}return U};var Q=function(T){if(T!=null&&typeof T.destroy=="function"){T.destroy()}};var O=function(X,Y,V){var T=X.responseText;var W=true;if(T!=null){if(V==K){try{if(e.JSON!=null&&typeof JSON.parse=="function"){if(a.isFullStr(T)){T=JSON.parse(T)}else{W=false;if(Y!=null&&typeof Y.error=="function"){Y.error("Validate JSON failed")}}}else{if(a.isJson(T)){T=new Function("return "+T)()}else{W=false;if(Y!=null&&typeof Y.error=="function"){Y.error("Validate JSON failed")}}}}catch(U){W=false; +if(Y!=null&&typeof Y.error=="function"){Y.error("Create JSON failed: "+U)}}}else{if(V==P){T=X.responseXML}}}if(W&&Y!=null&&typeof Y.success=="function"){Y.success(T)}};var L=function(Z,W,Y,ag,T){if(e.TVXAjaxService!=null&&typeof TVXAjaxService.executeRequest=="function"&&TVXAjaxService.executeRequest(Z,W,Y,ag,T)===true){return}var ac=N(ag);if(ac!=null){var ad=K;var X=false;var ae=false;var U=true;var af=null;if(T!=null){X=T.isForm===true;ae=T.withCredentials===true;U=T.accurateHeaders!==false;af=T.headers;if(T.dataType!=null){if(T.dataType=="json"){ad=K}else{if(T.dataType=="xml"){ad=P}else{if(T.dataType=="text"){ad=M}else{if(T.dataType=="html"){ad=S}else{ad=null}}}}}}try{if(ae){ac.withCredentials=true}ac.open(Z,W,true)}catch(ab){Q(ac);ac=null;if(ag!=null&&typeof ag.error=="function"){ag.error("Open connection failed: "+ab)}}if(ac!=null){ac.onreadystatechange=function(){if(ac!=null){if(ac.readyState==4){if((ac.status>=200&&ac.status<300)||(ac.status==0&&a.isFullStr(ac.responseText))){O(ac,ag,ad) +}else{if(ag!=null&&typeof ag.error=="function"){var ah=a.strValue(ac.status);if(a.isFullStr(ac.statusText)){ah+=" "+ac.statusText}ag.error("Server responded with status: "+ah)}}Q(ac);ac=null}}};if(ad!=null){if(Y!=null){ac.setRequestHeader("Content-Type",!X&&U?ad:R)}if(U){ac.setRequestHeader("Accept",ad)}}if(af!=null){for(var aa in af){var V=af[aa];if(V!=null){ac.setRequestHeader(a.strValue(aa),a.strValue(V))}}}try{ac.send(Y)}catch(ab){Q(ac);ac=null;if(ag!=null&&typeof ag.error=="function"){ag.error("Send data failed: "+ab)}}}}};this.get=function(T,V,U){L("GET",T,null,V,U)};this.post=function(U,W,T,V){L("POST",U,W,T,V)};this.put=function(U,W,T,V){L("PUT",U,W,T,V)};this.del=function(T,V,U){L("DELETE",T,null,V,U)}}var s={OFF:0,ERROR:1,WARN:2,INFO:3,DEBUG:4};function v(){var Q=[];var M=null;this.level=s.DEBUG;this.maxLines=30;this.maxDebugLength=116;this.maxInfoLength=-1;this.maxWarnLength=-1;this.maxErrorLength=-1;var O=function(){var R=new Date();var Y=R.getHours();var X=R.getMinutes();var V=R.getSeconds(); +var U=R.getMilliseconds();var T=R.getDate();var W=R.getMonth()+1;var S=R.getFullYear();return S+"-"+((W<10)?"0":"")+W+"-"+((T<10)?"0":"")+T+" "+((Y<10)?"0":"")+Y+":"+((X<10)?"0":"")+X+":"+((V<10)?"0":"")+V+"."+((U<10)?"00":((U<100)?"0":""))+U};var N=function(S,R){var T="";switch(S){case s.DEBUG:T=l.LOGGER.CSS.CLASS_DEBUG;break;case s.INFO:T=l.LOGGER.CSS.CLASS_INFO;break;case s.WARN:T=l.LOGGER.CSS.CLASS_WARN;break;case s.ERROR:T=l.LOGGER.CSS.CLASS_ERROR;break}return a.strReplace(l.LOGGER.HTML.LINE.replace("{LEVEL}",T),"{MESSAGE}",a.htmlEscape(R))};var L=function(S,R){var T="";switch(S){case s.DEBUG:T="DEBUG";break;case s.INFO:T="INFO";break;case s.WARN:T="WARNING";break;case s.ERROR:T="ERROR";break}return O()+" "+T+": "+R};var K=function(T,S,U,R){if(U>0&&S.length>U){S=S.substr(0,U)+"..."}Q.push(N(T,S));if(R>0){while(Q.length>R){Q.shift()}}};var P=function(S,R){if(e.console!=null){switch(S){case s.DEBUG:console.log(R);break;case s.INFO:console.info(R);break;case s.WARN:console.warn(R);break; +case s.ERROR:console.error(R);break}}};this.registerControl=function(R,S){M=R;if(S!==false){this.print()}};this.unregisterControl=function(R){if(M==R){M=null}};this.print=function(){if(M!=null&&Q.length>0){var S="";for(var R=0;R0){return this.getValueForKey(U.substr(0,T),U.substr(T+1))}else{return this.getValueForKey(U,"")}}return""};this.getData=function(){return{name:N,version:Q,size:P,properties:S}}}function i(){var M=null;var N={};var L=null;var K=null;this.delay=0;this.now=g.getNow();this.format="time";this.isRunning=function(){return M!=null};this.hasHook=function(O){return a.isFullStr(O)&&N[O]!=null};this.hasHooks=function(){var O;for(O in N){return true}return false};this.hasControl=function(){return L!=null +};this.clearHooks=function(){N={}};this.addHook=function(O,P){if(a.isFullStr(O)&&typeof P=="function"){N[O]=P}};this.removeHook=function(O){if(a.isFullStr(O)){delete N[O]}};this.onTick=function(O,P){if(a.isFullStr(O)){if(typeof P=="function"){this.addHook(O,P)}else{this.removeHook(O)}}};this.registerControl=function(O){L=O};this.unregisterControl=function(O){if(L==O){L=null}};this.update=function(){if(L!=null){var O=null;switch(this.format){case"full":O=H.toDayTimeFullStr(this.now);break;case"date":O=H.toDayTimeLongStr(this.now);break;case"day":O=H.toTimeDayStr(this.now);break;case"time":O=H.toTimeStr(this.now);break;default:O="";break}if(L.clockText!=O){L.clockText=O;L.html(O)}}};this.validate=function(){this.now=g.getNow()};this.process=function(){if(M!=null){this.validate();this.delay=K!=null?this.now.getTime()-K.getTime():0;K=this.now;this.update();for(var O in N){N[O](this)}}};this.start=function(){if(M==null){var O=this;K=null;M=setInterval(function(){O.process()},1000)}};this.stop=function(){if(M!=null){clearInterval(M); +M=null;K=null}}}var A={logger:new v(),cookies:new J(),storage:new d(),urlParams:new B(),ajax:new j()};var u=new function(){var K={};this.load=function(M,L,O,N){if(a.isFullStr(M)){if(L!=null&&K[L]!=null&&K[L].url==M&&K[L].data!=null){if(O!=null&&typeof O.success=="function"){O.success(K[L].data,true)}}else{A.ajax.get(M,{success:function(P){if(L!=null){K[L]={url:M,data:P}}if(O!=null&&typeof O.success=="function"){O.success(P,false)}},error:function(P){if(L!=null){K[L]={url:M,data:null}}if(O!=null&&typeof O.error=="function"){O.error(P)}}},N)}}};this.clearCache=function(L){if(L!=null){K[L]=null}};this.clear=function(){K={}}};function D(){var W={};var P={};var T={};var Q={};var S=function(Y){if(Y!=null&&Y.response!=null){return a.strToNum(Y.response.status,0)}return 0};var X=function(Y){if(Y!=null&&Y.response!=null){return Y.response.data}return null};var N=function(Z){var Y="";if(Z!=null&&Z.response!=null){if(a.isNum(Z.response.status)){Y+=""+Z.response.status}if(a.isFullStr(Z.response.text)){if(Y.length>0){Y+=" " +}Y+=Z.response.text}if(a.isFullStr(Z.response.message)){if(Y.length>0){Y+=": "}Y+=Z.response.message}}return Y.length>0?Y:"Unknown error"};var V=function(Y,Z){T[Y]=Z;for(var aa in W){if(W[aa]!=null){Z(W[aa])}}};var K=function(Y){delete T[Y]};var M=function(Y){for(var Z in T){T[Z](Y)}};var O=function(Y,Z){if(Y!=null&&typeof Z=="function"){Q[Y]=Z;for(var aa in P){if(P[aa]!=null){Z(P[aa])}}}};var U=function(Y){if(Y!=null){delete Q[Y]}};var L=function(Y){for(var Z in Q){Q[Z](Y)}};var R=function(Y){return Y!=null&&Y.indexOf("temp:")!=0};this.onReady=function(Y,Z){if(a.isFullStr(Y)){if(typeof Z=="function"){V(Y,Z)}else{K(Y)}}};this.onError=function(Y,Z){if(a.isFullStr(Y)){if(typeof Z=="function"){O(Y,Z)}else{U(Y)}}};this.onCompleted=function(Y,Z){this.onReady(Y,Z);this.onError(Y,Z)};this.foreachEntry=function(Z){if(typeof Z=="function"){for(var Y in W){if(W[Y]!=null){if(Z(W[Y])===true){break}}}}};this.foreachError=function(Z){if(typeof Z=="function"){for(var Y in P){if(P[Y]!=null){if(Z(P[Y])===true){break +}}}}};this.getData=function(Y){return Y!=null&&W[Y]!=null?W[Y].data:null};this.getEntry=function(Y){return Y!=null?W[Y]:null};this.setEntry=function(Z,Y){if(Z!=null&&Y!=null){W[Z]=Y;P[Z]=null;M(Y)}};this.getError=function(Y){return Y!=null?P[Y]:null};this.setError=function(Y,Z){if(Y!=null&&Z!=null){W[Y]=null;P[Y]=Z;L(Z)}};this.shouldStoreData=function(Y){return R(Y)};this.createData=function(Y,Z){return Z};this.putData=function(Z,ab,Y,aa){if(Z!=null&&ab!=null){A.ajax.put(Z,ab,{success:function(ac){if(ac.response!=null&&ac.response.status==200){if(Y!=null&&typeof Y.success=="function"){Y.success(ac.response.data)}}else{if(Y!=null&&typeof Y.error=="function"){Y.error(N(ac),S(ac),X(ac))}}},error:function(ac){if(Y!=null&&typeof Y.error=="function"){Y.error(ac,0,null)}}},aa)}};this.postData=function(Z,ab,Y,aa){if(Z!=null&&ab!=null){A.ajax.post(Z,ab,{success:function(ac){if(ac.response!=null&&ac.response.status==200){if(Y!=null&&typeof Y.success=="function"){Y.success(ac.response.data)}}else{if(Y!=null&&typeof Y.error=="function"){Y.error(N(ac),S(ac),X(ac)) +}}},error:function(ac){if(Y!=null&&typeof Y.error=="function"){Y.error(ac,0,null)}}},aa)}};this.deleteData=function(Y,aa,Z){if(Y!=null){A.ajax.del(Y,{success:function(ab){if(ab.response!=null&&ab.response.status==200){if(aa!=null&&typeof aa.success=="function"){aa.success(ab.response.data)}}else{if(aa!=null&&typeof aa.error=="function"){aa.error(N(ab),S(ab),X(ab))}}},error:function(ab){if(aa!=null&&typeof aa.error=="function"){aa.error(ab,0,null)}}},Z)}};this.loadData=function(ab,Z,ac,aa){if(ab!=null){var Y=this;if(R(ab)){this.clearData(ab)}if(Z!=null){A.ajax.get(Z,{success:function(ag){var af=false;if(ag.response!=null&&ag.response.status==200&&ag.response.data!=null){af=true;ag=ag.response.data}if(!af&&ag.response!=null){var ad={id:ab,error:N(ag),status:S(ag),reason:X(ag)};var ae=true;if(ac!=null&&typeof ac.error=="function"){ae=ac.error(ad)}if(ae!==false&&R(ab)){Y.setError(ab,ad)}if(ac!=null&&typeof ac.completed=="function"){ac.completed(ad)}}else{var ad={id:ab,data:Y.createData(ab,ag)}; +var ae=true;if(ac!=null&&typeof ac.success=="function"){ae=ac.success(ad)}if(ae!==false&&R(ab)){Y.setEntry(ab,ad)}if(ac!=null&&typeof ac.completed=="function"){ac.completed(ad)}}},error:function(af){var ad={id:ab,error:af,status:0,reason:null};var ae=true;if(ac!=null&&typeof ac.error=="function"){ae=ac.error(ad)}if(ae!==false&&R(ab)){Y.setError(ab,ad)}if(ac!=null&&typeof ac.completed=="function"){ac.completed(ad)}}},aa)}}};this.clearData=function(Y){if(Y!=null){W[Y]=null;P[Y]=null}};this.clear=function(){W={};P={}}}function r(){var P={};var S={};var Z={};var L={};var K=function(ac){if(ac!=null){try{if(e.URL!=null&&typeof URL.createObjectURL=="function"){return URL.createObjectURL(ac)}else{if(e.webkitURL!=null&&typeof webkitURL.createObjectURL=="function"){return webkitURL.createObjectURL(ac)}}}catch(ab){A.logger.error("Create blob URL failed: "+ab)}}return null};var V=function(ab){if(ab!=null){try{if(e.URL!=null&&typeof URL.revokeObjectURL=="function"){URL.revokeObjectURL(ab)}else{if(e.webkitURL!=null&&typeof webkitURL.revokeObjectURL=="function"){webkitURL.revokeObjectURL(ab) +}}}catch(ac){A.logger.error("Dispose blob URL failed: "+ac)}}};var aa=function(ad){var ac=null;try{ac=new XMLHttpRequest()}catch(ab){if(ad!=null&&typeof ad.error=="function"){ad.error("Create XML HTTP request failed: "+ab)}}return ac};var R=function(ab){if(ab!=null&&typeof ab.destroy=="function"){ab.destroy()}};var U=function(ab,ac){if(ab.response!=null){if(ac!=null&&typeof ac.success=="function"){ac.success(ab.response)}}else{if(ac!=null&&typeof ac.error=="function"){ac.error("Load blob failed: Response is missing")}}};var M=function(af,ad,ae,al,ab){var ai=aa(al);if(ai!=null){var aj=false;var ak=null;if(ab!=null){aj=ab.withCredentials===true;ak=ab.headers}try{if(aj){ai.withCredentials=true}ai.responseType="blob";ai.open(af,ad,true)}catch(ah){R(ai);ai=null;if(al!=null&&typeof al.error=="function"){al.error("Open connection failed: "+ah)}}if(ai!=null){ai.onreadystatechange=function(){if(ai!=null){if(ai.readyState==4){if(ai.status>=200&&ai.status<300){U(ai,al)}else{if(al!=null&&typeof al.error=="function"){var am=a.strValue(ai.status); +if(a.isFullStr(ai.statusText)){am+=" "+ai.statusText}al.error("Server responded with status: "+am)}}R(ai);ai=null}}};if(ak!=null){for(var ag in ak){var ac=ak[ag];if(ac!=null){ai.setRequestHeader(a.strValue(ag),a.strValue(ac))}}}try{ai.send(ae)}catch(ah){R(ai);ai=null;if(al!=null&&typeof al.error=="function"){al.error("Send data failed: "+ah)}}}}};var O=function(ab,ac,ag,ae,ah,ad,af){if(ag!=null){ab.clearBlob(ag);if(ae!=null){M(ac,ae,ah,{success:function(aj){var ai={id:ag,blob:aj,url:K(aj)};if(ad!=null&&typeof ad.success=="function"){ad.success(ai)}ab.setEntry(ag,ai);if(ad!=null&&typeof ad.completed=="function"){ad.completed(ai)}},error:function(aj){var ai={id:ag,error:aj,status:0,reason:null};if(ad!=null&&typeof ad.error=="function"){ad.error(ai)}ab.setError(ag,ai);if(ad!=null&&typeof ad.completed=="function"){ad.completed(ai)}}},af)}}};var N=function(ab,ac){Z[ab]=ac;for(var ad in P){if(P[ad]!=null){ac(P[ad])}}};var Q=function(ab){delete Z[ab]};var T=function(ab){for(var ac in Z){Z[ac](ab) +}};var X=function(ab,ac){if(ab!=null&&typeof ac=="function"){L[ab]=ac;for(var ad in S){if(S[ad]!=null){ac(S[ad])}}}};var W=function(ab){if(ab!=null){delete L[ab]}};var Y=function(ab){for(var ac in L){L[ac](ab)}};this.onReady=function(ab,ac){if(a.isFullStr(ab)){if(typeof ac=="function"){N(ab,ac)}else{Q(ab)}}};this.onError=function(ab,ac){if(a.isFullStr(ab)){if(typeof ac=="function"){X(ab,ac)}else{W(ab)}}};this.onCompleted=function(ab,ac){this.onReady(ab,ac);this.onError(ab,ac)};this.foreachEntry=function(ac){if(typeof ac=="function"){for(var ab in P){if(P[ab]!=null){if(ac(P[ab])===true){break}}}}};this.foreachError=function(ac){if(typeof ac=="function"){for(var ab in S){if(S[ab]!=null){if(ac(S[ab])===true){break}}}}};this.getBlob=function(ab){return ab!=null&&P[ab]!=null?P[ab].blob:null};this.getUrl=function(ab){return ab!=null&&P[ab]!=null?P[ab].url:null};this.getEntry=function(ab){return ab!=null?P[ab]:null};this.setEntry=function(ac,ab){if(ac!=null&&ab!=null){V(P[ac]!=null?P[ac].url:null); +P[ac]=ab;S[ac]=null;T(ab)}};this.getError=function(ab){return ab!=null?S[ab]:null};this.setError=function(ab,ac){if(ab!=null&&ac!=null){V(P[ab]!=null?P[ab].url:null);P[ab]=null;S[ab]=ac;Y(ac)}};this.executeBlob=function(ae,ac,af,ab,ad){O(this,"POST",ae,ac,af,ab,ad)};this.loadBlob=function(ad,ab,ae,ac){O(this,"GET",ad,ab,null,ae,ac)};this.clearBlob=function(ab){if(ab!=null){V(P[ab]!=null?P[ab].url:null);P[ab]=null;S[ab]=null}};this.clear=function(){for(var ab in P){V(P[ab]!=null?P[ab].url:null)}P={};S={}}}function w(P){var M="srq";var L=0;var K={};var Q=0;this.timeout=P!=null?P:30000;var N=function(R,U){L++;Q++;var T=M+L+"_"+g.getTimestamp();var S={timeout:new o(R),callback:U};K[T]=S;S.timeout.start(function(){O(T,null,"Request timed out","timeout")});return T};var O=function(U,V,R,S){if(U!=null){var T=K[U];if(T!=null){Q--;T.timeout.stop();delete K[U];if(R!=null){if(T.callback!=null&&typeof T.callback.error=="function"){T.callback.error(R,S)}}else{if(T.callback!=null&&typeof T.callback.success=="function"){T.callback.success(V) +}}}}};this.startRequest=function(R){return N(this.timeout,R)};this.getRequestsCount=function(){return Q};this.isRequestPending=function(R){return R!=null&&K[R]!=null};this.handleData=function(R,S){O(R,S!=null?S:null,null)};this.handleError=function(S,T,R){O(S,null,T!=null?T:"Unknown error",R!=null?R:null)}}function b(){var N=0;var M=null;var L=function(){if(M!=null){var P=M;M=null;if(P.length>0){for(var O=0;O0};this.start=function(O){if(O===true){N=1}else{N++}};this.stop=function(O){if(N>0){if(O===true){N=0}else{if(N>0){N--}}if(N==0){L()}}};this.onReady=function(O){if(typeof O=="function"){if(N>0){K(O)}else{O()}}}}function p(U){var V=4;var S=256;var W=null;var T=null;var ad=function(an){return a.isFullStr(an)&&an.length>=V&&an.length0){while(ao<0){ao+=an}while(ao>=an){ao-=an}}return ao};var ab=function(ap,ao,an){ap+=3;return ap+ao>=an?0:ap};var O=function(an,ao){an++;return an>=ao?0:an};var ac=function(an,ao){return ao?-an:an};var aj=function(aq,ar,ap,an,ao){return af(ar+ac(an,ao)*ae(aq,ap),S)};var Q=function(au,an,at,av,ao,ar,ap){var aq=au!=null&&at!=null?au.indexOf(at):-1;return aq>=0?al(au,af(aq+ac(ar,ap)*(av+ae(an,ao)),au.length)):at};var P=function(ao,an){return an!=null?(ao!=null?ao+an:an):ao};var al=function(an,ao){return an!=null&&ao>=0&&ao=0&&ao0.5?av.indexOf(au):av.lastIndexOf(au);return ap>=0?Y(aj(an,ap,ao,1,aq).toString(16)):null}return null};var M=function(at,an,ar,ao,aq){var av=al(at,ar);var au=al(at,ar+1);var ap=av!=null&&au!=null?parseInt(av+au,16):-1;return ap>=0?aj(an,ap,ao,-1,aq):-1 +};var ak=function(au,ay,ao){var ax=null;if(a.isFullStr(au)&&au.length%2==0&&ad(ay)&&ad(ao)){var at=au.length;var av=ao.length;var ap=0;var ar=0;var aq=false;for(var an=0;an=0&&ad0){for(var W=0;W0}if(a2.duration==0){a2.duration=aY(a5.getDuration());a8=a2.duration>0}if(a2.position>0&&a2.duration>0){aV()}if(a8){U()}}catch(a9){ak("Start failed",a9);aV()}}else{aV()}};var aV=function(){ab=true;ac()};var a4=function(){ac();if(aP&&!ab&&a5!=null&&typeof a5.getPosition=="function"&&typeof a5.getDuration=="function"){aB=setInterval(O,aj)}};var ac=function(){if(aB!=null){clearInterval(aB); +aB=null}};var aZ=0;var aS={};var av=function(ba){aZ++;var a8=aD+aZ+"_"+g.getTimestamp();var a9={timeout:new o(P),callback:ba};aS[a8]=a9;a9.timeout.start(function(){ax(a8,{error:"Request timed out"})});return a8};var ax=function(a8,ba){if(a8!=null){var a9=aS[a8];if(a9!=null){a9.timeout.stop();delete aS[a8];Y(a9.callback,ba)}}};var Y=function(ba,a8){if(typeof ba=="function"){try{ba(a8)}catch(a9){ak("Callback error",a9)}}};var aW=new h();var X=new o(500);var ay=null;var aI=null;var ag=function(a8){if(a8!=null){if(t.isSameContentState(ay,a8)){if(!t.isSameContentState(aI,a8)){if(aI==null){a8.init=true}aI=t.createChangedContentState(aI,a8);aW.notifyObservers(aI)}}else{ay=a8}}ah()};var aN=function(){if(aP){ar("info:content",function(a8){ag(a8.info!=null&&a8.info.content!=null?a8.info.content.state:null)})}else{ah()}};var ah=function(a8){if(aW.hasObservers()){if(a.isFullStr(a8)&&aI!=null){aW.notifyObserver(a8,aI)}X.start(aN)}else{ay=null;aI=null;X.stop()}};var U=function(){Z(a2)};var aH=function(){a7.addHook(N,aC) +};var a0=function(){if(a2.state==z.STOPPED){a7.stop()}else{a7.start()}};var V=function(a8,a9){if(a.isFullStr(a8)){Z({action:a8,data:a9!=null?a9:null})}};var az=function(a9,a8){if(a.isFullStr(a9)){if(a8!==false){V("logger:debug:"+a9)}}};var aE=function(a9,a8,ba){if(a.isFullStr(a9)){if(a8!==false){V("logger:success:"+a9,{show:ba!==false})}else{if(ba!==false){V("success:"+a9)}}}};var a6=function(a9,a8,ba){if(a.isFullStr(a9)){if(a8!==false){V("logger:info:"+a9,{show:ba!==false})}else{if(ba!==false){V("info:"+a9)}}}};var al=function(a9,a8,ba){if(a.isFullStr(a9)){if(a8!==false){V("logger:warn:"+a9,{show:ba!==false})}else{if(ba!==false){V("warn:"+a9)}}}};var aw=function(a9,a8,ba){if(a.isFullStr(a9)){if(a8!==false){V("logger:error:"+a9,{show:ba!==false})}else{if(ba!==false){V("error:"+a9)}}}};var Q=function(a8,a9){if(a.isFullStr(a8)&&a9!=null){if(typeof a9=="object"){V(a8+":data",a9)}else{V(a8+":"+a9)}}};var aR=function(a8){Q("menu",a8)};var au=function(a8){Q("content",a8)};var at=function(a8){Q("panel",a8) +};var ar=function(a8,ba,a9){if(a.isFullStr(a8)){if(a9==null){a9={}}a9.requestId=av(ba);a9.dataId=a8;V("player:commit:"+a8,a9)}else{Y(ba,{error:"Data ID is invalid: '"+a8+"'"})}};var ak=function(a8,a9){if(a8!=null&&a9!=null){if(a9.name!=null&&a9.message!=null){aw("Plugin: "+a8+": "+a9.name+": "+a9.message)}else{aw("Plugin: "+a8+": "+a9)}}};var K=function(a8){if(a2.state!=z.PLAYING||a8===true){a2.state=z.PLAYING;if(aP&&a5!=null&&typeof a5.play=="function"){try{a5.play()}catch(a9){ak("Play failed",a9)}}}};var aQ=function(a8){if(a2.state!=z.PAUSED||a8===true){a2.state=z.PAUSED;if(aP&&a5!=null&&typeof a5.pause=="function"){try{a5.pause()}catch(a9){ak("Pause failed",a9)}}}};var a3=function(a8){if(a2.state!=z.STOPPED||a8===true){a2.state=z.STOPPED;if(aP&&a5!=null&&typeof a5.stop=="function"){try{a5.stop()}catch(a9){ak("Stop failed",a9)}}}};var aT=function(a8,a9){if(a8==z.PLAYING){K(a9)}else{if(a8==z.PAUSED){aQ(a9)}else{if(a8==z.STOPPED){a3(a9)}}}};var aC=function(){if(aP&&a5!=null&&!aa.isBusy()&&typeof a5.getUpdateData=="function"){try{var a9=a5.getUpdateData(); +if(a9!=null){var ba=false;if(a.isNum(a9.state)){ba=true;a2.state=a.strToNum(a9.state,a2.state)}if(a.isNum(a9.position)){ba=true;a2.position=a.strToNum(a9.position,a2.position);if(!isFinite(a2.position)){a2.position=0}}if(a.isNum(a9.duration)){ba=true;a2.duration=a.strToNum(a9.duration,a2.duration);if(!isFinite(a2.duration)){a2.duration=0}}if(a.isNum(a9.speed)){ba=true;a2.speed=a.strToNum(a9.speed,a2.speed)}if(a.isBool(a9.ended)){ba=true;a2.ended=a.strToBool(a9.ended,a2.ended)}if(a.isNum(a9.volume)){ba=true;a2.volume=a.strToNum(a9.volume,a2.volume)}if(a.isBool(a9.muted)){ba=true;a2.muted=a.strToBool(a9.muted,a2.muted)}if(ba){U();a0()}}}catch(a8){ak("Update failed",a8)}}};var aK=function(ba,a8){aX=false;if(a2.position!=ba||ba==0||a8===true){a2.position=ba;if(aP&&a5!=null&&typeof a5.setPosition=="function"){try{a5.setPosition(ba);if(!aX){aa.start()}}catch(a9){ak("Set position failed",a9)}}}};var aL=function(a8,ba){if(a2.volume!=a8||ba===true){a2.volume=a8;if(aP&&a5!=null&&typeof a5.setVolume=="function"){try{a5.setVolume(a8) +}catch(a9){ak("Set volume failed",a9)}}}};var S=function(a8,a9){if(a2.muted!=a8||a9===true){a2.muted=a8;if(aP&&a5!=null&&typeof a5.setMuted=="function"){try{a5.setMuted(a8)}catch(ba){ak("Set muted failed",ba)}}}};var a1=function(a8,a9){if(a2.speed!=a8||a9===true){a2.speed=a8;if(aP&&a5!=null&&typeof a5.setSpeed=="function"){try{a5.setSpeed(a8)}catch(ba){ak("Set speed failed",ba)}}}};var ap=function(a9,a8,ba){if(a2.width!=a9||a2.height!=a8||ba===true){a2.width=a9;a2.height=a8;if(aP&&a5!=null&&typeof a5.setSize=="function"){try{a5.setSize(a9,a8)}catch(bb){ak("Set size failed",bb)}}}};var aM=function(a8,a9){V("response:"+a8,a9)};var an=function(a8,a9){ax(a8,a9)};var L=function(a9,a8,bb){if(typeof a5.handleRequest=="function"){try{a5.handleRequest(a8,bb,function(bc){aM(a9,bc)})}catch(ba){ak("Handle request failed",ba);aM(a9)}}else{aM(a9)}};var W=function(a9){if(aP&&a9!=null&&a5!=null){if(typeof a5.handleEvent=="function"){try{a5.handleEvent(a9)}catch(a8){ak("Handle event failed",a8)}}}};var aA=function(bc){if(aP&&bc!=null&&a5!=null){if(a.isFullStr(bc.requestId)&&a.isFullStr(bc.dataId)){L(bc.requestId,bc.dataId,bc.data) +}else{if(bc.data!=null&&a.isFullStr(bc.data.requestId)&&a.isFullStr(bc.data.dataId)){var a9={};var bb=bc.data.dataId;var a8=bb.indexOf(":");if(a8>0){bb=bb.substr(0,a8)}a9[bb]=bc[bb]!=null?bc[bb]:null;a9.error=a.strFullCheck(bc.error,null);an(bc.data.requestId,a9)}else{if(typeof a5.handleData=="function"){try{a5.handleData(bc)}catch(ba){ak("Handle data failed",ba)}}}}}};var ai=function(a8){if(!ao||a8===true){ao=true;if(a5!=null&&typeof a5.init=="function"){try{a5.init()}catch(a9){ak("Call init failed",a9)}}}};var aU=function(a8){if(!aP||a8===true){aP=true;if(a5!=null&&typeof a5.ready=="function"){try{a5.ready()}catch(a9){ak("Call ready failed",a9)}}}};var aJ=function(){aP=false;e.addEventListener("message",function(a8){if(n.checkOrigin(a8.origin)){am(a8.data)}},false);V("plugin:init")};var am=function(a8){if(ao&&a8!=null&&a8.type===N){if(a8.init===1&&aP){return}if(a.isNum(a8.state)){aT(a.strToNum(a8.state,a2.state))}if(a.isNum(a8.position)){aK(a.strToNum(a8.position,a2.position))}if(a.isNum(a8.speed)){a1(a.strToNum(a8.speed,a2.speed)) +}if(a.isNum(a8.volume)){S(false);aL(a.strToNum(a8.volume,a2.volume))}if(a.isBool(a8.muted)){S(a.strToBool(a8.muted,a2.muted))}if(a.isNum(a8.width)&&a.isNum(a8.height)){ap(a.strToNum(a8.width,a2.width),a.strToNum(a8.height,a2.height))}if(a8.init===1){aU()}else{if(a8.data!=null){if(a.isFullStr(a8.data.event)){W(a8.data)}else{aA(a8.data)}}}}};var Z=function(a9){if(e.parent!=null&&a9!=null){a9.type=N;a9.sender="plugin";a9.target="app";try{e.parent.postMessage(a9,"*")}catch(a8){if(e.console!=null){console.error("Post message failed",a8)}}}};this.setupPlayer=function(a8){a5=a8;if(ao){ai(true)}if(aP){aU(true)}};this.setSeekDelay=function(a8){aa.delay=a.strToNum(a8,aa.delay)};this.getSeekDelay=function(){return aa.delay};this.setLoadingDelay=function(a8){aF.delay=a.strToNum(a8,aF.delay)};this.getLoadingDelay=function(){return aF.delay};this.setState=function(a8,a9){if(aP){a2.state=a.strToNum(a8,a2.state);if(a9===true){U()}a0()}};this.getState=function(){return a2.state};this.applyState=function(){if(aP){aT(a2.state,true) +}};this.setPosition=function(a9,a8){if(aP){aX=true;a2.position=a.strToNum(a9,a2.position);if(!isFinite(a2.position)){a2.position=0}aa.stop();if(a8===true){U();a0()}}};this.getPosition=function(){return a2.position};this.applyPosition=function(){if(aP){aK(a2.position,true)}};this.setDuration=function(a8,a9){if(aP){a2.duration=a.strToNum(a8,a2.duration);if(!isFinite(a2.duration)){a2.duration=0}if(a9===true){U();a0()}}};this.getDuration=function(){return a2.duration};this.setSpeed=function(a8,a9){if(aP){a2.speed=a.strToNum(a8,a2.speed);if(a9===true){U();a0()}}};this.getSpeed=function(){return a2.speed};this.applySpeed=function(){if(aP){a1(a2.speed,true)}};this.setEnded=function(a8,a9){if(aP){a2.ended=a.strToBool(a8,a2.ended);if(a9===true){U();a0()}}};this.hasEnded=function(){return a2.ended};this.setVolume=function(a9,a8){if(aP){a2.volume=a.strToNum(a9,a2.volume);if(a8===true){U();a0()}}};this.getVolume=function(){return a2.volume};this.setMuted=function(a8,a9){if(aP){a2.muted=a.strToBool(a8,a2.muted); +if(a9===true){U();a0()}}};this.isMuted=function(){return a2.muted};this.applyVolume=function(){if(aP){aL(a2.volume,true);S(a2.muted,true)}};this.getWidth=function(){return a2.width};this.getHeight=function(){return a2.height};this.applySize=function(){if(aP){ap(a2.width,a2.height,true)}};this.executeAction=function(a8,a9){if(aP){V(a8,a9)}};this.debug=function(a9,a8){if(aP){az(a9,a8)}};this.success=function(a9,a8,ba){if(aP){aE(a9,a8,ba)}};this.info=function(a9,a8,ba){if(aP){a6(a9,a8,ba)}};this.warn=function(a9,a8,ba){if(aP){al(a9,a8,ba)}};this.error=function(a9,a8,ba){if(aP){aw(a9,a8,ba)}};this.showMenu=function(a8){if(aP){aR(a8)}};this.showContent=function(a8){if(aP){au(a8)}};this.showPanel=function(a8){if(aP){at(a8)}};this.showPlayer=function(a8){if(aP){if(a.isFullStr(a8)){V("player:show:"+a8)}else{V("player:show")}}};this.showAction=function(){if(aP){V("player:action")}};this.hidePlayer=function(){if(aP){V("player:hide")}};this.setupContentLabel=function(a8){if(aP){V("player:label:content:"+a.strFullCheck(a8,"default")) +}};this.setupExtensionLabel=function(a8){if(aP){V("player:label:extension:"+a.strFullCheck(a8,"default"))}};this.setupPositionLabel=function(a8){if(aP){V("player:label:position:"+a.strFullCheck(a8,"default"))}};this.setupDurationLabel=function(a8){if(aP){V("player:label:duration:"+a.strFullCheck(a8,"default"))}};this.setupSpeedLabel=function(a8){if(aP){V("player:label:speed:"+a.strFullCheck(a8,"default"))}};this.setupInfoText=function(a8){if(aP){V("player:info:text:"+a.strFullCheck(a8,"default"))}};this.setupInfoImage=function(a8){if(aP){V("player:info:image:"+a.strFullCheck(a8,"default"))}};this.setupButton=function(a8,a9){if(aP&&a.isId(a8)){V("player:button:"+a8+":setup",a9)}};this.enableButton=function(a8){if(aP&&a.isId(a8)){V("player:button:"+a8+":enable")}};this.disableButton=function(a8){if(aP&&a.isId(a8)){V("player:button:"+a8+":disable")}};this.focusButton=function(a8){if(aP&&a.isId(a8)){V("player:button:"+a8+":focus")}};this.setupProgressColor=function(a8){if(aP){V("player:progress:color:"+a.strFullCheck(a8,"default")) +}};this.setupProgressType=function(a8){if(aP){V("player:progress:type:"+a.strFullCheck(a8,"default"))}};this.enableProgressMarker=function(){if(aP){V("player:progress:marker:enable")}};this.disableProgressMarker=function(){if(aP){V("player:progress:marker:disable")}};this.invalidateProgressMarker=function(){if(aP){V("player:progress:marker:invalidate")}};this.setupBackground=function(a8){if(aP){V("player:background:"+a.strFullCheck(a8,"default"))}};this.setupTrigger=function(a8,a9,ba){if(aP&&a.isFullStr(a8)&&a.isFullStr(a9)){if(ba===true){V("trigger:"+a8+":shot:"+a9)}else{V("trigger:"+a8+":"+a9)}}};this.clearTrigger=function(a8){if(aP&&a.isFullStr(a8)){V("trigger:"+a8+":none")}};this.refreshPlayer=function(){if(aP){V("player:refresh")}};this.resetPlayer=function(){if(aP){V("player:reset")}};this.cancelResume=function(){if(aP){V("resume:cancel")}};this.requestData=function(a8,ba,a9){if(aP){ar(a8,ba,a9)}else{Y(ba,{error:"Plugin not ready"})}};this.requestInteractionResponse=function(a8,ba,a9){if(a.isFullStr(a8)){this.requestData("response:request:interaction:"+a8,ba,a9!=null?{requestData:a9}:null) +}else{Y(ba,{error:"Data ID is invalid: '"+a8+"'"})}};this.validateSettings=function(a8){t.invalidateSettings();this.requestData("info",function(a9){t.validateSettings(a9);Y(a8,a9)})};this.onValidatedSettings=function(a8){if(!t.areSettingsValidated()&&!aO){aO=true;this.validateSettings(function(){aO=false})}t.onValidatedSettings(a8)};this.triggerEvent=function(a8,a9){if(aP&&a.isFullStr(a8)){V("event:"+a8,a9)}};this.setupSteam=function(a8){af(a8)};this.createSteam=function(a8){return aq(a8)};this.resolveToken=function(a8,a9){return M(a8,a9)};this.transformString=function(a8,a9){return aG(a8,a9)};this.normalizeString=function(a8,a9){return ad(a8,a9)};this.transformStringAsync=function(ba,bb,a9){var a8=aG(ba,bb);if(a.isFullStr(a8)){this.requestData("string:transform:"+a8,function(bc){Y(a9,{string:a.strFullCheck(bc.string,null)})})}else{Y(a9,{string:null})}};this.normalizeStringAsync=function(a9,ba,a8){if(a.isFullStr(a9)){this.requestData("string:normalize:"+a9,function(bb){Y(a8,{string:ad(bb.string,ba)}) +})}else{Y(a8,{string:null})}};this.createHashKey=function(a8,a9){return n.createHashKey(a8,a9)};this.clearDeviceId=function(){n.clearDeviceId()};this.getDeviceId=function(a8){return n.getDeviceId(a8)};this.requestDeviceId=function(a8){this.requestData("info:extended",function(a9){if(a9.error!=null){Y(a8,{error:a9.error})}else{Y(a8,{deviceId:n.getDeviceId(a9)})}})};this.hasContentObservers=function(){return aW.hasObservers()};this.addContentObserver=function(a8,a9){aW.addObserver(a8,a9);ah(a8)};this.removeContentObserver=function(a8){aW.removeObserver(a8);ah()};this.clearContentObservers=function(){aW.clear();ah()};this.init=function(){if(!ao){aJ();aH();ai()}};this.commit=function(){if(aP){U();a0()}};this.isInitialized=function(){return ao};this.isReady=function(){return aP};this.startPlayback=function(a8){if(aP){aT(z.PLAYING,true);U();a0();if(a8===true){a4()}}};this.stopPlayback=function(){if(aP){this.setEnded(true);U();ac()}};this.cancelPlayback=function(){if(aP){V("player:eject")}};this.startLoading=function(){if(aP){aF.start(function(){R=true; +V("player:busy:start:loading")})}};this.stopLoading=function(){if(aP){aF.stop();if(R){R=false;V("player:busy:stop:loading")}}}};var y=new function(){var N="interactionPlugin";var ar="irq";var ah=10;var aK=30000;var Z=new p("j3RZ!=Y$M5TZ#JPem'P1i(Tf?X3WcGlyCqNeXRbp02HL]I~r!IfO(pvxQ7At%9yq.5=)wm@0o?Js[sUbUH416uhd;_S/Qr,w7vW]jBgND;GazhCL+D%z~8ni+n-B_E-KK42tl[OAV@*E.Ya6$V,&kF)o&Mg98#'ucx/dk*SF");var S=null;var R=false;var au=new o(1000);var aC=false;var aj=false;var ad=null;var aB=false;var aG=null;var aa=function(aO){S=new p(aO)};var ak=function(aO){if(aC){if(aO=="local"){return S!=null?S.createSteam():null}return Z.createSteam()}return null};var L=function(aO,aP){if(aC){if(aP=="local"){return S!=null?S.resolveToken(aO):null}return Z.resolveToken(aO)}return null};var av=function(aO,aP){if(aC){if(aP=="local"){return S!=null?S.transformString(aO):null}else{if(aP=="global"){return Z.transformString(aO)}else{if(aP=="shared"){return n.transformString(S!=null?S.transformString(aO):aO)}}}return Z.transformString(S!=null?S.transformString(aO):aO) +}return null};var Y=function(aO,aP){if(aC){if(aP=="local"){return S!=null?S.normalizeString(aO):null}else{if(aP=="global"){return Z.normalizeString(aO)}else{if(aP=="shared"){return S!=null?S.normalizeString(n.normalizeString(aO)):n.normalizeString(aO)}}}return S!=null?S.normalizeString(Z.normalizeString(aO)):Z.normalizeString(aO)}return null};var aL=0;var aF={};var am=function(aQ){aL++;var aO=ar+aL+"_"+g.getTimestamp();var aP={timeout:new o(aK),callback:aQ};aF[aO]=aP;aP.timeout.start(function(){ao(aO,{error:"Request timed out"})});return aO};var ao=function(aO,aQ){if(aO!=null){var aP=aF[aO];if(aP!=null){aP.timeout.stop();delete aF[aO];V(aP.callback,aQ)}}};var V=function(aQ,aO){if(typeof aQ=="function"){try{aQ(aO)}catch(aP){af("Callback error",aP)}}};var aJ=new h();var ae=new o(500);var ap=null;var ax=null;var ab=function(aO){if(aO!=null){if(t.isSameContentState(ap,aO)){if(!t.isSameContentState(ax,aO)){if(ax==null){aO.init=true}ax=t.createChangedContentState(ax,aO);aJ.notifyObservers(ax) +}}else{ap=aO}}ac()};var aA=function(){if(aC){al("info:content",function(aO){ab(aO.info!=null&&aO.info.content!=null?aO.info.content.state:null)})}else{ac()}};var ac=function(aO){if(aJ.hasObservers()){if(a.isFullStr(aO)&&ax!=null){aJ.notifyObserver(aO,ax)}ae.start(aA)}else{ap=null;ax=null;ae.stop()}};var T=function(aO,aP){if(a.isFullStr(aO)){W({action:aO,data:aP!=null?aP:null})}};var aw=function(aP,aO){if(a.isFullStr(aP)){if(aO!==false){T("logger:debug:"+aP)}}};var at=function(aP,aO,aQ){if(a.isFullStr(aP)){if(aO!==false){T("logger:success:"+aP,{show:aQ!==false})}else{if(aQ!==false){T("success:"+aP)}}}};var aN=function(aP,aO,aQ){if(a.isFullStr(aP)){if(aO!==false){T("logger:info:"+aP,{show:aQ!==false})}else{if(aQ!==false){T("info:"+aP)}}}};var ag=function(aP,aO,aQ){if(a.isFullStr(aP)){if(aO!==false){T("logger:warn:"+aP,{show:aQ!==false})}else{if(aQ!==false){T("warn:"+aP)}}}};var an=function(aP,aO,aQ){if(a.isFullStr(aP)){if(aO!==false){T("logger:error:"+aP,{show:aQ!==false})}else{if(aQ!==false){T("error:"+aP) +}}}};var P=function(aO,aP){if(a.isFullStr(aO)&&aP!=null){if(typeof aP=="object"){T(aO+":data",aP)}else{T(aO+":"+aP)}}};var aE=function(aO){P("menu",aO)};var X=function(aO){P("content",aO)};var U=function(aO){P("panel",aO)};var al=function(aO,aQ,aP){if(a.isFullStr(aO)){if(aP==null){aP={}}aP.requestId=am(aQ);aP.dataId=aO;T("interaction:commit:"+aO,aP)}else{V(aQ,{error:"Data ID is invalid: '"+aO+"'"})}};var af=function(aO,aP){if(aO!=null&&aP!=null){if(aP.name!=null&&aP.message!=null){an("Interaction: "+aO+": "+aP.name+": "+aP.message)}else{an("Interaction: "+aO+": "+aP)}}};var az=function(aO,aP){T("response:"+aO,aP)};var ai=function(aO,aP){ao(aO,aP)};var K=function(aP,aO,aR){if(typeof ad.handleRequest=="function"){try{ad.handleRequest(aO,aR,function(aS){az(aP,aS)})}catch(aQ){af("Handle request failed",aQ);az(aP)}}else{az(aP)}};var aM=function(aP){if(aC&&aP!=null&&ad!=null){if(typeof ad.handleEvent=="function"){try{ad.handleEvent(aP)}catch(aO){af("Handle event failed",aO)}}}};var aq=function(aS){if(aC&&aS!=null&&ad!=null){if(a.isFullStr(aS.requestId)&&a.isFullStr(aS.dataId)){K(aS.requestId,aS.dataId,aS.data) +}else{if(aS.data!=null&&a.isFullStr(aS.data.requestId)&&a.isFullStr(aS.data.dataId)){var aP={};var aR=aS.data.dataId;var aO=aR.indexOf(":");if(aO>0){aR=aR.substr(0,aO)}aP[aR]=aS[aR]!=null?aS[aR]:null;aP.error=a.strFullCheck(aS.error,null);ai(aS.data.requestId,aP)}else{if(typeof ad.handleData=="function"){try{ad.handleData(aS)}catch(aQ){af("Handle data failed",aQ)}}}}}};var aH=function(aO){aG=aO!=null&&aO.length>0?aO:null};var Q=function(){if(aG!=null&&aG.length>0){for(var aO=0;aO=ah){aG.shift()}aG.push(aO)}};var O=function(aO){if(!aj||aO===true){aj=true;if(ad!=null&&typeof ad.init=="function"){try{ad.init()}catch(aP){af("Call init failed",aP)}}}};var aD=function(aO){if(!aC||aO===true){aC=true;if(ad!=null&&typeof ad.ready=="function"){try{ad.ready()}catch(aP){af("Call ready failed",aP)}}if(ad!=null){Q()}}};var ay=function(){aC=false;e.addEventListener("message",function(aO){if(n.checkOrigin(aO.origin)){M(aO.data) +}},false);T("interaction:init")};var M=function(aO){if(aj&&aO!=null&&aO.type===N){if(aO.init===1&&aC){return}if(aO.init===1){aH(aO.data);aD()}else{if(aO.data!=null){if(a.isFullStr(aO.data.event)){aM(aO.data)}else{if(ad!=null){aq(aO.data)}else{aI(aO.data)}}}}}};var W=function(aP){if(e.parent!=null&&aP!=null){aP.type=N;aP.sender="plugin";aP.target="app";try{e.parent.postMessage(aP,"*")}catch(aO){if(e.console!=null){console.error("Post message failed",aO)}}}};this.setupHandler=function(aO){ad=aO;if(aj){O(true)}if(aC){aD(true)}};this.setLoadingDelay=function(aO){au.delay=a.strToNum(aO,au.delay)};this.getLoadingDelay=function(){return au.delay};this.executeAction=function(aO,aP){if(aC){T(aO,aP)}};this.debug=function(aP,aO){if(aC){aw(aP,aO)}};this.success=function(aP,aO,aQ){if(aC){at(aP,aO,aQ)}};this.info=function(aP,aO,aQ){if(aC){aN(aP,aO,aQ)}};this.warn=function(aP,aO,aQ){if(aC){ag(aP,aO,aQ)}};this.error=function(aP,aO,aQ){if(aC){an(aP,aO,aQ)}};this.showMenu=function(aO){if(aC){aE(aO)}};this.showContent=function(aO){if(aC){X(aO) +}};this.showPanel=function(aO){if(aC){U(aO)}};this.requestData=function(aO,aQ,aP){if(aC){al(aO,aQ,aP)}else{V(aQ,{error:"Plugin not ready"})}};this.requestPlayerResponse=function(aO,aQ,aP){if(a.isFullStr(aO)){this.requestData("response:request:player:"+aO,aQ,aP!=null?{requestData:aP}:null)}else{V(aQ,{error:"Data ID is invalid: '"+aO+"'"})}};this.validateSettings=function(aO){t.invalidateSettings();this.requestData("info",function(aP){t.validateSettings(aP);V(aO,aP)})};this.onValidatedSettings=function(aO){if(!t.areSettingsValidated()&&!aB){aB=true;this.validateSettings(function(){aB=false})}t.onValidatedSettings(aO)};this.triggerEvent=function(aO,aP){if(aC&&a.isFullStr(aO)){T("event:"+aO,aP)}};this.setupSteam=function(aO){aa(aO)};this.createSteam=function(aO){return ak(aO)};this.resolveToken=function(aO,aP){return L(aO,aP)};this.transformString=function(aO,aP){return av(aO,aP)};this.normalizeString=function(aO,aP){return Y(aO,aP)};this.transformStringAsync=function(aQ,aR,aP){var aO=av(aQ,aR); +if(a.isFullStr(aO)){this.requestData("string:transform:"+aO,function(aS){V(aP,{string:a.strFullCheck(aS.string,null)})})}else{V(aP,{string:null})}};this.normalizeStringAsync=function(aP,aQ,aO){if(a.isFullStr(aP)){this.requestData("string:normalize:"+aP,function(aR){V(aO,{string:Y(aR.string,aQ)})})}else{V(aO,{string:null})}};this.createHashKey=function(aO,aP){return n.createHashKey(aO,aP)};this.clearDeviceId=function(){n.clearDeviceId()};this.getDeviceId=function(aO){return n.getDeviceId(aO)};this.requestDeviceId=function(aO){this.requestData("info:extended",function(aP){if(aP.error!=null){V(aO,{error:aP.error})}else{V(aO,{deviceId:n.getDeviceId(aP)})}})};this.hasContentObservers=function(){return aJ.hasObservers()};this.addContentObserver=function(aO,aP){aJ.addObserver(aO,aP);ac(aO)};this.removeContentObserver=function(aO){aJ.removeObserver(aO);ac()};this.clearContentObservers=function(){aJ.clear();ac()};this.init=function(){if(!aj){ay();O()}};this.isInitialized=function(){return aj};this.isReady=function(){return aC +};this.startLoading=function(){if(aC){au.start(function(){R=true;T("interaction:busy:start:loading")})}};this.stopLoading=function(){if(aC){au.stop();if(R){R=false;T("interaction:busy:stop:loading")}}}};e.TVXSettings=k;e.TVXStyles=l;e.TVXTools=a;e.TVXDateTools=g;e.TVXDateFormatter=H;e.TVXPropertyTools=F;e.TVXVideoState=z;e.TVXAction=f;e.TVXCookies=J;e.TVXStorage=d;e.TVXUrlParams=B;e.TVXOptions=C;e.TVXObservers=h;e.TVXEventObservers=I;e.TVXQueue=x;e.TVXWorker=c;e.TVXDelay=o;e.TVXClick=E;e.TVXAjax=j;e.TVXLogLevel=s;e.TVXLogger=v;e.TVXDictionary=q;e.TVXClock=i;e.TVXServices=A;e.TVXDataLoader=u;e.TVXDataService=D;e.TVXBlobService=r;e.TVXRequestService=w;e.TVXBusyService=b;e.TVXPluginTools=t;e.TVXVideoPlugin=G;e.TVXInteractionPlugin=y})(window,document); \ No newline at end of file diff --git a/server/web/msx/route.go b/server/web/msx/route.go index 61f6fee..651a0c9 100644 --- a/server/web/msx/route.go +++ b/server/web/msx/route.go @@ -7,4 +7,16 @@ func SetupRoute(route *gin.RouterGroup) { route.GET("/msx/torrents", msxTorrents) route.GET("/msx/playlist", msxPlaylist) route.GET("/msx/playlist/*fname", msxPlaylist) + + route.GET("/msx/tizen.html", func(c *gin.Context) { + c.Data(200, "text/html; charset=utf-8", Msxtizenhtml) + }) + + route.GET("/msx/tizen.js", func(c *gin.Context) { + c.Data(200, "text/javascript; charset=utf-8", Msxtizenjs) + }) + + route.GET("/msx/tvx-plugin.min.js", func(c *gin.Context) { + c.Data(200, "text/javascript; charset=utf-8", Msxtvxpluginminjs) + }) } diff --git a/server/web/pages/template/pages/static/js/main.26d1f79c.chunk.js.map b/server/web/pages/template/pages/static/js/main.26d1f79c.chunk.js.map new file mode 100644 index 0000000..91443da --- /dev/null +++ b/server/web/pages/template/pages/static/js/main.26d1f79c.chunk.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["utils/Hosts.js","i18n.js","utils/Utils.js","icons/index.jsx","components/DialogTorrentDetailsContent/customHooks.jsx","components/DialogTorrentDetailsContent/DialogHeader.jsx","style/colors.js","style/materialUISetup.js","components/DialogTorrentDetailsContent/TorrentCache/snakeSettings.js","components/DialogTorrentDetailsContent/TorrentCache/style.js","components/DialogTorrentDetailsContent/TorrentCache/index.jsx","components/DialogTorrentDetailsContent/TorrentCache/getShortCacheMap.js","components/DialogTorrentDetailsContent/Table/style.js","components/DialogTorrentDetailsContent/Table/index.jsx","components/DialogTorrentDetailsContent/style.js","components/DialogTorrentDetailsContent/DetailedView/style.js","components/DialogTorrentDetailsContent/StatisticsField.jsx","components/DialogTorrentDetailsContent/widgets/useGetWidgetColors.jsx","components/DialogTorrentDetailsContent/widgets/index.jsx","torrentStates.js","components/DialogTorrentDetailsContent/DetailedView/index.jsx","components/DialogTorrentDetailsContent/TorrentFunctions/style.js","components/DialogTorrentDetailsContent/TorrentFunctions/index.jsx","components/DialogTorrentDetailsContent/helpers.js","components/DialogTorrentDetailsContent/index.jsx","utils/useChangeLanguage.js","utils/usePreviousState.js","style/DialogStyles.js","components/Add/helpers.js","components/Add/style.js","components/Add/RightSideComponent.jsx","components/Add/LeftSideComponent.jsx","components/Add/AddDialog.jsx","components/TorrentCard/style.js","components/TorrentCard/index.jsx","components/App/style.js","components/TorrentList/style.js","components/TorrentList/NoServerConnection.jsx","components/TorrentList/AddFirstTorrent.jsx","components/TorrentList/index.jsx","components/Donate/DonateDialog.jsx","components/Donate/index.jsx","style/GlobalStyle.js","components/Add/index.jsx","components/Settings/style.js","components/Settings/defaultSettings.js","components/Settings/tabComponents.jsx","components/Settings/SliderInput.jsx","components/Settings/PrimarySettingsComponent.jsx","components/Settings/SecondarySettingsComponent.jsx","components/Settings/SettingsDialog.jsx","components/Settings/index.jsx","components/RemoveAll.jsx","components/About/style.js","components/About/LinkComponent.jsx","components/About/index.jsx","components/CloseServer.jsx","components/App/Sidebar.jsx","components/App/index.jsx","style/getStyledComponentsTheme.js","index.jsx"],"names":["window","location","protocol","hostname","port","torrserverHost","torrentsHost","viewedHost","settingsHost","streamHost","echoHost","playlistTorrHost","i18n","use","LanguageDetector","initReactI18next","init","fallbackLng","interpolation","escapeValue","resources","en","translation","translationEN","ru","translationRU","ua","translationUA","humanizeSize","size","i","Math","floor","log","pow","toFixed","t","humanizeSpeed","speed","getPeerString","torrent","connected_seeders","active_peers","total_peers","removeRedundantCharacters","string","newString","forEach","el","leftBracketRegexFormula","leftBracketRegex","RegExp","leftBracketAmount","matchAll","length","rightBracketRegexFormula","rightBracketRegex","removeFormula","removeRegex","replace","hasThreeDotsAtTheEnd","match","trimmedString","trim","getTorrents","a","axios","post","action","data","Error","NoImageIcon","color","primary","useTheme","palette","main","height","width","fill","xmlns","xmlnsXlink","version","x","y","viewBox","enableBackground","xmlSpace","d","points","AddItemIcon","id","opacity","USBIcon","RAMIcon","TorrentIcon","secondaryColor","useUpdateCache","hash","useState","cache","setCache","componentIsMounted","useRef","timerID","useEffect","current","setInterval","updateCache","newCache","then","catch","clearInterval","useStyles","makeStyles","appBar","position","title","marginLeft","flex","DialogHeader","onClose","onBack","classes","AppBar","className","Toolbar","IconButton","edge","onClick","ArrowBack","Typography","variant","autoFocus","style","marginRight","themeColors","light","app","headerToggleColor","appSecondaryColor","sidebarBGColor","sidebarFillColor","torrentCard","accentCardColor","buttonBGColor","rgba","cardPrimaryColor","cardSecondaryColor","dialogTorrentDetailsContent","posterBGColor","gradientStartColor","gradientEndColor","chacheSectionBGColor","widgetFontColor","titleFontColor","subNameFontColor","torrentFilesSectionBGColor","detailedView","cacheSectionBGColor","addDialog","fontColor","notificationErrorBGColor","notificationSuccessBGColor","languageSwitchBGColor","languageSwitchFontColor","torrentFunctions","table","defaultPrimaryColor","defaultSecondaryColor","defaultTertiaryColor","settingsDialog","contentBG","footerBG","dark","mainColors","secondary","labels","THEME_MODES","typography","fontFamily","lightTheme","createMuiTheme","type","snakeSettings","default","borderWidth","pieceSize","gapBetweenPieces","borderColor","completeColor","backgroundColor","progressColor","readerColor","rangeColor","mini","cacheMaxHeight","ScrollNotification","styled","div","SnakeWrapper","isMini","themeType","css","TorrentCache","shotCacheMap","isSnakeDebugMode","useTranslation","dimensions","setDimensions","canvasRef","ctxRef","cacheMap","setCacheMap","PiecesCount","Pieces","Readers","map","Size","Length","Priority","newPiece","percentage","priority","r","Reader","isReader","Start","End","isReaderRange","push","useCreateCacheMap","settingsTarget","theme","useContext","DarkModeContext","isDarkMode","canvasWidth","pieceSizeWithGap","piecesInOneRow","preloadPiecesAmount","cacheMapWithoutEmptyBlocks","filter","getFullAmountOfBlocks","amountOfBlocks","amountOfBlocksToRenderInShortView","scalableAmountOfBlocksToRenderInShortView","extraBlocksAmount","max","extraEmptyBlocksForFillingLine","Array","getShortCacheMap","round","Capacity","PiecesLength","source","startingXPoint","ceil","canvas","getContext","ctx","clearRect","inProgress","isCompleted","currentRow","currentColumn","fixBlurStroke","requiredFix","lineWidth","fillStyle","snakeType","gradient","createLinearGradient","addColorStop","createGradient","strokeStyle","translate","fillRect","strokeRect","setTransform","info","font","xpad","ypad","fillText","bounds","onResize","measureRef","display","flexDirection","ref","memo","prev","next","isEqual","viewedPrimaryColor","viewedIndicator","TableStyle","ShortTableWrapper","ShortTable","isViewed","require","ptt","addHandler","Table","playableFileList","viewedFileList","selectedSeason","seasonAmount","preloadBuffer","fileId","fetch","getFileLink","path","encodeURIComponent","split","pop","fileHasEpisodeText","find","parse","episode","fileHasSeasonText","season","fileHasResolutionText","resolution","shouldDisplayFullFileName","includes","link","Button","textDecoration","href","target","rel","text","DialogContentGrid","Poster","poster","MainSection","section","CacheSection","TorrentFilesSection","SectionSubName","mb","SectionTitle","SectionHeader","WidgetWrapper","WidgetFieldWrapper","WidgetFieldTitle","WidgetFieldIcon","bgColor","WidgetFieldValue","LoadingProgress","attrs","value","fullAmount","min","background","label","Divider","DetailedViewWidgetSection","DetailedViewCacheSection","StatisticsField","Icon","icon","iconBg","valueBg","LIGHT","DARK","colors","downloadSpeed","iconBGColor","valueBGColor","uploadSpeed","peers","piecesCount","piecesLength","status","useGetWidgetColors","widgetName","DownlodSpeedWidget","ArrowDownwardIcon","UploadSpeedWidget","ArrowUpwardIcon","PeersWidget","SwapVerticalCircleIcon","PiecesCountWidget","WidgetsIcon","PiecesLengthWidget","PhotoSizeSelectSmallIcon","StatusWidget","stat","values","BuildIcon","SizeWidget","ViewAgendaIcon","DetailedView","torrentSize","JSON","localStorage","getItem","setIsSnakeDebugMode","justifyContent","alignItems","FormControlLabel","control","Checkbox","checked","disableRipple","onChange","setItem","labelPlacement","MainSectionButtonGroup","SmallLabel","TorrentFunctions","name","setViewedFileList","latestViewedFileId","latestViewedFile","isOnlyOnePlayableFile","latestViewedFileData","fullPlaylistLink","partialPlaylistLink","file_index","playableExtList","Loader","minHeight","placeItems","CircularProgress","DialogTorrentDetailsContent","closeDialog","isLoading","setIsLoading","isDetailedCacheView","setIsDetailedCacheView","setPlayableFileList","setSeasonAmount","setSelectedSeason","download_speed","upload_speed","torrent_size","torrentFileList","file_stats","settings","setSettings","useGetSettings","Filled","seasons","currentSeason","sort","b","fileName","filename","ext","toLowerCase","getExt","cacheLoaded","Object","entries","torrentLoaded","lst","itm","preloadSize","PreloadCache","bufferSize","getParsedTitle","newNameStringArr","torrentParsedName","year","newNameString","join","overflow","alt","src","marginTop","ButtonGroup","marginBottom","language","substr","lang","changeLanguage","usePreviousState","Header","ButtonWrapper","getMoviePosters","movieName","url","get","params","api_key","process","include_image_language","query","results","poster_path","checkImageURL","magnetRegex","hashRegex","torrentRegex","linkRegex","Content","isEditMode","RightSide","RightSideContainer","isHidden","notificationMessage","isError","LeftSide","LeftSideBottomSectionBasicStyles","LeftSideBottomSectionNoFile","isDragActive","LeftSideBottomSectionFileSelected","TorrentIconWrapper","CancelIconWrapper","IconWrapper","LeftSideTopSection","active","PosterWrapper","PosterSuggestions","PosterSuggestionsItem","ClearPosterButton","showbutton","PosterLanguageSwitch","RightSideComponent","setTitle","setPosterUrl","setIsPosterUrlCorrect","setIsUserInteractedWithPoster","setPosterList","isTorrentSourceCorrect","isHashAlreadyExists","parsedTitle","posterUrl","isPosterUrlCorrect","posterList","currentLang","posterSearchLanguage","setPosterSearchLanguage","posterSearch","removePoster","torrentSource","originalTorrentTitle","updateTitleFromSource","isCustomTitleEnabled","setIsCustomTitleEnabled","handleTitleChange","TextField","margin","fullWidth","disabled","InputProps","readOnly","onFocus","onBlur","helperText","endAdornment","InputAdornment","padding","HighlightOff","slice","userChangesPosterUrl","newLanguage","shouldRefreshMainPoster","LeftSideComponent","setSelectedFile","setTorrentSource","selectedFile","isTorrentSourceActive","setIsTorrentSourceActive","useDropzone","onDrop","files","file","accept","getRootProps","getInputProps","inputProps","autoComplete","Cancel","AddDialog","handleClose","originalHash","originalTitle","originalName","originalPoster","setOriginalTorrentTitle","setParsedTitle","setIsTorrentSourceCorrect","setIsHashAlreadyExists","isUserInteractedWithPoster","useChangeLanguage","isSaving","setIsSaving","skipDebounce","setSkipDebounce","currentSourceHash","setCurrentSourceHash","torrents","useQuery","retry","refetchInterval","parseTorrent","remote","_","infoHash","allHashes","fullScreen","useMediaQuery","useCallback","parsingSource","callback","err","torrentName","nameOfFileInsideTorrent","newTitle","correctImage","useMemo","urlList","firstPoster","delayedPosterSearch","debounce","prevTorrentSourceState","prevTitleState","cancel","Dialog","open","maxWidth","minWidth","finally","FormData","append","save_to_db","TorrentCard","TorrentCardPoster","isPoster","TorrentCardButtons","TorrentCardDescription","StyledButton","button","Transition","forwardRef","props","Slide","direction","Torrent","isDetailedInfoOpened","setIsDetailedInfoOpened","isDeleteTorrentOpened","setIsDeleteTorrentOpened","breakpoints","down","closeDetailedInfo","closeDeleteTorrentAlert","key","titleStrings","parsedYear","parsedResolution","isEditDialogOpen","setIsEditDialogOpen","UnfoldMore","PlayArrow","Close","Delete","TransitionComponent","DialogTitle","DialogActions","AppWrapper","CenteredGrid","AppHeader","AppSidebarStyle","isDrawerOpen","TorrentListWrapper","HeaderToggle","isButton","NoServerConnection","trigger","stroke","scale","AddFirstTorrent","isDialogOpen","setIsDialogOpen","TorrentList","isOffline","DonateDialog","DialogContent","List","ListItem","dangerouslySetInnerHTML","__html","DonateSnackbar","setOpen","snackbarOpen","setSnackbarOpen","disableSnackbar","Snackbar","anchorOrigin","vertical","horizontal","message","fontSize","createGlobalStyle","AddDialogButton","ListItemIcon","ListItemText","cacheBeforeReaderColor","cacheAfterReaderColor","SettingsHeader","FooterSection","PreloadCacheValue","MainSettingsContent","SecondarySettingsContent","StorageButton","small","selected","StorageIconWrapper","CacheStorageSelector","SettingSectionLabel","PreloadCachePercentage","preloadCachePercentage","CacheSize","ReaderReadAHead","UseDisk","UploadRateLimit","TorrentsSavePath","ConnectionsLimit","DhtConnectionLimit","DisableDHT","DisablePEX","DisableTCP","DisableUPNP","DisableUTP","DisableUpload","DownloadRateLimit","EnableDebug","EnableIPv6","ForceEncrypt","PeersListenPort","RemoveCacheOnDrop","RetrackersMode","Strategy","TorrentDisconnectTimeout","a11yProps","index","TabPanel","children","other","role","hidden","SliderInput","isProMode","setValue","sliderMin","sliderMax","inputMin","inputMax","step","onBlurCallback","Grid","container","spacing","item","xs","Slider","newValue","OutlinedInput","Number","CacheStorageLocationLabel","PrimarySettingsComponent","inputForm","cachePercentage","cacheSize","setCacheSize","setCachePercentage","setPreloadCachePercentage","updateSettings","preloadCacheSize","gridAutoFlow","Switch","placeSelf","gridArea","SecondarySettingsComponent","EnableDLNA","InputLabel","htmlFor","Select","native","SettingsDialog","selectedTab","setSelectedTab","setIsProMode","sets","stringify","Boolean","isNaN","newProps","Tabs","indicatorColor","textColor","Tab","axis","onChangeIndex","dir","defaultSettings","SettingsDialogButton","RemoveAll","method","body","headers","Accept","res","json","torr","DialogWrapper","HeaderSection","ThanksSection","Section","LinkWrapper","isLink","LinkIcon","LinkComponent","GitHub","AboutDialog","torrServerVersion","setTorrServerVersion","CloseServer","PowerSettingsNew","Sidebar","setIsDonationDialogOpen","createContext","App","setIsDrawerOpen","isDonationDialogOpen","savedThemeMode","isSystemModeDark","setIsDarkMode","currentThemeMode","setCurrentThemeMode","muiTheme","overrides","MuiInputBase","input","MuiFormControlLabel","labelPlacementStart","marginStart","MuiInputLabel","root","mode","useMaterialUITheme","updateThemeMode","changeLang","setIsOffline","onError","onSuccess","GlobalStyle","Provider","CssBaseline","Menu","noWrap","justifySelf","gridTemplateColumns","gap","Brightness5","Brightness4","BrightnessAuto","toUpperCase","queryClient","QueryClient","ReactDOM","render","QueryClientProvider","client","document","getElementById"],"mappings":"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","file":"static/js/main.26d1f79c.chunk.js","sourcesContent":["const { protocol, hostname, port } = window.location\n\nlet torrserverHost = process.env.REACT_APP_SERVER_HOST || `${protocol}//${hostname}${port ? `:${port}` : ''}`\n\nexport const torrentsHost = () => `${torrserverHost}/torrents`\nexport const viewedHost = () => `${torrserverHost}/viewed`\nexport const cacheHost = () => `${torrserverHost}/cache`\nexport const torrentUploadHost = () => `${torrserverHost}/torrent/upload`\nexport const settingsHost = () => `${torrserverHost}/settings`\nexport const streamHost = () => `${torrserverHost}/stream`\nexport const shutdownHost = () => `${torrserverHost}/shutdown`\nexport const echoHost = () => `${torrserverHost}/echo`\nexport const playlistTorrHost = () => `${torrserverHost}/stream`\n\nexport const getTorrServerHost = () => torrserverHost\nexport const setTorrServerHost = host => {\n torrserverHost = host\n}\n","import i18n from 'i18next'\nimport { initReactI18next } from 'react-i18next'\nimport LanguageDetector from 'i18next-browser-languagedetector'\nimport translationEN from 'locales/en/translation.json'\nimport translationRU from 'locales/ru/translation.json'\nimport translationUA from 'locales/ua/translation.json'\n\ni18n\n .use(LanguageDetector)\n .use(initReactI18next)\n .init({\n fallbackLng: 'en', // default language will be used if none of declared lanuages detected (en, ru)\n interpolation: { escapeValue: false }, // react already safes from xss\n resources: {\n en: { translation: translationEN },\n ru: { translation: translationRU },\n ua: { translation: translationUA },\n },\n })\n\nexport default i18n\n","import axios from 'axios'\n\nimport i18n from '../i18n'\nimport { torrentsHost } from './Hosts'\n\nexport function humanizeSize(size) {\n if (!size) return ''\n const i = Math.floor(Math.log(size) / Math.log(1024))\n return `${(size / Math.pow(1024, i)).toFixed(2) * 1} ${\n [i18n.t('B'), i18n.t('KB'), i18n.t('MB'), i18n.t('GB'), i18n.t('TB')][i]\n }`\n}\n\nexport function humanizeSpeed(speed) {\n if (!speed) return ''\n const i = Math.floor(Math.log(speed * 8) / Math.log(1000))\n return `${((speed * 8) / Math.pow(1000, i)).toFixed(0) * 1} ${\n [i18n.t('bps'), i18n.t('kbps'), i18n.t('Mbps'), i18n.t('Gbps'), i18n.t('Tbps')][i]\n }`\n}\n\nexport function getPeerString(torrent) {\n if (!torrent || !torrent.connected_seeders) return null\n return `${torrent.connected_seeders} · ${torrent.active_peers} / ${torrent.total_peers}`\n}\n\nexport const shortenText = (text, sympolAmount) =>\n text ? text.slice(0, sympolAmount) + (text.length > sympolAmount ? '…' : '') : ''\n\nexport const removeRedundantCharacters = string => {\n let newString = string\n const brackets = [\n ['(', ')'],\n ['[', ']'],\n ['{', '}'],\n ]\n\n brackets.forEach(el => {\n const leftBracketRegexFormula = `\\\\${el[0]}`\n const leftBracketRegex = new RegExp(leftBracketRegexFormula, 'g')\n const leftBracketAmount = [...newString.matchAll(leftBracketRegex)].length\n const rightBracketRegexFormula = `\\\\${el[1]}`\n const rightBracketRegex = new RegExp(rightBracketRegexFormula, 'g')\n const rightBracketAmount = [...newString.matchAll(rightBracketRegex)].length\n\n if (leftBracketAmount !== rightBracketAmount) {\n const removeFormula = `(\\\\${el[0]})(?!.*\\\\1).*`\n const removeRegex = new RegExp(removeFormula, 'g')\n newString = newString.replace(removeRegex, '')\n }\n })\n\n const hasThreeDotsAtTheEnd = !!newString.match(/\\.{3}$/g)\n\n const trimmedString = newString.replace(/[\\\\.| ]+$/g, '').trim()\n\n return hasThreeDotsAtTheEnd ? `${trimmedString}..` : trimmedString\n}\n\nexport const getTorrents = async () => {\n try {\n const { data } = await axios.post(torrentsHost(), { action: 'list' })\n return data\n } catch (error) {\n throw new Error(null)\n }\n}\n","import { useTheme } from '@material-ui/core'\n\nexport const NoImageIcon = ({ color }) => {\n const primary = useTheme().palette.primary.main\n\n return (\n \n \n \n \n \n \n \n )\n}\n\nexport const AddItemIcon = () => {\n const primary = useTheme().palette.primary.main\n\n return (\n \n \n \n \n \n \n )\n}\n\nexport const USBIcon = ({ color, width }) => {\n const primary = useTheme().palette.primary.main\n\n return (\n \n \n \n \n \n \n )\n}\n\nexport const RAMIcon = ({ color, width }) => {\n const primary = useTheme().palette.primary.main\n\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n )\n}\n\nexport const TorrentIcon = () => {\n const primary = useTheme().palette.primary.main\n const secondaryColor = primary === '#00a572' ? '#74c39c' : '#4a5255'\n\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n )\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { cacheHost, settingsHost } from 'utils/Hosts'\nimport axios from 'axios'\n\nexport const useUpdateCache = hash => {\n const [cache, setCache] = useState({})\n const componentIsMounted = useRef(true)\n const timerID = useRef(null)\n\n useEffect(\n () => () => {\n // this function is required to notify \"updateCache\" when NOT to make state update\n componentIsMounted.current = false\n },\n [],\n )\n\n useEffect(() => {\n if (hash) {\n timerID.current = setInterval(() => {\n const updateCache = newCache => componentIsMounted.current && setCache(newCache)\n\n axios\n .post(cacheHost(), { action: 'get', hash })\n .then(({ data }) => updateCache(data))\n // empty cache if error\n .catch(() => updateCache({}))\n }, 100)\n } else clearInterval(timerID.current)\n\n return () => clearInterval(timerID.current)\n }, [hash])\n\n return cache\n}\n\nexport const useCreateCacheMap = cache => {\n const [cacheMap, setCacheMap] = useState([])\n\n useEffect(() => {\n const { PiecesCount, Pieces, Readers } = cache\n\n const map = []\n\n for (let i = 0; i < PiecesCount; i++) {\n const { Size, Length, Priority } = Pieces[i] || {}\n\n const newPiece = { id: i, percentage: (Size / Length) * 100 || 0, priority: Priority || 0 }\n\n Readers.forEach(r => {\n if (i === r.Reader) newPiece.isReader = true\n if (i >= r.Start && i <= r.End) newPiece.isReaderRange = true\n })\n\n map.push(newPiece)\n }\n setCacheMap(map)\n }, [cache])\n\n return cacheMap\n}\n\nexport const useGetSettings = cache => {\n const [settings, setSettings] = useState()\n useEffect(() => {\n axios.post(settingsHost(), { action: 'get' }).then(({ data }) => setSettings(data))\n }, [cache])\n\n return settings\n}\n","import { AppBar, IconButton, makeStyles, Toolbar, Typography } from '@material-ui/core'\nimport CloseIcon from '@material-ui/icons/Close'\nimport { ArrowBack } from '@material-ui/icons'\n\nconst useStyles = makeStyles({\n appBar: { position: 'relative' },\n title: { marginLeft: '5px', flex: 1 },\n})\n\nexport default function DialogHeader({ title, onClose, onBack }) {\n const classes = useStyles()\n\n return (\n \n \n {onBack && (\n \n \n \n )}\n\n \n {title}\n \n\n \n \n \n \n \n )\n}\n","import { rgba } from 'polished'\n\nexport const themeColors = {\n light: {\n app: {\n headerToggleColor: '#4db380',\n appSecondaryColor: '#cbe8d9',\n sidebarBGColor: '#575757',\n sidebarFillColor: '#dee3e5',\n },\n torrentCard: {\n accentCardColor: '#337a57',\n buttonBGColor: rgba('#337a57', 0.5),\n cardPrimaryColor: '#00a572',\n cardSecondaryColor: '#74c39c',\n },\n dialogTorrentDetailsContent: {\n posterBGColor: '#74c39c',\n gradientStartColor: '#e4f6ed',\n gradientEndColor: '#b5dec9',\n chacheSectionBGColor: '#88cdaa',\n widgetFontColor: '#fff',\n titleFontColor: '#000',\n subNameFontColor: '#7c7b7c',\n torrentFilesSectionBGColor: '#f1eff3',\n },\n detailedView: {\n gradientStartColor: '#e4f6ed',\n gradientEndColor: '#b5dec9',\n cacheSectionBGColor: '#fff',\n },\n addDialog: {\n gradientStartColor: '#e4f6ed',\n gradientEndColor: '#b5dec9',\n fontColor: '#000',\n notificationErrorBGColor: '#cda184',\n notificationSuccessBGColor: '#88cdaa',\n languageSwitchBGColor: '#74c39c',\n languageSwitchFontColor: '#e4f6ed',\n posterBGColor: '#74c39c',\n },\n torrentFunctions: {\n fontColor: '#000',\n },\n table: {\n defaultPrimaryColor: '#009879',\n defaultSecondaryColor: '#00a383',\n defaultTertiaryColor: '#03aa89',\n },\n settingsDialog: {\n contentBG: '#f1eff3',\n footerBG: '#fff',\n },\n },\n dark: {\n app: {\n headerToggleColor: '#545a5e',\n appSecondaryColor: '#545a5e',\n sidebarBGColor: '#323637',\n sidebarFillColor: '#dee3e5',\n },\n torrentCard: {\n accentCardColor: '#323637',\n buttonBGColor: rgba('#323637', 0.5),\n cardPrimaryColor: '#545a5e',\n cardSecondaryColor: rgba('#dee3e5', 0.4),\n },\n dialogTorrentDetailsContent: {\n posterBGColor: rgba('#dee3e5', 0.4),\n gradientStartColor: '#656f76',\n gradientEndColor: '#545a5e',\n chacheSectionBGColor: '#3c4244',\n widgetFontColor: rgba('#fff', 0.8),\n titleFontColor: '#f1eff3',\n subNameFontColor: '#dee3e5',\n torrentFilesSectionBGColor: rgba('#545a5e', 0.9),\n },\n detailedView: {\n gradientStartColor: '#656f76',\n gradientEndColor: '#545a5e',\n cacheSectionBGColor: '#949ca0',\n },\n addDialog: {\n gradientStartColor: '#656f76',\n gradientEndColor: '#545a5e',\n fontColor: '#fff',\n notificationErrorBGColor: '#c82e3f',\n notificationSuccessBGColor: '#323637',\n languageSwitchBGColor: '#545a5e',\n languageSwitchFontColor: '#dee3e5',\n posterBGColor: '#dee3e5',\n },\n torrentFunctions: {\n fontColor: '#f1eff3',\n },\n table: {\n defaultPrimaryColor: '#323637',\n defaultSecondaryColor: rgba('#545a5e', 0.9),\n defaultTertiaryColor: '#545a5e',\n },\n settingsDialog: {\n contentBG: '#5a6166',\n footerBG: '#323637',\n },\n },\n}\n\nexport const mainColors = {\n light: {\n primary: '#00a572',\n secondary: '#00a572',\n labels: rgba('#000', 0.9),\n },\n dark: {\n primary: '#323637',\n secondary: '#dee3e5',\n labels: rgba('#fff', 0.9),\n },\n}\n","import { createMuiTheme, useMediaQuery } from '@material-ui/core'\nimport { useEffect, useMemo, useState } from 'react'\n\nimport { mainColors } from './colors'\n\nexport const THEME_MODES = { LIGHT: 'light', DARK: 'dark', AUTO: 'auto' }\n\nconst typography = { fontFamily: 'Open Sans, sans-serif' }\n\nexport const darkTheme = createMuiTheme({\n typography,\n palette: {\n type: THEME_MODES.DARK,\n primary: { main: mainColors.dark.primary },\n secondary: { main: mainColors.dark.secondary },\n },\n})\nexport const lightTheme = createMuiTheme({\n typography,\n palette: {\n type: THEME_MODES.LIGHT,\n primary: { main: mainColors.light.primary },\n secondary: { main: mainColors.light.secondary },\n },\n})\n\nexport const useMaterialUITheme = () => {\n const savedThemeMode = localStorage.getItem('themeMode')\n const isSystemModeDark = useMediaQuery('(prefers-color-scheme: dark)')\n const [isDarkMode, setIsDarkMode] = useState(savedThemeMode === 'dark' || isSystemModeDark)\n const [currentThemeMode, setCurrentThemeMode] = useState(savedThemeMode || THEME_MODES.LIGHT)\n\n const updateThemeMode = mode => {\n setCurrentThemeMode(mode)\n localStorage.setItem('themeMode', mode)\n }\n\n useEffect(() => {\n currentThemeMode === THEME_MODES.LIGHT && setIsDarkMode(false)\n currentThemeMode === THEME_MODES.DARK && setIsDarkMode(true)\n currentThemeMode === THEME_MODES.AUTO && setIsDarkMode(isSystemModeDark)\n }, [isSystemModeDark, currentThemeMode])\n\n const theme = isDarkMode ? THEME_MODES.DARK : THEME_MODES.LIGHT\n\n const muiTheme = useMemo(\n () =>\n createMuiTheme({\n typography,\n palette: {\n type: theme,\n primary: { main: mainColors[theme].primary },\n secondary: { main: mainColors[theme].secondary },\n },\n overrides: {\n MuiInputBase: {\n input: {\n color: mainColors[theme].labels,\n },\n },\n // https://material-ui.com/ru/api/form-control-label/\n MuiFormControlLabel: {\n labelPlacementStart: {\n display: 'flex',\n justifyContent: 'space-between',\n marginStart: 0,\n marginTop: 6,\n marginBottom: 2,\n },\n },\n MuiInputLabel: {\n root: {\n color: mainColors[theme].labels,\n marginBottom: 8,\n '&$focused': {\n color: mainColors[theme].labels,\n },\n },\n },\n },\n }),\n [theme],\n )\n\n return [isDarkMode, currentThemeMode, updateThemeMode, muiTheme]\n}\n","import { rgba } from 'polished'\nimport { mainColors } from 'style/colors'\n\nexport const snakeSettings = {\n dark: {\n default: {\n borderWidth: 1,\n pieceSize: 14,\n gapBetweenPieces: 3,\n borderColor: rgba('#fff', 0.2),\n completeColor: rgba(mainColors.dark.primary, 0.5),\n backgroundColor: '#949ca0',\n progressColor: rgba('#fff', 0.2),\n readerColor: '#8f0405',\n rangeColor: '#cda184',\n },\n mini: {\n cacheMaxHeight: 340,\n borderWidth: 2,\n pieceSize: 23,\n gapBetweenPieces: 6,\n borderColor: '#5c6469',\n completeColor: '#5c6469',\n backgroundColor: '#949ca0',\n progressColor: '#949ca0',\n readerColor: '#ccc',\n rangeColor: '#cda184',\n },\n },\n light: {\n default: {\n borderWidth: 1,\n pieceSize: 14,\n gapBetweenPieces: 3,\n borderColor: '#dbf2e8',\n completeColor: mainColors.light.primary,\n backgroundColor: '#fff',\n progressColor: '#b3dfc9',\n readerColor: '#000',\n rangeColor: '#afa6e3',\n },\n mini: {\n cacheMaxHeight: 340,\n borderWidth: 2,\n pieceSize: 23,\n gapBetweenPieces: 6,\n borderColor: '#4db380',\n completeColor: '#4db380',\n backgroundColor: '#dbf2e8',\n progressColor: '#dbf2e8',\n readerColor: '#0a0a0a',\n rangeColor: '#afa6e3',\n },\n },\n}\n\nexport const createGradient = (ctx, percentage, theme, snakeType) => {\n const { pieceSize, completeColor, progressColor } = snakeSettings[theme][snakeType]\n\n const gradient = ctx.createLinearGradient(0, pieceSize, 0, 0)\n gradient.addColorStop(0, completeColor)\n gradient.addColorStop(percentage / 100, completeColor)\n gradient.addColorStop(percentage / 100, progressColor)\n gradient.addColorStop(1, progressColor)\n\n return gradient\n}\n","import styled, { css } from 'styled-components'\n\nimport { snakeSettings } from './snakeSettings'\n\nexport const ScrollNotification = styled.div`\n margin-top: 10px;\n text-transform: uppercase;\n color: rgba(0, 0, 0, 0.5);\n align-self: center;\n`\n\nexport const SnakeWrapper = styled.div`\n ${({ isMini, themeType }) => css`\n ${isMini &&\n css`\n display: grid;\n justify-content: center;\n max-height: ${snakeSettings[themeType].mini.cacheMaxHeight}px;\n overflow: auto;\n `}\n\n canvas {\n display: block;\n }\n `}\n`\n","import Measure from 'react-measure'\nimport { useState, memo, useRef, useEffect, useContext } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport isEqual from 'lodash/isEqual'\nimport { DarkModeContext } from 'components/App'\nimport { THEME_MODES } from 'style/materialUISetup'\n\nimport { useCreateCacheMap } from '../customHooks'\nimport getShortCacheMap from './getShortCacheMap'\nimport { SnakeWrapper, ScrollNotification } from './style'\nimport { createGradient, snakeSettings } from './snakeSettings'\n\nconst TorrentCache = ({ cache, isMini, isSnakeDebugMode }) => {\n const { t } = useTranslation()\n const [dimensions, setDimensions] = useState({ width: 0, height: 0 })\n const { width } = dimensions\n const canvasRef = useRef(null)\n const ctxRef = useRef(null)\n const cacheMap = useCreateCacheMap(cache)\n const settingsTarget = isMini ? 'mini' : 'default'\n const { isDarkMode } = useContext(DarkModeContext)\n const theme = isDarkMode ? THEME_MODES.DARK : THEME_MODES.LIGHT\n\n const {\n readerColor,\n rangeColor,\n borderWidth,\n pieceSize,\n gapBetweenPieces,\n backgroundColor,\n borderColor,\n cacheMaxHeight,\n completeColor,\n } = snakeSettings[theme][settingsTarget]\n\n const canvasWidth = isMini ? width * 0.93 : width\n\n const pieceSizeWithGap = pieceSize + gapBetweenPieces\n const piecesInOneRow = Math.floor(canvasWidth / pieceSizeWithGap)\n\n let shotCacheMap\n if (isMini) {\n const preloadPiecesAmount = Math.round(cache.Capacity / cache.PiecesLength - 1)\n shotCacheMap = getShortCacheMap({ cacheMap, preloadPiecesAmount, piecesInOneRow })\n }\n const source = isMini ? shotCacheMap : cacheMap\n const startingXPoint = Math.ceil((canvasWidth - pieceSizeWithGap * piecesInOneRow) / 2) // needed to center grid\n const height = Math.ceil(source.length / piecesInOneRow) * pieceSizeWithGap\n\n useEffect(() => {\n if (!canvasWidth || !height) return\n\n const canvas = canvasRef.current\n canvas.width = canvasWidth\n canvas.height = height\n ctxRef.current = canvas.getContext('2d')\n }, [canvasRef, height, canvasWidth])\n\n useEffect(() => {\n const ctx = ctxRef.current\n if (!ctx) return\n\n ctx.clearRect(0, 0, canvasWidth, height)\n\n source.forEach(({ percentage, priority, isReader, isReaderRange }, i) => {\n const inProgress = percentage > 0 && percentage < 100\n const isCompleted = percentage === 100\n const currentRow = i % piecesInOneRow\n const currentColumn = Math.floor(i / piecesInOneRow)\n const fixBlurStroke = borderWidth % 2 === 0 ? 0 : 0.5\n const requiredFix = Math.ceil(borderWidth / 2) + 1 + fixBlurStroke\n const x = currentRow * pieceSize + currentRow * gapBetweenPieces + startingXPoint + requiredFix\n const y = currentColumn * pieceSize + currentColumn * gapBetweenPieces + requiredFix\n\n ctx.lineWidth = borderWidth\n ctx.fillStyle = inProgress\n ? createGradient(ctx, percentage, theme, settingsTarget)\n : isCompleted\n ? completeColor\n : backgroundColor\n ctx.strokeStyle = isReader\n ? readerColor\n : inProgress || isCompleted\n ? completeColor\n : isReaderRange\n ? rangeColor\n : borderColor\n\n ctx.translate(x, y)\n ctx.fillRect(0, 0, pieceSize, pieceSize)\n ctx.strokeRect(0, 0, pieceSize, pieceSize)\n ctx.setTransform(1, 0, 0, 1, 0, 0)\n\n if (isSnakeDebugMode && priority > 0) {\n let info = ''\n if (priority === 1) info = ''\n else if (priority === 2) info = 'H'\n else if (priority === 3) info = 'R'\n else if (priority === 4) info = 'N'\n else if (priority === 5) info = 'A'\n ctx.font = isMini ? '13px monospace' : '10px monospace'\n const xpad = isMini ? pieceSize * 0.35 : pieceSize * 0.29\n const ypad = isMini ? pieceSize * 0.69 : pieceSize * 0.78\n ctx.fillStyle = 'black'\n ctx.fillText(info, x + xpad, y + ypad)\n }\n })\n }, [\n cacheMap,\n height,\n canvasWidth,\n piecesInOneRow,\n startingXPoint,\n pieceSize,\n gapBetweenPieces,\n source,\n backgroundColor,\n borderColor,\n borderWidth,\n settingsTarget,\n completeColor,\n readerColor,\n rangeColor,\n isMini,\n theme,\n isSnakeDebugMode,\n ])\n\n return (\n setDimensions(bounds)}>\n {({ measureRef }) => (\n
\n \n \n \n\n {isMini && height >= cacheMaxHeight && {t('ScrollDown')}}\n
\n )}\n
\n )\n}\n\nexport default memo(\n TorrentCache,\n (prev, next) => isEqual(prev.cache.Pieces, next.cache.Pieces) && isEqual(prev.cache.Readers, next.cache.Readers),\n)\n","export default ({ cacheMap, preloadPiecesAmount, piecesInOneRow }) => {\n const cacheMapWithoutEmptyBlocks = cacheMap.filter(({ percentage }) => percentage > 0)\n\n const getFullAmountOfBlocks = amountOfBlocks =>\n // this function counts existed amount of blocks with extra \"empty blocks\" to fill the row till the end\n amountOfBlocks % piecesInOneRow === 0\n ? amountOfBlocks - 1\n : amountOfBlocks + piecesInOneRow - (amountOfBlocks % piecesInOneRow) - 1 || 0\n\n const amountOfBlocksToRenderInShortView = getFullAmountOfBlocks(preloadPiecesAmount)\n // preloadPiecesAmount is counted from \"cache.Capacity / cache.PiecesLength\". We always show at least this amount of blocks\n const scalableAmountOfBlocksToRenderInShortView = getFullAmountOfBlocks(cacheMapWithoutEmptyBlocks.length)\n // cacheMap can become bigger than preloadPiecesAmount counted before. In that case we count blocks dynamically\n\n const finalAmountOfBlocksToRenderInShortView = Math.max(\n // this check is needed to decide which is the biggest amount of blocks and take it to render\n scalableAmountOfBlocksToRenderInShortView,\n amountOfBlocksToRenderInShortView,\n )\n\n const extraBlocksAmount = finalAmountOfBlocksToRenderInShortView - cacheMapWithoutEmptyBlocks.length + 1\n // amount of blocks needed to fill the line till the end\n\n const extraEmptyBlocksForFillingLine = extraBlocksAmount ? new Array(extraBlocksAmount).fill({}) : []\n\n return [...cacheMapWithoutEmptyBlocks, ...extraEmptyBlocksForFillingLine]\n}\n","import styled, { css } from 'styled-components'\n\nconst viewedPrimaryColor = '#858c90'\nconst viewedSecondaryColor = '#8c9498'\nconst viewedTertiaryColor = '#949ca0'\nconst bigTableDividerColor = '#d2d2d2'\nconst bigTableDefaultRowColor = '#f3f3f3'\nconst bigTableViewedRowColor = '#ddd'\n\nconst viewedIndicator = css`\n ${({\n theme: {\n table: { defaultPrimaryColor },\n },\n }) => css`\n :before {\n content: '';\n width: 10px;\n height: 10px;\n background: ${defaultPrimaryColor};\n border-radius: 50%;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n }\n `}\n`\nexport const TableStyle = styled.table`\n ${({\n theme: {\n table: { defaultPrimaryColor },\n },\n }) => css`\n border-collapse: collapse;\n margin: 25px 0;\n font-size: 0.9em;\n width: 100%;\n border-radius: 5px 5px 0 0;\n overflow: hidden;\n box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);\n color: #000;\n\n thead tr {\n background: ${defaultPrimaryColor};\n color: #fff;\n text-align: left;\n text-transform: uppercase;\n }\n\n th,\n td {\n padding: 12px 15px;\n }\n\n tbody tr {\n border-bottom: 1px solid ${bigTableDividerColor};\n background: ${bigTableDefaultRowColor};\n\n :last-of-type {\n border-bottom: 2px solid ${defaultPrimaryColor};\n }\n\n &.viewed-file-row {\n background: ${bigTableViewedRowColor};\n }\n }\n\n td {\n &.viewed-file-indicator {\n position: relative;\n\n ${viewedIndicator}\n }\n }\n\n .button-cell {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 10px;\n }\n\n @media (max-width: 970px) {\n display: none;\n }\n `}\n`\n\nexport const ShortTableWrapper = styled.div`\n display: grid;\n gap: 20px;\n grid-template-columns: repeat(2, 1fr);\n display: none;\n\n @media (max-width: 970px) {\n display: grid;\n }\n\n @media (max-width: 820px) {\n gap: 15px;\n grid-template-columns: 1fr;\n }\n`\n\nexport const ShortTable = styled.div`\n ${({\n isViewed,\n theme: {\n table: { defaultPrimaryColor, defaultSecondaryColor, defaultTertiaryColor },\n },\n }) => css`\n width: 100%;\n grid-template-rows: repeat(3, max-content);\n border-radius: 5px;\n overflow: hidden;\n box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);\n\n .short-table {\n &-name {\n background: ${isViewed ? viewedPrimaryColor : defaultPrimaryColor};\n display: grid;\n place-items: center;\n padding: 15px;\n color: #fff;\n text-transform: uppercase;\n font-size: 15px;\n font-weight: bold;\n\n @media (max-width: 880px) {\n font-size: 13px;\n padding: 10px;\n }\n }\n &-data {\n display: grid;\n grid-auto-flow: column;\n grid-template-columns: ${isViewed ? 'max-content' : '1fr'};\n grid-auto-columns: 1fr;\n }\n &-field {\n display: grid;\n grid-template-rows: 30px 1fr;\n background: black;\n :not(:last-child) {\n border-right: 1px solid ${isViewed ? viewedPrimaryColor : defaultPrimaryColor};\n }\n\n &-name {\n background: ${isViewed ? viewedSecondaryColor : defaultSecondaryColor};\n color: #fff;\n text-transform: uppercase;\n font-size: 12px;\n font-weight: 500;\n display: grid;\n place-items: center;\n padding: 0 10px;\n\n @media (max-width: 880px) {\n font-size: 11px;\n }\n }\n\n &-value {\n background: ${isViewed ? viewedTertiaryColor : defaultTertiaryColor};\n display: grid;\n place-items: center;\n color: #fff;\n font-size: 15px;\n padding: 15px 10px;\n position: relative;\n\n @media (max-width: 880px) {\n font-size: 13px;\n padding: 12px 8px;\n }\n }\n }\n\n &-viewed-indicator {\n ${isViewed && viewedIndicator}\n }\n\n &-buttons {\n padding: 20px;\n border-bottom: 2px solid ${isViewed ? viewedPrimaryColor : defaultPrimaryColor};\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n align-items: center;\n gap: 20px;\n background: #f3f3f3;\n\n @media (max-width: 410px) {\n gap: 10px;\n grid-template-columns: 1fr;\n }\n }\n }\n `}\n`\n","import { streamHost } from 'utils/Hosts'\nimport isEqual from 'lodash/isEqual'\nimport { humanizeSize } from 'utils/Utils'\nimport ptt from 'parse-torrent-title'\nimport { Button } from '@material-ui/core'\nimport CopyToClipboard from 'react-copy-to-clipboard'\nimport { useTranslation } from 'react-i18next'\n\nimport { TableStyle, ShortTableWrapper, ShortTable } from './style'\n\nconst { memo } = require('react')\n\n// russian episode detection support\nptt.addHandler('episode', /(\\d{1,4})[- |. ]серия|серия[- |. ](\\d{1,4})/i, { type: 'integer' })\nptt.addHandler('season', /sezon[- |. ](\\d{1,3})|(\\d{1,3})[- |. ]sezon/i, { type: 'integer' })\nptt.addHandler('season', /сезон[- |. ](\\d{1,3})|(\\d{1,3})[- |. ]сезон/i, { type: 'integer' })\n\nconst Table = memo(\n ({ playableFileList, viewedFileList, selectedSeason, seasonAmount, hash }) => {\n const { t } = useTranslation()\n const preloadBuffer = fileId => fetch(`${streamHost()}?link=${hash}&index=${fileId}&preload`)\n const getFileLink = (path, id) =>\n `${streamHost()}/${encodeURIComponent(path.split('\\\\').pop().split('/').pop())}?link=${hash}&index=${id}&play`\n const fileHasEpisodeText = !!playableFileList?.find(({ path }) => ptt.parse(path).episode)\n const fileHasSeasonText = !!playableFileList?.find(({ path }) => ptt.parse(path).season)\n const fileHasResolutionText = !!playableFileList?.find(({ path }) => ptt.parse(path).resolution)\n\n // if files in list is more then 1 and no season text detected by ptt.parse, show full name\n const shouldDisplayFullFileName = playableFileList.length > 1 && !fileHasEpisodeText\n\n return !playableFileList?.length ? (\n 'No playable files in this torrent'\n ) : (\n <>\n \n \n \n {t('Viewed')}\n {t('Name')}\n {fileHasSeasonText && seasonAmount?.length === 1 && {t('Season')}}\n {fileHasEpisodeText && {t('Episode')}}\n {fileHasResolutionText && {t('Resolution')}}\n {t('Size')}\n {t('Actions')}\n \n \n\n \n {playableFileList.map(({ id, path, length }) => {\n const { title, resolution, episode, season } = ptt.parse(path)\n const isViewed = viewedFileList?.includes(id)\n const link = getFileLink(path, id)\n\n return (\n (season === selectedSeason || !seasonAmount?.length) && (\n \n \n {shouldDisplayFullFileName ? path : title}\n {fileHasSeasonText && seasonAmount?.length === 1 && {season}}\n {fileHasEpisodeText && {episode}}\n {fileHasResolutionText && {resolution}}\n {humanizeSize(length)}\n \n
\n \n\n \n \n \n\n \n \n \n
\n \n \n )\n )\n })}\n \n
\n\n \n {playableFileList.map(({ id, path, length }) => {\n const { title, resolution, episode, season } = ptt.parse(path)\n const isViewed = viewedFileList?.includes(id)\n const link = getFileLink(path, id)\n\n return (\n (season === selectedSeason || !seasonAmount?.length) && (\n \n
{shouldDisplayFullFileName ? path : title}
\n
\n {isViewed && (\n
\n
{t('Viewed')}
\n
\n
\n
\n
\n )}\n {fileHasSeasonText && seasonAmount?.length === 1 && (\n
\n
{t('Season')}
\n
{season}
\n
\n )}\n {fileHasEpisodeText && (\n
\n
{t('Episode')}
\n
{episode}
\n
\n )}\n {fileHasResolutionText && (\n
\n
{t('Resolution')}
\n
{resolution}
\n
\n )}\n
\n
{t('Size')}
\n
{humanizeSize(length)}
\n
\n
\n
\n \n\n \n \n \n\n \n \n \n
\n \n )\n )\n })}\n \n \n )\n },\n (prev, next) => isEqual(prev, next),\n)\n\nexport default Table\n","import { rgba } from 'polished'\nimport styled, { css } from 'styled-components'\n\nexport const DialogContentGrid = styled.div`\n display: grid;\n grid-template-columns: 70% 1fr;\n grid-template-rows: repeat(2, min-content);\n grid-template-areas:\n 'main cache'\n 'file-list file-list';\n\n @media (max-width: 1450px) {\n grid-template-columns: 1fr;\n grid-template-rows: repeat(3, min-content);\n grid-template-areas:\n 'main'\n 'cache'\n 'file-list';\n }\n`\nexport const Poster = styled.div`\n ${({\n poster,\n theme: {\n dialogTorrentDetailsContent: { posterBGColor },\n },\n }) => css`\n height: 400px;\n border-radius: 5px;\n overflow: hidden;\n align-self: center;\n\n ${poster\n ? css`\n img {\n border-radius: 5px;\n height: 100%;\n }\n `\n : css`\n width: 300px;\n display: grid;\n place-items: center;\n background: ${posterBGColor};\n\n svg {\n transform: scale(2.5) translateY(-3px);\n }\n `}\n\n @media (max-width: 1280px) {\n align-self: start;\n }\n\n @media (max-width: 840px) {\n ${poster\n ? css`\n height: 200px;\n `\n : css`\n display: none;\n `}\n }\n `}\n`\nexport const MainSection = styled.section`\n ${({\n theme: {\n dialogTorrentDetailsContent: { gradientStartColor, gradientEndColor },\n },\n }) => css`\n grid-area: main;\n padding: 40px;\n display: grid;\n grid-template-columns: min-content 1fr;\n gap: 30px;\n background: linear-gradient(145deg, ${gradientStartColor}, ${gradientEndColor});\n\n @media (max-width: 840px) {\n grid-template-columns: 1fr;\n }\n\n @media (max-width: 800px) {\n padding: 20px;\n }\n `}\n`\n\nexport const CacheSection = styled.section`\n ${({\n theme: {\n dialogTorrentDetailsContent: { chacheSectionBGColor },\n },\n }) => css`\n grid-area: cache;\n padding: 40px;\n display: grid;\n align-content: start;\n grid-template-rows: min-content 1fr min-content;\n background: ${chacheSectionBGColor};\n\n @media (max-width: 800px) {\n padding: 20px;\n }\n `}\n`\n\nexport const TorrentFilesSection = styled.section`\n ${({\n theme: {\n dialogTorrentDetailsContent: { torrentFilesSectionBGColor },\n },\n }) => css`\n grid-area: file-list;\n padding: 40px;\n box-shadow: inset 3px 25px 8px -25px rgba(0, 0, 0, 0.5);\n background: ${torrentFilesSectionBGColor};\n\n @media (max-width: 800px) {\n padding: 20px;\n }\n `}\n`\n\nexport const SectionSubName = styled.div`\n ${({\n theme: {\n dialogTorrentDetailsContent: { subNameFontColor },\n },\n }) => css`\n ${({ mb }) => css`\n ${mb && `margin-top: ${mb / 3}px`};\n ${mb && `margin-bottom: ${mb}px`};\n line-height: 1.2;\n color: ${subNameFontColor};\n\n @media (max-width: 800px) {\n ${mb && `margin-top: ${mb / 4}px`};\n ${mb && `margin-bottom: ${mb / 2}px`};\n font-size: 14px;\n }\n `}\n `}\n`\n\nexport const SectionTitle = styled.div`\n ${({\n color,\n theme: {\n dialogTorrentDetailsContent: { titleFontColor },\n },\n }) => css`\n ${({ mb }) => css`\n ${mb && `margin-bottom: ${mb}px`};\n font-size: 34px;\n font-weight: 300;\n line-height: 1;\n word-break: break-word;\n color: ${color || titleFontColor};\n\n @media (max-width: 800px) {\n font-size: 24px;\n line-height: 1.1;\n ${mb && `margin-bottom: ${mb / 2}px`};\n }\n `}\n `}\n`\n\nexport const SectionHeader = styled.div`\n margin-bottom: 20px;\n`\n\nexport const WidgetWrapper = styled.div`\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(max-content, 220px));\n gap: 20px;\n\n @media (max-width: 800px) {\n gap: 15px;\n }\n @media (max-width: 410px) {\n gap: 10px;\n }\n\n ${({ detailedView }) =>\n detailedView\n ? css`\n @media (max-width: 800px) {\n grid-template-columns: repeat(2, 1fr);\n }\n @media (max-width: 410px) {\n grid-template-columns: 1fr;\n }\n `\n : css`\n @media (max-width: 800px) {\n grid-template-columns: repeat(auto-fit, minmax(max-content, 185px));\n }\n @media (max-width: 480px) {\n grid-template-columns: 1fr 1fr;\n }\n @media (max-width: 390px) {\n grid-template-columns: 1fr;\n }\n `}\n`\n\nexport const WidgetFieldWrapper = styled.div`\n display: grid;\n grid-template-columns: 40px 1fr;\n grid-template-rows: min-content 50px;\n grid-template-areas:\n 'title title'\n 'icon value';\n\n > * {\n display: grid;\n place-items: center;\n }\n\n @media (max-width: 800px) {\n grid-template-columns: 30px 1fr;\n grid-template-rows: min-content 40px;\n }\n`\nexport const WidgetFieldTitle = styled.div`\n ${({\n theme: {\n dialogTorrentDetailsContent: { titleFontColor },\n },\n }) => css`\n grid-area: title;\n justify-self: start;\n text-transform: uppercase;\n font-size: 11px;\n margin-bottom: 2px;\n font-weight: 600;\n color: ${titleFontColor};\n `}\n`\n\nexport const WidgetFieldIcon = styled.div`\n ${({ bgColor }) => css`\n grid-area: icon;\n color: ${rgba('#fff', 0.8)};\n background: ${bgColor};\n border-radius: 5px 0 0 5px;\n\n @media (max-width: 800px) {\n > svg {\n width: 50%;\n }\n }\n `}\n`\nexport const WidgetFieldValue = styled.div`\n ${({\n bgColor,\n theme: {\n dialogTorrentDetailsContent: { widgetFontColor },\n },\n }) => css`\n grid-area: value;\n font-size: 24px;\n padding: 0 20px 0 0;\n color: ${widgetFontColor};\n background: ${bgColor};\n border-radius: 0 5px 5px 0;\n white-space: nowrap;\n\n @media (max-width: 800px) {\n font-size: 18px;\n padding: 0 16px 0 0;\n }\n `}\n`\n\nexport const LoadingProgress = styled.div.attrs(\n ({\n value,\n fullAmount,\n theme: {\n dialogTorrentDetailsContent: { gradientStartColor, gradientEndColor },\n },\n }) => {\n const percentage = Math.min(100, (value * 100) / fullAmount)\n\n return {\n // this block is here according to styled-components recomendation about fast changable components\n style: {\n background: `linear-gradient(to right, ${gradientStartColor} 0%, ${gradientEndColor} ${percentage}%, #eee ${percentage}%, #fff 100%)`,\n },\n }\n },\n)`\n ${({ label }) => css`\n border: 1px solid;\n padding: 10px 20px;\n border-radius: 5px;\n color: #000;\n\n :before {\n content: '${label}';\n display: grid;\n place-items: center;\n font-size: 20px;\n }\n `}\n`\n\nexport const Divider = styled.div`\n height: 1px;\n background-color: rgba(0, 0, 0, 0.12);\n margin: 30px 0;\n`\n","import styled, { css } from 'styled-components'\n\nexport const DetailedViewWidgetSection = styled.section`\n ${({\n theme: {\n detailedView: { gradientStartColor, gradientEndColor },\n },\n }) => css`\n padding: 40px;\n background: linear-gradient(145deg, ${gradientStartColor}, ${gradientEndColor});\n\n @media (max-width: 800px) {\n padding: 20px;\n }\n `}\n`\n\nexport const DetailedViewCacheSection = styled.section`\n ${({\n theme: {\n detailedView: { cacheSectionBGColor },\n },\n }) => css`\n padding: 40px;\n box-shadow: inset 3px 25px 8px -25px rgba(0, 0, 0, 0.5);\n background: ${cacheSectionBGColor};\n flex: 1;\n\n @media (max-width: 800px) {\n padding: 20px;\n }\n `}\n`\n","import { WidgetFieldWrapper, WidgetFieldIcon, WidgetFieldValue, WidgetFieldTitle } from './style'\n\nexport default function StatisticsField({ icon: Icon, title, value, iconBg, valueBg }) {\n return (\n \n {title}\n \n \n \n\n {value}\n \n )\n}\n","import { DarkModeContext } from 'components/App'\nimport { useContext } from 'react'\nimport { THEME_MODES } from 'style/materialUISetup'\n\nconst { LIGHT, DARK } = THEME_MODES\n\nconst colors = {\n light: {\n downloadSpeed: { iconBGColor: '#118f00', valueBGColor: '#13a300' },\n uploadSpeed: { iconBGColor: '#0146ad', valueBGColor: '#0058db' },\n peers: { iconBGColor: '#cdc118', valueBGColor: '#d8cb18' },\n piecesCount: { iconBGColor: '#b6c95e', valueBGColor: '#c0d076' },\n piecesLength: { iconBGColor: '#0982c8', valueBGColor: '#098cd7' },\n status: { iconBGColor: '#aea25b', valueBGColor: '#b4aa6e' },\n size: { iconBGColor: '#9b01ad', valueBGColor: '#ac03bf' },\n },\n dark: {\n downloadSpeed: { iconBGColor: '#0c6600', valueBGColor: '#0d7000' },\n uploadSpeed: { iconBGColor: '#003f9e', valueBGColor: '#0047b3' },\n peers: { iconBGColor: '#a69c11', valueBGColor: '#b4a913' },\n piecesCount: { iconBGColor: '#8da136', valueBGColor: '#99ae3d' },\n piecesLength: { iconBGColor: '#07659c', valueBGColor: '#0872af' },\n status: { iconBGColor: '#938948', valueBGColor: '#9f9450' },\n size: { iconBGColor: '#81008f', valueBGColor: '#9102a1' },\n },\n}\n\nexport default function useGetWidgetColors(widgetName) {\n const { isDarkMode } = useContext(DarkModeContext)\n const widgetColors = colors[isDarkMode ? DARK : LIGHT][widgetName]\n\n return widgetColors\n}\n","import {\n ArrowDownward as ArrowDownwardIcon,\n ArrowUpward as ArrowUpwardIcon,\n SwapVerticalCircle as SwapVerticalCircleIcon,\n ViewAgenda as ViewAgendaIcon,\n Widgets as WidgetsIcon,\n PhotoSizeSelectSmall as PhotoSizeSelectSmallIcon,\n Build as BuildIcon,\n} from '@material-ui/icons'\nimport { getPeerString, humanizeSize, humanizeSpeed } from 'utils/Utils'\nimport { useTranslation } from 'react-i18next'\nimport { GETTING_INFO, IN_DB, CLOSED, PRELOAD, WORKING } from 'torrentStates'\n\nimport StatisticsField from '../StatisticsField'\nimport useGetWidgetColors from './useGetWidgetColors'\n\nexport const DownlodSpeedWidget = ({ data }) => {\n const { t } = useTranslation()\n const { iconBGColor, valueBGColor } = useGetWidgetColors('downloadSpeed')\n\n return (\n \n )\n}\n\nexport const UploadSpeedWidget = ({ data }) => {\n const { t } = useTranslation()\n const { iconBGColor, valueBGColor } = useGetWidgetColors('uploadSpeed')\n\n return (\n \n )\n}\n\nexport const PeersWidget = ({ data }) => {\n const { t } = useTranslation()\n const { iconBGColor, valueBGColor } = useGetWidgetColors('peers')\n\n return (\n \n )\n}\n\nexport const PiecesCountWidget = ({ data }) => {\n const { t } = useTranslation()\n const { iconBGColor, valueBGColor } = useGetWidgetColors('piecesCount')\n\n return (\n \n )\n}\n\nexport const PiecesLengthWidget = ({ data }) => {\n const { t } = useTranslation()\n const { iconBGColor, valueBGColor } = useGetWidgetColors('piecesLength')\n\n return (\n \n )\n}\n\nexport const StatusWidget = ({ stat }) => {\n const { t } = useTranslation()\n\n const values = {\n [GETTING_INFO]: t('TorrentGettingInfo'),\n [PRELOAD]: t('TorrentPreload'),\n [WORKING]: t('TorrentWorking'),\n [CLOSED]: t('TorrentClosed'),\n [IN_DB]: t('TorrentInDb'),\n }\n const { iconBGColor, valueBGColor } = useGetWidgetColors('status')\n\n return (\n \n )\n}\n\nexport const SizeWidget = ({ data }) => {\n const { t } = useTranslation()\n const { iconBGColor, valueBGColor } = useGetWidgetColors('size')\n\n return (\n \n )\n}\n","export const [GETTING_INFO, PRELOAD, WORKING, CLOSED, IN_DB] = [1, 2, 3, 4, 5]\n","import { useTranslation } from 'react-i18next'\nimport { Checkbox, FormControlLabel } from '@material-ui/core'\nimport { useState } from 'react'\n\nimport { SectionTitle, WidgetWrapper } from '../style'\nimport { DetailedViewCacheSection, DetailedViewWidgetSection } from './style'\nimport TorrentCache from '../TorrentCache'\nimport {\n SizeWidget,\n PiecesLengthWidget,\n StatusWidget,\n PiecesCountWidget,\n PeersWidget,\n UploadSpeedWidget,\n DownlodSpeedWidget,\n} from '../widgets'\n\nexport default function DetailedView({\n downloadSpeed,\n uploadSpeed,\n torrent,\n torrentSize,\n PiecesCount,\n PiecesLength,\n stat,\n cache,\n}) {\n const { t } = useTranslation()\n const [isSnakeDebugMode, setIsSnakeDebugMode] = useState(\n JSON.parse(localStorage.getItem('isSnakeDebugMode')) || false,\n )\n\n return (\n <>\n \n {t('Data')}\n\n \n \n \n \n \n \n \n \n \n \n\n \n \n
\n {t('Cache')}\n\n {\n setIsSnakeDebugMode(checked)\n localStorage.setItem('isSnakeDebugMode', checked)\n }}\n />\n }\n label={t('DebugMode')}\n labelPlacement='start'\n />\n
\n
\n\n \n
\n \n )\n}\n","import styled, { css } from 'styled-components'\n\nexport const MainSectionButtonGroup = styled.div`\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 20px;\n\n :not(:last-child) {\n margin-bottom: 30px;\n }\n\n @media (max-width: 1580px) {\n grid-template-columns: repeat(2, 1fr);\n }\n\n @media (max-width: 880px) {\n grid-template-columns: 1fr;\n }\n`\n\nexport const SmallLabel = styled.div`\n ${({\n mb,\n theme: {\n torrentFunctions: { fontColor },\n },\n }) => css`\n ${mb && `margin-bottom: ${mb}px`};\n font-size: 20px;\n font-weight: 300;\n line-height: 1;\n color: ${fontColor};\n\n @media (max-width: 800px) {\n font-size: 18px;\n ${mb && `margin-bottom: ${mb / 1.5}px`};\n }\n `}\n`\n","import axios from 'axios'\nimport { memo } from 'react'\nimport { playlistTorrHost, torrentsHost, viewedHost } from 'utils/Hosts'\nimport { CopyToClipboard } from 'react-copy-to-clipboard'\nimport { Button } from '@material-ui/core'\nimport ptt from 'parse-torrent-title'\nimport { useTranslation } from 'react-i18next'\n\nimport { SmallLabel, MainSectionButtonGroup } from './style'\nimport { SectionSubName } from '../style'\n\nconst TorrentFunctions = memo(\n ({ hash, viewedFileList, playableFileList, name, title, setViewedFileList }) => {\n const { t } = useTranslation()\n const latestViewedFileId = viewedFileList?.[viewedFileList?.length - 1]\n const latestViewedFile = playableFileList?.find(({ id }) => id === latestViewedFileId)?.path\n const isOnlyOnePlayableFile = playableFileList?.length === 1\n const latestViewedFileData = latestViewedFile && ptt.parse(latestViewedFile)\n const dropTorrent = () => axios.post(torrentsHost(), { action: 'drop', hash })\n const removeTorrentViews = () =>\n axios.post(viewedHost(), { action: 'rem', hash, file_index: -1 }).then(() => setViewedFileList())\n const fullPlaylistLink = `${playlistTorrHost()}/${encodeURIComponent(name || title || 'file')}.m3u?link=${hash}&m3u`\n const partialPlaylistLink = `${fullPlaylistLink}&fromlast`\n\n return (\n <>\n {!isOnlyOnePlayableFile && !!viewedFileList?.length && (\n <>\n {t('DownloadPlaylist')}\n \n {t('LatestFilePlayed')}{' '}\n \n {latestViewedFileData?.title}.\n {latestViewedFileData?.season && (\n <>\n {' '}\n {t('Season')}: {latestViewedFileData?.season}. {t('Episode')}: {latestViewedFileData?.episode}.\n \n )}\n \n \n\n \n \n \n \n\n \n \n \n \n \n )}\n {t('TorrentState')}\n \n \n \n \n {t('Info')}\n \n {(isOnlyOnePlayableFile || !viewedFileList?.length) && (\n \n \n \n )}\n \n \n \n \n \n )\n },\n () => true,\n)\n\nexport default TorrentFunctions\n","const getExt = filename => {\n const ext = filename.split('.').pop()\n if (ext === filename) return ''\n return ext.toLowerCase()\n}\nconst playableExtList = [\n // video\n '3g2',\n '3gp',\n 'aaf',\n 'asf',\n 'avchd',\n 'avi',\n 'drc',\n 'flv',\n 'iso',\n 'm2v',\n 'm2ts',\n 'm4p',\n 'm4v',\n 'mkv',\n 'mng',\n 'mov',\n 'mp2',\n 'mp4',\n 'mpe',\n 'mpeg',\n 'mpg',\n 'mpv',\n 'mxf',\n 'nsv',\n 'ogg',\n 'ogv',\n 'ts',\n 'qt',\n 'rm',\n 'rmvb',\n 'roq',\n 'svi',\n 'vob',\n 'webm',\n 'wmv',\n 'yuv',\n // audio\n 'aac',\n 'aiff',\n 'ape',\n 'au',\n 'flac',\n 'gsm',\n 'it',\n 'm3u',\n 'm4a',\n 'mid',\n 'mod',\n 'mp3',\n 'mpa',\n 'pls',\n 'ra',\n 's3m',\n 'sid',\n 'wav',\n 'wma',\n 'xm',\n]\n\n// eslint-disable-next-line import/prefer-default-export\nexport const isFilePlayable = fileName => playableExtList.includes(getExt(fileName))\n","import { NoImageIcon } from 'icons'\nimport { humanizeSize, removeRedundantCharacters } from 'utils/Utils'\nimport { useEffect, useState } from 'react'\nimport { Button, ButtonGroup } from '@material-ui/core'\nimport ptt from 'parse-torrent-title'\nimport axios from 'axios'\nimport { viewedHost } from 'utils/Hosts'\nimport { GETTING_INFO, IN_DB } from 'torrentStates'\nimport CircularProgress from '@material-ui/core/CircularProgress'\nimport { useTranslation } from 'react-i18next'\n\nimport { useUpdateCache, useGetSettings } from './customHooks'\nimport DialogHeader from './DialogHeader'\nimport TorrentCache from './TorrentCache'\nimport Table from './Table'\nimport DetailedView from './DetailedView'\nimport {\n DialogContentGrid,\n MainSection,\n Poster,\n SectionTitle,\n SectionSubName,\n WidgetWrapper,\n LoadingProgress,\n SectionHeader,\n CacheSection,\n TorrentFilesSection,\n Divider,\n} from './style'\nimport { DownlodSpeedWidget, UploadSpeedWidget, PeersWidget, SizeWidget, StatusWidget } from './widgets'\nimport TorrentFunctions from './TorrentFunctions'\nimport { isFilePlayable } from './helpers'\n\nconst Loader = () => (\n
\n \n
\n)\n\nexport default function DialogTorrentDetailsContent({ closeDialog, torrent }) {\n const { t } = useTranslation()\n const [isLoading, setIsLoading] = useState(true)\n const [isDetailedCacheView, setIsDetailedCacheView] = useState(false)\n const [viewedFileList, setViewedFileList] = useState()\n const [playableFileList, setPlayableFileList] = useState()\n const [seasonAmount, setSeasonAmount] = useState(null)\n const [selectedSeason, setSelectedSeason] = useState()\n const [isSnakeDebugMode] = useState(JSON.parse(localStorage.getItem('isSnakeDebugMode')) || false)\n\n const {\n poster,\n hash,\n title,\n name,\n stat,\n download_speed: downloadSpeed,\n upload_speed: uploadSpeed,\n torrent_size: torrentSize,\n file_stats: torrentFileList,\n } = torrent\n\n const cache = useUpdateCache(hash)\n const settings = useGetSettings(cache)\n\n const { Capacity, PiecesCount, PiecesLength, Filled } = cache\n\n useEffect(() => {\n if (playableFileList && seasonAmount === null) {\n const seasons = []\n playableFileList.forEach(({ path }) => {\n const currentSeason = ptt.parse(path).season\n if (currentSeason) {\n !seasons.includes(currentSeason) && seasons.push(currentSeason)\n }\n })\n seasons.length && setSelectedSeason(seasons[0])\n setSeasonAmount(seasons.sort((a, b) => a - b))\n }\n }, [playableFileList, seasonAmount])\n\n useEffect(() => {\n setPlayableFileList(torrentFileList?.filter(({ path }) => isFilePlayable(path)))\n }, [torrentFileList])\n\n useEffect(() => {\n const cacheLoaded = !!Object.entries(cache).length\n const torrentLoaded = stat !== GETTING_INFO && stat !== IN_DB\n\n if (!cacheLoaded && !isLoading) setIsLoading(true)\n if (cacheLoaded && isLoading && torrentLoaded) setIsLoading(false)\n }, [stat, cache, isLoading])\n\n useEffect(() => {\n // getting viewed file list\n axios.post(viewedHost(), { action: 'list', hash }).then(({ data }) => {\n if (data) {\n const lst = data.map(itm => itm.file_index).sort((a, b) => a - b)\n setViewedFileList(lst)\n } else setViewedFileList()\n })\n }, [hash])\n\n const preloadPerc = settings?.PreloadCache\n const preloadSize = (Capacity / 100) * preloadPerc\n const bufferSize = preloadSize > 33554432 ? preloadSize : 33554432 // Not less than 32MB\n\n const getParsedTitle = () => {\n const newNameStringArr = []\n\n const torrentParsedName = name && ptt.parse(name)\n\n if (title !== name) {\n newNameStringArr.push(removeRedundantCharacters(title))\n } else if (torrentParsedName?.title) newNameStringArr.push(removeRedundantCharacters(torrentParsedName?.title))\n\n // These 2 checks are needed to get year and resolution from torrent name if title does not have this info\n if (torrentParsedName?.year && !newNameStringArr[0].includes(torrentParsedName?.year))\n newNameStringArr.push(torrentParsedName?.year)\n if (torrentParsedName?.resolution && !newNameStringArr[0].includes(torrentParsedName?.resolution))\n newNameStringArr.push(torrentParsedName?.resolution)\n\n const newNameString = newNameStringArr.join('. ')\n\n // removeRedundantCharacters is returning \"..\" if it was \"...\"\n const lastDotShouldBeAdded =\n newNameString[newNameString.length - 1] === '.' && newNameString[newNameString.length - 2] === '.'\n\n return lastDotShouldBeAdded ? `${newNameString}.` : newNameString\n }\n\n return (\n <>\n setIsDetailedCacheView(false) })}\n />\n\n \n {isLoading ? (\n \n ) : isDetailedCacheView ? (\n \n ) : (\n \n \n {poster ? poster : }\n\n
\n {title && name !== title ? (\n getParsedTitle().length > 90 ? (\n <>\n {ptt.parse(name).title}\n {getParsedTitle()}\n \n ) : (\n <>\n {getParsedTitle()}\n {ptt.parse(name || '')?.title}\n \n )\n ) : (\n {getParsedTitle()}\n )}\n\n \n \n \n \n \n \n \n\n \n\n \n
\n
\n\n \n \n {t('Buffer')}\n {bufferSize <= 33554432 && {t('BufferNote')}}\n \n \n\n \n setIsDetailedCacheView(true)}\n >\n {t('DetailedCacheView.button')}\n \n \n\n \n {t('TorrentContent')}\n\n {seasonAmount?.length > 1 && (\n <>\n {t('SelectSeason')}\n \n {seasonAmount.map(season => (\n setSelectedSeason(season)}\n >\n {season}\n \n ))}\n \n\n \n {t('Season')} {selectedSeason}\n \n \n )}\n\n \n \n
\n )}\n
\n \n )\n}\n","import { useTranslation } from 'react-i18next'\n\nexport default () => {\n const { i18n } = useTranslation()\n const currentLanguage = i18n.language.substr(0, 2)\n\n return [currentLanguage, lang => i18n.changeLanguage(lang)]\n}\n","import { useEffect, useRef } from 'react'\n\nexport default function usePreviousState(value) {\n const ref = useRef(value)\n\n useEffect(() => {\n ref.current = value\n }, [value])\n\n return ref.current\n}\n","import styled, { css } from 'styled-components'\n\nexport const Header = styled.div`\n ${({ theme: { primary } }) => css`\n background: ${primary};\n color: rgba(0, 0, 0, 0.87);\n font-size: 20px;\n color: #fff;\n font-weight: 600;\n box-shadow: 0px 2px 4px -1px rgb(0 0 0 / 20%), 0px 4px 5px 0px rgb(0 0 0 / 14%), 0px 1px 10px 0px rgb(0 0 0 / 12%);\n padding: 15px 24px;\n position: relative;\n `}\n`\n\nexport const ButtonWrapper = styled.div`\n padding: 20px;\n display: flex;\n justify-content: flex-end;\n\n > :not(:last-child) {\n margin-right: 10px;\n }\n`\n","import axios from 'axios'\nimport parseTorrent from 'parse-torrent'\nimport ptt from 'parse-torrent-title'\n\nexport const getMoviePosters = (movieName, language = 'en') => {\n const url = 'http://api.themoviedb.org/3/search/multi'\n\n return axios\n .get(url, {\n params: {\n api_key: process.env.REACT_APP_TMDB_API_KEY,\n language,\n include_image_language: `${language},null,en`,\n query: movieName,\n },\n })\n .then(({ data: { results } }) =>\n results.filter(el => el.poster_path).map(el => `https://image.tmdb.org/t/p/w300${el.poster_path}`),\n )\n .catch(() => null)\n}\n\nexport const checkImageURL = async url => {\n if (!url || !url.match(/.(jpg|jpeg|png|gif)$/i)) return false\n return true\n}\n\nconst magnetRegex = /^magnet:\\?xt=urn:[a-z0-9].*/i\nexport const hashRegex = /^\\b[0-9a-f]{32}\\b$|^\\b[0-9a-f]{40}\\b$|^\\b[0-9a-f]{64}\\b$/i\nconst torrentRegex = /^.*\\.(torrent)$/i\nconst linkRegex = /^(http(s?)):\\/\\/.*/i\n\nexport const checkTorrentSource = source =>\n source.match(hashRegex) !== null ||\n source.match(magnetRegex) !== null ||\n source.match(torrentRegex) !== null ||\n source.match(linkRegex) !== null\n\nexport const parseTorrentTitle = (parsingSource, callback) => {\n parseTorrent.remote(parsingSource, (err, { name, files } = {}) => {\n if (!name || err) return callback({ parsedTitle: null, originalName: null })\n\n const torrentName = ptt.parse(name).title\n const nameOfFileInsideTorrent = files ? ptt.parse(files[0].name).title : null\n\n let newTitle = torrentName\n if (nameOfFileInsideTorrent) {\n // taking shorter title because in most cases it is more accurate\n newTitle = torrentName.length < nameOfFileInsideTorrent.length ? torrentName : nameOfFileInsideTorrent\n }\n\n callback({ parsedTitle: newTitle, originalName: name })\n })\n}\n","import { Button } from '@material-ui/core'\nimport styled, { css } from 'styled-components'\n\nexport const Content = styled.div`\n ${({\n isEditMode,\n theme: {\n addDialog: { gradientStartColor, gradientEndColor, fontColor },\n },\n }) => css`\n height: 550px;\n background: linear-gradient(145deg, ${gradientStartColor}, ${gradientEndColor});\n flex: 1;\n display: grid;\n grid-template-columns: repeat(${isEditMode ? '1' : '2'}, 1fr);\n border-bottom: 1px solid rgba(0, 0, 0, 0.12);\n overflow: auto;\n color: ${fontColor};\n\n @media (max-width: 540px) {\n ${'' /* Just for bug fixing on small screens */}\n overflow: scroll;\n }\n\n @media (max-width: 930px) {\n grid-template-columns: 1fr;\n }\n\n @media (max-width: 500px) {\n align-content: start;\n }\n `}\n`\n\nexport const RightSide = styled.div`\n padding: 0 20px 20px 20px;\n`\n\nexport const RightSideContainer = styled.div`\n ${({\n isHidden,\n notificationMessage,\n isError,\n theme: {\n addDialog: { notificationErrorBGColor, notificationSuccessBGColor },\n },\n }) => css`\n height: 530px;\n\n ${notificationMessage &&\n css`\n position: relative;\n white-space: nowrap;\n\n :before {\n font-size: 20px;\n font-weight: 300;\n content: '${notificationMessage}';\n display: grid;\n place-items: center;\n background: ${isError ? notificationErrorBGColor : notificationSuccessBGColor};\n padding: 10px 15px;\n position: absolute;\n top: 52%;\n left: 50%;\n transform: translate(-50%, -50%);\n border-radius: 5px;\n }\n `};\n\n ${isHidden &&\n css`\n display: none;\n `};\n\n @media (max-width: 500px) {\n height: 170px;\n }\n `}\n`\nexport const LeftSide = styled.div`\n display: flex;\n flex-direction: column;\n border-right: 1px solid rgba(0, 0, 0, 0.12);\n`\n\nexport const LeftSideBottomSectionBasicStyles = css`\n transition: transform 0.3s;\n padding: 20px;\n height: 100%;\n display: grid;\n`\n\nexport const LeftSideBottomSectionNoFile = styled.div`\n ${LeftSideBottomSectionBasicStyles}\n border: 4px dashed rgba(0,0,0,0.1);\n text-align: center;\n\n ${({ isDragActive }) => isDragActive && `border: 4px dashed green`};\n\n justify-items: center;\n grid-template-rows: 130px 1fr;\n cursor: pointer;\n\n :hover {\n background-color: rgba(0, 0, 0, 0.04);\n svg {\n transform: translateY(-4%);\n }\n }\n\n @media (max-width: 930px) {\n border: 4px dashed transparent;\n height: 400px;\n place-items: center;\n grid-template-rows: 40% 1fr;\n }\n\n @media (max-width: 500px) {\n height: 170px;\n grid-template-rows: 1fr;\n\n > div:first-of-type {\n display: none;\n }\n }\n`\n\nexport const LeftSideBottomSectionFileSelected = styled.div`\n ${LeftSideBottomSectionBasicStyles}\n place-items: center;\n\n @media (max-width: 930px) {\n height: 400px;\n }\n\n @media (max-width: 500px) {\n height: 170px;\n }\n`\n\nexport const TorrentIconWrapper = styled.div`\n position: relative;\n`\n\nexport const CancelIconWrapper = styled.div`\n position: absolute;\n top: -9px;\n left: 10px;\n cursor: pointer;\n\n > svg {\n transition: all 0.3s;\n fill: rgba(0, 0, 0, 0.7);\n\n :hover {\n fill: rgba(0, 0, 0, 0.6);\n }\n }\n`\n\nexport const IconWrapper = styled.div`\n display: grid;\n justify-items: center;\n align-content: start;\n gap: 10px;\n align-self: start;\n\n svg {\n transition: all 0.3s;\n }\n`\n\nexport const LeftSideTopSection = styled.div`\n ${({\n active,\n theme: {\n addDialog: { gradientStartColor },\n },\n }) => css`\n background: ${gradientStartColor};\n padding: 0 20px 20px 20px;\n transition: all 0.3s;\n\n ${active && 'box-shadow: 0 8px 10px -9px rgba(0, 0, 0, 0.5)'};\n `}\n`\n\nexport const PosterWrapper = styled.div`\n margin-top: 20px;\n display: grid;\n grid-template-columns: max-content 1fr;\n grid-template-rows: 300px max-content;\n column-gap: 5px;\n position: relative;\n margin-bottom: 20px;\n\n grid-template-areas:\n 'poster suggestions'\n 'clear empty';\n\n @media (max-width: 540px) {\n grid-template-columns: 1fr;\n gap: 5px 0;\n justify-items: center;\n grid-template-areas:\n 'poster'\n 'clear'\n 'suggestions';\n }\n`\n\nexport const PosterSuggestions = styled.div`\n display: grid;\n grid-area: suggestions;\n grid-auto-flow: column;\n grid-template-columns: repeat(3, max-content);\n grid-template-rows: repeat(4, max-content);\n gap: 5px;\n\n @media (max-width: 540px) {\n grid-auto-flow: row;\n grid-template-columns: repeat(5, max-content);\n }\n @media (max-width: 375px) {\n grid-template-columns: repeat(4, max-content);\n }\n`\n\nexport const PosterSuggestionsItem = styled.div`\n cursor: pointer;\n width: 71px;\n height: 71px;\n\n @media (max-width: 430px) {\n width: 60px;\n height: 60px;\n }\n\n @media (max-width: 375px) {\n width: 71px;\n height: 71px;\n }\n\n @media (max-width: 355px) {\n width: 60px;\n height: 60px;\n }\n\n img {\n transition: all 0.3s;\n border-radius: 5px;\n width: 100%;\n height: 100%;\n object-fit: cover;\n\n :hover {\n filter: brightness(130%);\n }\n }\n`\n\nexport const Poster = styled.div`\n ${({\n poster,\n theme: {\n addDialog: { posterBGColor },\n },\n }) => css`\n border-radius: 5px;\n overflow: hidden;\n width: 200px;\n grid-area: poster;\n\n ${poster\n ? css`\n img {\n width: 200px;\n object-fit: cover;\n border-radius: 5px;\n height: 100%;\n }\n `\n : css`\n display: grid;\n place-items: center;\n background: ${posterBGColor};\n\n svg {\n transform: scale(1.5) translateY(-3px);\n }\n `}\n `}\n`\n\nexport const ClearPosterButton = styled(Button)`\n grid-area: clear;\n justify-self: center;\n transform: translateY(-50%);\n position: absolute;\n ${({ showbutton }) => !showbutton && 'display: none'};\n\n @media (max-width: 540px) {\n transform: translateY(-140%);\n }\n`\n\nexport const PosterLanguageSwitch = styled.div`\n ${({\n showbutton,\n theme: {\n addDialog: { languageSwitchBGColor, languageSwitchFontColor },\n },\n }) => css`\n grid-area: poster;\n z-index: 5;\n position: absolute;\n top: 0;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 30px;\n height: 30px;\n background: ${languageSwitchBGColor};\n border-radius: 50%;\n display: grid;\n place-items: center;\n color: ${languageSwitchFontColor};\n font-weight: 600;\n cursor: pointer;\n transition: all 0.3s;\n\n ${!showbutton && 'display: none'};\n\n :hover {\n filter: brightness(1.1);\n }\n `}\n`\n","import { useTranslation } from 'react-i18next'\nimport { rgba } from 'polished'\nimport { NoImageIcon } from 'icons'\nimport { IconButton, InputAdornment, TextField, useTheme } from '@material-ui/core'\nimport { HighlightOff as HighlightOffIcon } from '@material-ui/icons'\n\nimport {\n ClearPosterButton,\n PosterLanguageSwitch,\n RightSide,\n Poster,\n PosterSuggestions,\n PosterSuggestionsItem,\n PosterWrapper,\n RightSideContainer,\n} from './style'\nimport { checkImageURL } from './helpers'\n\nexport default function RightSideComponent({\n setTitle,\n setPosterUrl,\n setIsPosterUrlCorrect,\n setIsUserInteractedWithPoster,\n setPosterList,\n isTorrentSourceCorrect,\n isHashAlreadyExists,\n title,\n parsedTitle,\n posterUrl,\n isPosterUrlCorrect,\n posterList,\n currentLang,\n posterSearchLanguage,\n setPosterSearchLanguage,\n posterSearch,\n removePoster,\n torrentSource,\n originalTorrentTitle,\n updateTitleFromSource,\n isCustomTitleEnabled,\n setIsCustomTitleEnabled,\n isEditMode,\n}) {\n const { t } = useTranslation()\n const primary = useTheme().palette.primary.main\n\n const handleTitleChange = ({ target: { value } }) => setTitle(value)\n const handlePosterUrlChange = ({ target: { value } }) => {\n setPosterUrl(value)\n checkImageURL(value).then(setIsPosterUrlCorrect)\n setIsUserInteractedWithPoster(!!value)\n setPosterList()\n }\n const userChangesPosterUrl = url => {\n setPosterUrl(url)\n checkImageURL(url).then(setIsPosterUrlCorrect)\n setIsUserInteractedWithPoster(true)\n }\n\n return (\n \n \n {originalTorrentTitle ? (\n <>\n \n setIsCustomTitleEnabled(true)}\n onBlur={({ target: { value } }) => !value && setIsCustomTitleEnabled(false)}\n value={title}\n margin='dense'\n label={t('AddDialog.CustomTorrentTitle')}\n type='text'\n fullWidth\n helperText={t('AddDialog.CustomTorrentTitleHelperText')}\n InputProps={{\n endAdornment: (\n \n {\n setTitle('')\n setIsCustomTitleEnabled(!isCustomTitleEnabled)\n updateTitleFromSource()\n setIsUserInteractedWithPoster(false)\n }}\n >\n \n \n \n ),\n }}\n />\n \n ) : (\n \n )}\n \n\n \n \n {isPosterUrlCorrect ? poster : }\n \n\n \n {posterList\n ?.filter(url => url !== posterUrl)\n .slice(0, 12)\n .map(url => (\n userChangesPosterUrl(url)} key={url}>\n poster\n \n ))}\n \n\n {currentLang !== 'en' && (\n {\n const newLanguage = posterSearchLanguage === 'en' ? 'ru' : 'en'\n setPosterSearchLanguage(newLanguage)\n posterSearch(isCustomTitleEnabled ? title : originalTorrentTitle ? parsedTitle : title, newLanguage, {\n shouldRefreshMainPoster: true,\n })\n }}\n showbutton={+isPosterUrlCorrect}\n color='primary'\n variant='contained'\n size='small'\n >\n {posterSearchLanguage === 'en' ? 'EN' : 'RU'}\n \n )}\n\n {\n removePoster()\n setIsUserInteractedWithPoster(true)\n }}\n color='primary'\n variant='contained'\n size='small'\n >\n {t('Clear')}\n \n \n \n\n \n \n )\n}\n","import { useTranslation } from 'react-i18next'\nimport { useDropzone } from 'react-dropzone'\nimport { AddItemIcon, TorrentIcon } from 'icons'\nimport TextField from '@material-ui/core/TextField'\nimport { Cancel as CancelIcon } from '@material-ui/icons'\nimport { useState } from 'react'\n\nimport {\n CancelIconWrapper,\n IconWrapper,\n LeftSide,\n LeftSideBottomSectionFileSelected,\n LeftSideBottomSectionNoFile,\n LeftSideTopSection,\n TorrentIconWrapper,\n} from './style'\n\nexport default function LeftSideComponent({\n setIsUserInteractedWithPoster,\n setSelectedFile,\n torrentSource,\n setTorrentSource,\n selectedFile,\n}) {\n const { t } = useTranslation()\n\n const handleCapture = files => {\n const [file] = files\n if (!file) return\n\n setIsUserInteractedWithPoster(false)\n setSelectedFile(file)\n setTorrentSource(file.name)\n }\n\n const clearSelectedFile = () => {\n setSelectedFile()\n setTorrentSource('')\n }\n\n const [isTorrentSourceActive, setIsTorrentSourceActive] = useState(false)\n const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop: handleCapture, accept: '.torrent' })\n\n const handleTorrentSourceChange = ({ target: { value } }) => setTorrentSource(value)\n\n return (\n \n \n setIsTorrentSourceActive(true)}\n onBlur={() => setIsTorrentSourceActive(false)}\n inputProps={{ autoComplete: 'off' }}\n disabled={!!selectedFile}\n />\n \n\n {selectedFile ? (\n \n \n \n\n \n \n \n \n \n ) : (\n \n \n
{t('AddDialog.AppendFile.Or')}
\n\n \n \n
{t('AddDialog.AppendFile.ClickOrDrag')}
\n
\n
\n )}\n
\n )\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react'\nimport Button from '@material-ui/core/Button'\nimport Dialog from '@material-ui/core/Dialog'\nimport { torrentsHost, torrentUploadHost } from 'utils/Hosts'\nimport axios from 'axios'\nimport { useTranslation } from 'react-i18next'\nimport debounce from 'lodash/debounce'\nimport useChangeLanguage from 'utils/useChangeLanguage'\nimport { useMediaQuery } from '@material-ui/core'\nimport CircularProgress from '@material-ui/core/CircularProgress'\nimport usePreviousState from 'utils/usePreviousState'\nimport { useQuery } from 'react-query'\nimport { getTorrents } from 'utils/Utils'\nimport parseTorrent from 'parse-torrent'\nimport { ButtonWrapper, Header } from 'style/DialogStyles'\n\nimport { checkImageURL, getMoviePosters, checkTorrentSource, parseTorrentTitle } from './helpers'\nimport { Content } from './style'\nimport RightSideComponent from './RightSideComponent'\nimport LeftSideComponent from './LeftSideComponent'\n\nexport default function AddDialog({\n handleClose,\n hash: originalHash,\n title: originalTitle,\n name: originalName,\n poster: originalPoster,\n}) {\n const { t } = useTranslation()\n const isEditMode = !!originalHash\n const [torrentSource, setTorrentSource] = useState(originalHash || '')\n const [title, setTitle] = useState(originalTitle || '')\n const [originalTorrentTitle, setOriginalTorrentTitle] = useState('')\n const [parsedTitle, setParsedTitle] = useState('')\n const [posterUrl, setPosterUrl] = useState(originalPoster || '')\n const [isPosterUrlCorrect, setIsPosterUrlCorrect] = useState(false)\n const [isTorrentSourceCorrect, setIsTorrentSourceCorrect] = useState(false)\n const [isHashAlreadyExists, setIsHashAlreadyExists] = useState(false)\n const [posterList, setPosterList] = useState()\n const [isUserInteractedWithPoster, setIsUserInteractedWithPoster] = useState(isEditMode)\n const [currentLang] = useChangeLanguage()\n const [selectedFile, setSelectedFile] = useState()\n const [posterSearchLanguage, setPosterSearchLanguage] = useState(currentLang === 'ru' ? 'ru' : 'en')\n const [isSaving, setIsSaving] = useState(false)\n const [skipDebounce, setSkipDebounce] = useState(false)\n const [isCustomTitleEnabled, setIsCustomTitleEnabled] = useState(false)\n const [currentSourceHash, setCurrentSourceHash] = useState()\n\n const { data: torrents } = useQuery('torrents', getTorrents, { retry: 1, refetchInterval: 1000 })\n\n useEffect(() => {\n // getting hash from added torrent source\n parseTorrent.remote(selectedFile || torrentSource, (_, { infoHash } = {}) => setCurrentSourceHash(infoHash))\n }, [selectedFile, torrentSource])\n\n useEffect(() => {\n // checking if torrent already exists in DB\n if (!setCurrentSourceHash) return\n\n const allHashes = torrents.map(({ hash }) => hash)\n setIsHashAlreadyExists(allHashes.includes(currentSourceHash))\n }, [currentSourceHash, torrents])\n\n useEffect(() => {\n // closing dialog when torrent successfully added in DB\n if (!isSaving) return\n\n const allHashes = torrents.map(({ hash }) => hash)\n allHashes.includes(currentSourceHash) && handleClose()\n // FIXME! check api reply on add links\n const linkRegex = /^(http(s?)):\\/\\/.*/i\n torrentSource.match(linkRegex) !== null && handleClose()\n }, [isSaving, torrents, torrentSource, currentSourceHash, handleClose])\n\n const fullScreen = useMediaQuery('@media (max-width:930px)')\n\n const updateTitleFromSource = useCallback(() => {\n parseTorrentTitle(selectedFile || torrentSource, ({ parsedTitle, originalName }) => {\n if (!originalName) return\n\n setSkipDebounce(true)\n setTitle('')\n setIsCustomTitleEnabled(false)\n setOriginalTorrentTitle(originalName)\n setParsedTitle(parsedTitle)\n })\n }, [selectedFile, torrentSource])\n\n useEffect(() => {\n if (!selectedFile && !torrentSource) {\n setTitle('')\n setOriginalTorrentTitle('')\n setParsedTitle('')\n setIsCustomTitleEnabled(false)\n setPosterList()\n removePoster()\n setIsUserInteractedWithPoster(false)\n }\n }, [selectedFile, torrentSource])\n\n const removePoster = () => {\n setIsPosterUrlCorrect(false)\n setPosterUrl('')\n }\n\n useEffect(() => {\n if (originalHash) {\n checkImageURL(posterUrl).then(correctImage => {\n correctImage ? setIsPosterUrlCorrect(true) : removePoster()\n })\n }\n // This is needed only on mount. Do not remove line below\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const posterSearch = useMemo(\n () =>\n (movieName, language, { shouldRefreshMainPoster = false } = {}) => {\n if (!movieName) {\n setPosterList()\n removePoster()\n return\n }\n\n getMoviePosters(movieName, language).then(urlList => {\n if (urlList) {\n setPosterList(urlList)\n if (!shouldRefreshMainPoster && isUserInteractedWithPoster) return\n\n const [firstPoster] = urlList\n checkImageURL(firstPoster).then(correctImage => {\n if (correctImage) {\n setIsPosterUrlCorrect(true)\n setPosterUrl(firstPoster)\n } else removePoster()\n })\n } else {\n setPosterList()\n if (isUserInteractedWithPoster) return\n\n removePoster()\n }\n })\n },\n [isUserInteractedWithPoster],\n )\n\n const delayedPosterSearch = useMemo(() => debounce(posterSearch, 700), [posterSearch])\n\n const prevTorrentSourceState = usePreviousState(torrentSource)\n\n useEffect(() => {\n const isCorrectSource = checkTorrentSource(torrentSource)\n if (!isCorrectSource) return setIsTorrentSourceCorrect(false)\n\n setIsTorrentSourceCorrect(true)\n\n // if torrentSource is updated then we are getting title from the source\n const torrentSourceChanged = torrentSource !== prevTorrentSourceState\n if (!torrentSourceChanged) return\n\n updateTitleFromSource()\n }, [prevTorrentSourceState, selectedFile, torrentSource, updateTitleFromSource])\n\n const prevTitleState = usePreviousState(title)\n\n useEffect(() => {\n // if title exists and title was changed then search poster.\n const titleChanged = title !== prevTitleState\n if (!titleChanged && !parsedTitle) return\n\n if (skipDebounce) {\n posterSearch(title || parsedTitle, posterSearchLanguage)\n setSkipDebounce(false)\n } else if (!title) {\n delayedPosterSearch.cancel()\n\n if (parsedTitle) {\n posterSearch(parsedTitle, posterSearchLanguage)\n } else {\n !isUserInteractedWithPoster && removePoster()\n }\n } else {\n delayedPosterSearch(title, posterSearchLanguage)\n }\n }, [\n title,\n parsedTitle,\n prevTitleState,\n delayedPosterSearch,\n posterSearch,\n posterSearchLanguage,\n skipDebounce,\n isUserInteractedWithPoster,\n ])\n\n const handleSave = () => {\n setIsSaving(true)\n\n if (isEditMode) {\n axios\n .post(torrentsHost(), {\n action: 'set',\n hash: originalHash,\n title: title || originalName,\n poster: posterUrl,\n })\n .finally(handleClose)\n } else if (selectedFile) {\n // file save\n const data = new FormData()\n data.append('save', 'true')\n data.append('file', selectedFile)\n title && data.append('title', title)\n posterUrl && data.append('poster', posterUrl)\n axios.post(torrentUploadHost(), data).catch(handleClose)\n } else {\n // link save\n axios\n .post(torrentsHost(), { action: 'add', link: torrentSource, title, poster: posterUrl, save_to_db: true })\n .catch(handleClose)\n }\n }\n\n return (\n \n
{t(isEditMode ? 'EditTorrent' : 'AddNewTorrent')}
\n\n \n {!isEditMode && (\n \n )}\n\n \n \n\n \n \n\n \n {isSaving ? : t(isEditMode ? 'Save' : 'Add')}\n \n \n
\n )\n}\n","import styled, { css } from 'styled-components'\n\nexport const TorrentCard = styled.div`\n ${({\n theme: {\n torrentCard: { cardPrimaryColor },\n },\n }) => css`\n border-radius: 5px;\n display: grid;\n grid-template-columns: 120px 260px 1fr;\n grid-template-rows: 180px;\n grid-template-areas: 'poster description buttons';\n gap: 10px;\n padding: 10px;\n background: ${cardPrimaryColor};\n box-shadow: 0px 2px 4px -1px rgb(0 0 0 / 20%), 0px 4px 5px 0px rgb(0 0 0 / 14%), 0px 1px 10px 0px rgb(0 0 0 / 12%);\n\n @media (max-width: 1260px), (max-height: 500px) {\n grid-template-areas:\n 'poster description'\n 'buttons buttons';\n\n grid-template-columns: 70px 1fr;\n grid-template-rows: 110px max-content;\n }\n\n @media (max-width: 770px) {\n grid-template-columns: 60px 1fr;\n grid-template-rows: 90px max-content;\n }\n `}\n`\n\nexport const TorrentCardPoster = styled.div`\n grid-area: poster;\n border-radius: 5px;\n overflow: hidden;\n text-align: center;\n cursor: pointer;\n transition: 0.2s;\n position: relative;\n\n :hover {\n filter: brightness(0.7);\n }\n\n ${({\n isPoster,\n theme: {\n torrentCard: { cardSecondaryColor, accentCardColor },\n },\n }) =>\n isPoster\n ? css`\n img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n border-radius: 5px;\n }\n `\n : css`\n display: grid;\n place-items: center;\n background: ${cardSecondaryColor};\n border: 1px solid ${accentCardColor};\n\n svg {\n transform: translateY(-3px);\n }\n `};\n\n @media (max-width: 1260px), (max-height: 500px) {\n svg {\n width: 50%;\n }\n }\n`\n\nexport const TorrentCardButtons = styled.div`\n grid-area: buttons;\n display: grid;\n gap: 10px;\n\n @media (max-width: 1260px), (max-height: 500px) {\n grid-template-columns: repeat(4, 1fr);\n }\n\n @media (max-width: 340px) {\n gap: 5px;\n }\n`\nexport const TorrentCardDescription = styled.div`\n ${({\n theme: {\n torrentCard: { cardSecondaryColor, accentCardColor },\n },\n }) => css`\n grid-area: description;\n background: ${cardSecondaryColor};\n border-radius: 5px;\n padding: 5px;\n display: grid;\n grid-template-rows: 55% 1fr;\n gap: 10px;\n\n @media (max-width: 770px) {\n grid-template-rows: 60% 1fr;\n gap: 3px;\n }\n\n .description-title-wrapper {\n display: flex;\n flex-direction: column;\n }\n\n .description-section-name {\n text-transform: uppercase;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.4px;\n color: ${accentCardColor};\n\n @media (max-width: 770px) {\n font-size: 0.4rem;\n }\n }\n\n .description-torrent-title {\n overflow: auto;\n word-break: break-all;\n }\n\n .description-statistics-wrapper {\n display: grid;\n grid-template-columns: 80px 80px 1fr;\n align-self: end;\n\n @media (max-width: 1260px), (max-height: 500px) {\n grid-template-columns: 70px 70px 1fr;\n }\n\n @media (max-width: 770px) {\n grid-template-columns: 65px 65px 1fr;\n }\n\n @media (max-width: 700px) {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n }\n }\n\n .description-statistics-element-wrapper {\n }\n\n .description-statistics-element-value {\n margin-left: 5px;\n margin-bottom: 10px;\n word-break: break-all;\n\n @media (max-width: 1260px), (max-height: 500px) {\n font-size: 0.7rem;\n margin-bottom: 0;\n margin-left: 0;\n }\n }\n\n .description-torrent-title,\n .description-statistics-element-value {\n @media (max-width: 770px) {\n font-size: 0.6rem;\n }\n\n @media (max-width: 410px) {\n font-size: 10px;\n }\n }\n `}\n`\n\nexport const StyledButton = styled.button`\n ${({\n theme: {\n torrentCard: { buttonBGColor, accentCardColor },\n },\n }) => css`\n border-radius: 5px;\n border: none;\n cursor: pointer;\n transition: 0.2s;\n display: flex;\n align-items: center;\n text-transform: uppercase;\n background: ${buttonBGColor};\n color: #fff;\n font-size: 0.9rem;\n letter-spacing: 0.009em;\n padding: 0 12px;\n svg {\n width: 20px;\n }\n\n :hover {\n background: ${accentCardColor};\n }\n\n > :first-child {\n margin-right: 10px;\n }\n\n @media (max-width: 1260px), (max-height: 500px) {\n padding: 7px 10px;\n justify-content: center;\n font-size: 0.8rem;\n\n svg {\n display: none;\n }\n }\n\n @media (max-width: 770px) {\n font-size: 0.7rem;\n }\n\n @media (max-width: 420px) {\n font-size: 0.6rem;\n padding: 7px 5px;\n }\n `}\n`\n","import { forwardRef, memo, useState } from 'react'\nimport {\n UnfoldMore as UnfoldMoreIcon,\n PlayArrow as PlayArrowIcon,\n Close as CloseIcon,\n Delete as DeleteIcon,\n} from '@material-ui/icons'\nimport { getPeerString, humanizeSize, humanizeSpeed, removeRedundantCharacters } from 'utils/Utils'\nimport { playlistTorrHost, torrentsHost } from 'utils/Hosts'\nimport { NoImageIcon } from 'icons'\nimport DialogTorrentDetailsContent from 'components/DialogTorrentDetailsContent'\nimport Dialog from '@material-ui/core/Dialog'\nimport Slide from '@material-ui/core/Slide'\nimport { Button, DialogActions, DialogTitle, useMediaQuery, useTheme } from '@material-ui/core'\nimport axios from 'axios'\nimport ptt from 'parse-torrent-title'\nimport { useTranslation } from 'react-i18next'\nimport AddDialog from 'components/Add/AddDialog'\n\nimport { StyledButton, TorrentCard, TorrentCardButtons, TorrentCardDescription, TorrentCardPoster } from './style'\n\nconst Transition = forwardRef((props, ref) => )\n\nconst Torrent = ({ torrent }) => {\n const { t } = useTranslation()\n const [isDetailedInfoOpened, setIsDetailedInfoOpened] = useState(false)\n const [isDeleteTorrentOpened, setIsDeleteTorrentOpened] = useState(false)\n\n const theme = useTheme()\n const fullScreen = useMediaQuery(theme.breakpoints.down('md'))\n\n const openDetailedInfo = () => setIsDetailedInfoOpened(true)\n const closeDetailedInfo = () => setIsDetailedInfoOpened(false)\n const openDeleteTorrentAlert = () => setIsDeleteTorrentOpened(true)\n const closeDeleteTorrentAlert = () => setIsDeleteTorrentOpened(false)\n\n const { title, name, poster, torrent_size: torrentSize, download_speed: downloadSpeed, hash } = torrent\n\n const dropTorrent = () => axios.post(torrentsHost(), { action: 'drop', hash })\n const deleteTorrent = () => axios.post(torrentsHost(), { action: 'rem', hash })\n\n const getParsedTitle = () => {\n const parse = key => ptt.parse(title || '')?.[key] || ptt.parse(name || '')?.[key]\n\n const titleStrings = []\n\n let parsedTitle = removeRedundantCharacters(parse('title'))\n const parsedYear = parse('year')\n const parsedResolution = parse('resolution')\n if (parsedTitle) titleStrings.push(parsedTitle)\n if (parsedYear) titleStrings.push(`(${parsedYear})`)\n if (parsedResolution) titleStrings.push(`[${parsedResolution}]`)\n parsedTitle = titleStrings.join(' ')\n return { parsedTitle }\n }\n const { parsedTitle } = getParsedTitle()\n\n const [isEditDialogOpen, setIsEditDialogOpen] = useState(false)\n const handleClickOpenEditDialog = () => setIsEditDialogOpen(true)\n const handleCloseEditDialog = () => setIsEditDialogOpen(false)\n\n const fullPlaylistLink = `${playlistTorrHost()}/${encodeURIComponent(parsedTitle || 'file')}.m3u?link=${hash}&m3u`\n\n return (\n <>\n \n \n {poster ? poster : }\n \n\n \n \n \n {t('Details')}\n \n\n {\n window.open(fullPlaylistLink, '_blank')\n }}\n >\n \n {t('Playlist')}\n \n\n dropTorrent(torrent)}>\n \n {t('Drop')}\n \n\n \n \n {t('Delete')}\n \n \n\n \n
\n
{t('Name')}
\n
{parsedTitle}
\n
\n\n
\n
\n
{t('Size')}
\n
{torrentSize > 0 && humanizeSize(torrentSize)}
\n
\n\n
\n
{t('Speed')}
\n
\n {downloadSpeed > 0 ? humanizeSpeed(downloadSpeed) : '---'}\n
\n
\n\n
\n
{t('Peers')}
\n
{getPeerString(torrent) || '---'}
\n
\n
\n
\n
\n\n \n \n \n\n \n {t('DeleteTorrent?')}\n \n \n\n {\n deleteTorrent(torrent)\n closeDeleteTorrentAlert()\n }}\n color='secondary'\n autoFocus\n >\n {t('OK')}\n \n \n \n\n {isEditDialogOpen && (\n \n )}\n \n )\n}\n\nexport default memo(Torrent)\n","import { rgba } from 'polished'\nimport styled, { css } from 'styled-components'\n\nexport const AppWrapper = styled.div`\n ${({\n theme: {\n app: { appSecondaryColor },\n },\n }) => css`\n height: 100%;\n background: ${rgba(appSecondaryColor, 0.8)};\n display: grid;\n grid-template-columns: 60px 1fr;\n grid-template-rows: 60px 1fr;\n grid-template-areas:\n 'head head'\n 'side content';\n `}\n`\n\nexport const CenteredGrid = styled.div`\n height: 100%;\n display: grid;\n place-items: center;\n`\n\nexport const AppHeader = styled.div`\n ${({ theme: { primary } }) => css`\n background: ${primary};\n color: #fff;\n grid-area: head;\n display: grid;\n grid-auto-flow: column;\n align-items: center;\n grid-template-columns: repeat(2, max-content) 1fr;\n box-shadow: 0px 2px 4px -1px rgb(0 0 0 / 20%), 0px 4px 5px 0px rgb(0 0 0 / 14%), 0px 1px 10px 0px rgb(0 0 0 / 12%);\n padding: 0 16px;\n z-index: 3;\n `}\n`\nexport const AppSidebarStyle = styled.div`\n ${({\n isDrawerOpen,\n theme: {\n app: { appSecondaryColor, sidebarBGColor, sidebarFillColor },\n },\n }) => css`\n grid-area: side;\n width: ${isDrawerOpen ? '400%' : '100%'};\n z-index: 2;\n overflow-x: hidden;\n transition: width 195ms cubic-bezier(0.4, 0, 0.6, 1) 0ms;\n border-right: 1px solid ${rgba(appSecondaryColor, 0.12)};\n background: ${sidebarBGColor};\n color: ${sidebarFillColor};\n white-space: nowrap;\n\n svg {\n fill: ${sidebarFillColor};\n }\n `}\n`\nexport const TorrentListWrapper = styled.div`\n grid-area: content;\n padding: 20px;\n overflow: auto;\n\n display: grid;\n place-content: start;\n grid-template-columns: repeat(auto-fit, minmax(max-content, 570px));\n gap: 20px;\n\n @media (max-width: 1260px), (max-height: 500px) {\n padding: 10px;\n gap: 15px;\n grid-template-columns: repeat(3, 1fr);\n }\n\n @media (max-width: 1100px) {\n grid-template-columns: repeat(2, 1fr);\n }\n\n @media (max-width: 700px) {\n grid-template-columns: 1fr;\n }\n`\n\nexport const HeaderToggle = styled.div`\n ${({\n theme: {\n app: { headerToggleColor },\n },\n }) => css`\n cursor: pointer;\n border-radius: 50%;\n background: ${headerToggleColor};\n height: 35px;\n width: 35px;\n transition: all 0.2s;\n font-weight: 600;\n display: grid;\n place-items: center;\n color: #fff;\n\n :hover {\n background: ${rgba(headerToggleColor, 0.7)};\n }\n\n @media (max-width: 700px) {\n height: 28px;\n width: 28px;\n font-size: 12px;\n\n svg {\n width: 17px;\n }\n }\n `}\n`\n","import styled, { css } from 'styled-components'\n\nexport default styled.div`\n ${({ isButton }) => css`\n display: grid;\n place-items: center;\n padding: 20px 40px;\n border-radius: 5px;\n\n ${isButton &&\n css`\n background: #88cdaa;\n transition: 0.2s;\n cursor: pointer;\n\n :hover {\n background: #74c39c;\n }\n `}\n\n lord-icon {\n width: 200px;\n height: 200px;\n }\n\n .icon-label {\n font-size: 20px;\n }\n `}\n`\n","import { useTheme } from '@material-ui/core'\nimport { useTranslation } from 'react-i18next'\n\nimport IconWrapper from './style'\n\nexport default function NoServerConnection() {\n const { t } = useTranslation()\n const primary = useTheme().palette.primary.main\n\n return (\n \n \n
{t('Offline')}
\n
\n )\n}\n","import { useTheme } from '@material-ui/core'\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\n\nimport AddDialog from '../Add/AddDialog'\nimport IconWrapper from './style'\n\nexport default function AddFirstTorrent() {\n const { t } = useTranslation()\n const [isDialogOpen, setIsDialogOpen] = useState(false)\n const handleClickOpen = () => setIsDialogOpen(true)\n const handleClose = () => setIsDialogOpen(false)\n const primary = useTheme().palette.primary.main\n\n return (\n <>\n handleClickOpen(true)} isButton>\n \n
{t('NoTorrentsAdded')}
\n
\n\n {isDialogOpen && }\n \n )\n}\n","import TorrentCard from 'components/TorrentCard'\nimport CircularProgress from '@material-ui/core/CircularProgress'\nimport { TorrentListWrapper, CenteredGrid } from 'components/App/style'\n\nimport NoServerConnection from './NoServerConnection'\nimport AddFirstTorrent from './AddFirstTorrent'\n\nexport default function TorrentList({ isOffline, isLoading, torrents }) {\n if (isLoading || isOffline || !torrents.length) {\n return (\n \n {isOffline ? (\n \n ) : isLoading ? (\n \n ) : (\n !torrents.length && \n )}\n \n )\n }\n\n return (\n \n {torrents.map(torrent => (\n \n ))}\n \n )\n}\n","import ListItem from '@material-ui/core/ListItem'\nimport Dialog from '@material-ui/core/Dialog'\nimport DialogTitle from '@material-ui/core/DialogTitle'\nimport DialogContent from '@material-ui/core/DialogContent'\nimport DialogActions from '@material-ui/core/DialogActions'\nimport List from '@material-ui/core/List'\nimport ButtonGroup from '@material-ui/core/ButtonGroup'\nimport Button from '@material-ui/core/Button'\nimport { useTranslation } from 'react-i18next'\n\nconst donateFrame =\n ''\n\nexport default function DonateDialog({ onClose }) {\n const { t } = useTranslation()\n\n return (\n \n {t('Donate')}\n \n \n \n \n \n \n \n \n \n {/* eslint-disable-next-line react/no-danger */}\n
\n \n \n \n\n \n \n \n
\n )\n}\n","import { useState } from 'react'\nimport Button from '@material-ui/core/Button'\nimport Snackbar from '@material-ui/core/Snackbar'\nimport IconButton from '@material-ui/core/IconButton'\nimport CreditCardIcon from '@material-ui/icons/CreditCard'\nimport CloseIcon from '@material-ui/icons/Close'\nimport { useTranslation } from 'react-i18next'\n\nimport DonateDialog from './DonateDialog'\n\nexport default function DonateSnackbar() {\n const { t } = useTranslation()\n const [open, setOpen] = useState(false)\n const [snackbarOpen, setSnackbarOpen] = useState(true)\n\n const disableSnackbar = () => {\n setSnackbarOpen(false)\n localStorage.setItem('snackbarIsClosed', true)\n }\n\n return (\n <>\n {open && setOpen(false)} />}\n\n \n {\n setOpen(true)\n disableSnackbar()\n }}\n >\n \n {t('Support')}\n \n\n \n \n \n \n }\n />\n \n )\n}\n","import { createGlobalStyle } from 'styled-components'\n\nexport default createGlobalStyle`\n *,\n *::before,\n *::after { \n margin: 0;\n padding: 0;\n box-sizing: inherit;\n }\n\n body { \n font-family: \"Open Sans\", sans-serif;\n box-sizing: border-box;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n letter-spacing: -0.1px;\n }\n\n button {\n font-family: \"Open Sans\", sans-serif;\n letter-spacing: -0.1px;\n }\n`\n","import { useState } from 'react'\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\nimport LibraryAddIcon from '@material-ui/icons/LibraryAdd'\nimport ListItemText from '@material-ui/core/ListItemText'\nimport ListItem from '@material-ui/core/ListItem'\nimport { useTranslation } from 'react-i18next'\n\nimport AddDialog from './AddDialog'\n\nexport default function AddDialogButton({ isOffline, isLoading }) {\n const { t } = useTranslation()\n const [isDialogOpen, setIsDialogOpen] = useState(false)\n const handleClickOpen = () => setIsDialogOpen(true)\n const handleClose = () => setIsDialogOpen(false)\n\n return (\n
\n \n \n \n \n \n \n\n {isDialogOpen && }\n
\n )\n}\n","import styled, { css } from 'styled-components'\nimport { mainColors } from 'style/colors'\nimport { Header } from 'style/DialogStyles'\n\nexport const cacheBeforeReaderColor = '#b3dfc9'\nexport const cacheAfterReaderColor = mainColors.light.primary\n\nexport const SettingsHeader = styled(Header)`\n display: grid;\n grid-auto-flow: column;\n align-items: center;\n justify-content: space-between;\n\n @media (max-width: 340px) {\n grid-auto-flow: row;\n }\n`\n\nexport const FooterSection = styled.div`\n ${({\n theme: {\n settingsDialog: { footerBG },\n },\n }) => css`\n padding: 20px;\n display: grid;\n grid-auto-flow: column;\n justify-content: end;\n gap: 10px;\n align-items: center;\n background: ${footerBG};\n\n @media (max-width: 500px) {\n grid-auto-flow: row;\n justify-content: stretch;\n }\n `}\n`\nexport const Divider = styled.div`\n height: 1px;\n background-color: rgba(0, 0, 0, 0.12);\n margin: 30px 0;\n`\n\nexport const Content = styled.div`\n ${({\n isLoading,\n theme: {\n settingsDialog: { contentBG },\n },\n }) => css`\n background: ${contentBG};\n overflow: auto;\n flex: 1;\n\n ${isLoading &&\n css`\n min-height: 500px;\n display: grid;\n place-items: center;\n `}\n `}\n`\n\nexport const PreloadCacheValue = styled.div`\n ${({ color }) => css`\n display: grid;\n grid-template-columns: max-content 100px 1fr;\n gap: 10px;\n align-items: flex-start;\n\n :not(:last-child) {\n margin-bottom: 5px;\n }\n\n :before {\n content: '';\n background: ${color};\n width: 16px;\n height: 16px;\n border-radius: 50%;\n margin-top: 2px;\n }\n `}\n`\n\nexport const MainSettingsContent = styled.div`\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 40px;\n padding: 20px;\n\n @media (max-width: 930px) {\n grid-template-columns: 1fr;\n }\n`\nexport const SecondarySettingsContent = styled.div`\n padding: 20px;\n`\n\nexport const StorageButton = styled.div`\n ${({ small, selected }) => css`\n transition: 0.2s;\n cursor: default;\n text-align: center;\n\n ${!selected &&\n css`\n cursor: pointer;\n\n :hover {\n filter: brightness(0.8);\n }\n `}\n\n ${small\n ? css`\n display: grid;\n grid-template-columns: max-content 1fr;\n gap: 20px;\n align-items: center;\n justify-items: start;\n margin-bottom: 20px;\n `\n : css`\n display: grid;\n place-items: center;\n gap: 10px;\n `}\n `}\n`\n\nexport const StorageIconWrapper = styled.div`\n ${({ selected, small }) => css`\n width: ${small ? '60px' : '150px'};\n height: ${small ? '60px' : '150px'};\n border-radius: 50%;\n background: ${selected ? '#323637' : '#dee3e5'};\n\n svg {\n transform: rotate(-45deg) scale(0.75);\n }\n\n @media (max-width: 930px) {\n width: ${small ? '50px' : '90px'};\n height: ${small ? '50px' : '90px'};\n }\n `}\n`\n\nexport const CacheStorageSelector = styled.div`\n display: grid;\n grid-template-rows: max-content 1fr;\n grid-template-areas: 'label label';\n place-items: center;\n\n @media (max-width: 930px) {\n justify-content: start;\n column-gap: 30px;\n }\n`\n\nexport const SettingSectionLabel = styled.div`\n font-size: 25px;\n padding-bottom: 20px;\n\n small {\n display: block;\n font-size: 11px;\n }\n`\n\nexport const PreloadCachePercentage = styled.div.attrs(({ value }) => ({\n // this block is here according to styled-components recomendation about fast changable components\n style: {\n background: `linear-gradient(to right, ${cacheBeforeReaderColor} 0%, ${cacheBeforeReaderColor} ${value}%, ${cacheAfterReaderColor} ${value}%, ${cacheAfterReaderColor} 100%)`,\n },\n}))`\n ${({ label, preloadCachePercentage }) => css`\n border: 1px solid #323637;\n padding: 10px 20px;\n border-radius: 5px;\n color: #000;\n margin-bottom: 10px;\n position: relative;\n\n :before {\n content: '${label}';\n display: grid;\n place-items: center;\n font-size: 20px;\n }\n\n :after {\n content: '';\n width: ${preloadCachePercentage}%;\n height: 100%;\n background: #323637;\n position: absolute;\n bottom: 0;\n left: 0;\n border-radius: 4px;\n filter: opacity(0.15);\n }\n `}\n`\n","export default {\n CacheSize: 96,\n ReaderReadAHead: 95,\n UseDisk: false,\n UploadRateLimit: 0,\n TorrentsSavePath: '',\n ConnectionsLimit: 23,\n DhtConnectionLimit: 500,\n DisableDHT: false,\n DisablePEX: false,\n DisableTCP: false,\n DisableUPNP: false,\n DisableUTP: true,\n DisableUpload: false,\n DownloadRateLimit: 0,\n EnableDebug: false,\n EnableIPv6: false,\n ForceEncrypt: false,\n PeersListenPort: 0,\n PreloadCache: 0,\n RemoveCacheOnDrop: false,\n RetrackersMode: 1,\n Strategy: 0,\n TorrentDisconnectTimeout: 30,\n}\n","export const a11yProps = index => ({\n id: `full-width-tab-${index}`,\n 'aria-controls': `full-width-tabpanel-${index}`,\n})\n\nexport const TabPanel = ({ children, value, index, ...other }) => (\n \n)\n","import { Grid, OutlinedInput, Slider } from '@material-ui/core'\n\nexport default function SliderInput({\n isProMode,\n title,\n value,\n setValue,\n sliderMin,\n sliderMax,\n inputMin,\n inputMax,\n step = 1,\n onBlurCallback,\n}) {\n const onBlur = ({ target: { value } }) => {\n if (value < inputMin) return setValue(inputMin)\n if (value > inputMax) return setValue(inputMax)\n\n onBlurCallback && onBlurCallback(value)\n }\n\n const onInputChange = ({ target: { value } }) => setValue(value === '' ? '' : Number(value))\n const onSliderChange = (_, newValue) => setValue(newValue)\n\n return (\n <>\n
{title}
\n\n \n \n \n \n\n {isProMode && (\n \n \n \n )}\n \n \n )\n}\n","import { useTranslation } from 'react-i18next'\nimport { USBIcon, RAMIcon } from 'icons'\nimport { FormControlLabel, Switch } from '@material-ui/core'\nimport TextField from '@material-ui/core/TextField'\n\nimport {\n PreloadCacheValue,\n MainSettingsContent,\n StorageButton,\n StorageIconWrapper,\n CacheStorageSelector,\n SettingSectionLabel,\n PreloadCachePercentage,\n cacheBeforeReaderColor,\n cacheAfterReaderColor,\n} from './style'\nimport SliderInput from './SliderInput'\n\nconst CacheStorageLocationLabel = ({ style }) => {\n const { t } = useTranslation()\n\n return (\n \n {t('SettingsDialog.CacheStorageLocation')}\n {t('SettingsDialog.UseDiskDesc')}\n \n )\n}\n\nexport default function PrimarySettingsComponent({\n settings,\n inputForm,\n cachePercentage,\n preloadCachePercentage,\n cacheSize,\n isProMode,\n setCacheSize,\n setCachePercentage,\n setPreloadCachePercentage,\n updateSettings,\n}) {\n const { t } = useTranslation()\n const { UseDisk, TorrentsSavePath, RemoveCacheOnDrop } = settings || {}\n const preloadCacheSize = Math.round((cacheSize / 100) * preloadCachePercentage)\n\n return (\n \n
\n {t('SettingsDialog.CacheSettings')}\n\n \n\n \n
\n {100 - cachePercentage}% ({Math.round((cacheSize / 100) * (100 - cachePercentage))} {t('MB')})\n
\n\n
{t('SettingsDialog.CacheBeforeReaderDesc')}
\n
\n\n \n
\n {cachePercentage}% ({Math.round((cacheSize / 100) * cachePercentage)} {t('MB')})\n
\n\n
{t('SettingsDialog.CacheAfterReaderDesc')}
\n
\n\n
\n\n setCacheSize(Math.round(value / 4) * 4)}\n />\n\n \n\n \n
\n\n {UseDisk ? (\n
\n \n\n
\n updateSettings({ UseDisk: false })}>\n \n \n \n\n
{t('SettingsDialog.RAM')}
\n
\n\n \n \n \n \n\n
{t('SettingsDialog.Disk')}
\n
\n
\n\n \n }\n label={t('SettingsDialog.RemoveCacheOnDrop')}\n labelPlacement='start'\n />\n
\n {t('SettingsDialog.RemoveCacheOnDropDesc')}\n
\n
\n \n
\n ) : (\n \n \n\n \n \n \n \n\n
{t('SettingsDialog.RAM')}
\n
\n\n updateSettings({ UseDisk: true })}>\n \n \n \n\n
{t('SettingsDialog.Disk')}
\n
\n
\n )}\n
\n )\n}\n","import { useTranslation } from 'react-i18next'\nimport TextField from '@material-ui/core/TextField'\nimport { FormControlLabel, InputAdornment, InputLabel, Select, Switch } from '@material-ui/core'\n\nimport { SecondarySettingsContent, SettingSectionLabel } from './style'\n\nexport default function SecondarySettingsComponent({ settings, inputForm }) {\n const { t } = useTranslation()\n\n const {\n RetrackersMode,\n TorrentDisconnectTimeout,\n EnableDLNA,\n EnableIPv6,\n ForceEncrypt,\n DisableTCP,\n DisableUTP,\n DisableUPNP,\n DisableDHT,\n DisablePEX,\n DisableUpload,\n DownloadRateLimit,\n UploadRateLimit,\n ConnectionsLimit,\n PeersListenPort,\n } = settings || {}\n\n return (\n \n {t('SettingsDialog.AdditionalSettings')}\n\n }\n label='IPv6'\n labelPlacement='start'\n />\n }\n label='TCP (Transmission Control Protocol)'\n labelPlacement='start'\n />\n }\n label='μTP (Micro Transport Protocol)'\n labelPlacement='start'\n />\n }\n label='PEX (Peer Exchange)'\n labelPlacement='start'\n />\n }\n label={t('SettingsDialog.ForceEncrypt')}\n labelPlacement='start'\n />\n {t('Seconds')},\n }}\n value={TorrentDisconnectTimeout}\n type='number'\n variant='outlined'\n fullWidth\n />\n
\n \n
\n }\n label={t('SettingsDialog.DHT')}\n labelPlacement='start'\n />\n {t('Kilobytes')},\n }}\n value={DownloadRateLimit}\n type='number'\n variant='outlined'\n fullWidth\n />\n
\n }\n label={t('SettingsDialog.Upload')}\n labelPlacement='start'\n />\n {t('Kilobytes')},\n }}\n value={UploadRateLimit}\n type='number'\n variant='outlined'\n fullWidth\n />\n
\n \n }\n label='UPnP (Universal Plug and Play)'\n labelPlacement='start'\n />\n }\n label={t('SettingsDialog.DLNA')}\n labelPlacement='start'\n />\n
\n {t('SettingsDialog.RetrackersMode')}\n \n \n \n \n \n \n
\n
\n )\n}\n","import axios from 'axios'\nimport Dialog from '@material-ui/core/Dialog'\nimport Button from '@material-ui/core/Button'\nimport Checkbox from '@material-ui/core/Checkbox'\nimport { FormControlLabel, useMediaQuery, useTheme } from '@material-ui/core'\nimport { settingsHost } from 'utils/Hosts'\nimport { useEffect, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport AppBar from '@material-ui/core/AppBar'\nimport Tabs from '@material-ui/core/Tabs'\nimport Tab from '@material-ui/core/Tab'\nimport SwipeableViews from 'react-swipeable-views'\nimport CircularProgress from '@material-ui/core/CircularProgress'\n\nimport { SettingsHeader, FooterSection, Content } from './style'\nimport defaultSettings from './defaultSettings'\nimport { a11yProps, TabPanel } from './tabComponents'\nimport PrimarySettingsComponent from './PrimarySettingsComponent'\nimport SecondarySettingsComponent from './SecondarySettingsComponent'\n\nexport default function SettingsDialog({ handleClose }) {\n const { t } = useTranslation()\n const fullScreen = useMediaQuery('@media (max-width:930px)')\n const { direction } = useTheme()\n\n const [settings, setSettings] = useState()\n const [selectedTab, setSelectedTab] = useState(0)\n const [cacheSize, setCacheSize] = useState(32)\n const [cachePercentage, setCachePercentage] = useState(40)\n const [preloadCachePercentage, setPreloadCachePercentage] = useState(0)\n const [isProMode, setIsProMode] = useState(JSON.parse(localStorage.getItem('isProMode')) || false)\n\n useEffect(() => {\n axios.post(settingsHost(), { action: 'get' }).then(({ data }) => {\n setSettings({ ...data, CacheSize: data.CacheSize / (1024 * 1024) })\n })\n }, [])\n\n const handleSave = () => {\n handleClose()\n const sets = JSON.parse(JSON.stringify(settings))\n sets.CacheSize = cacheSize * 1024 * 1024\n sets.ReaderReadAHead = cachePercentage\n sets.PreloadCache = preloadCachePercentage\n axios.post(settingsHost(), { action: 'set', sets })\n }\n\n const inputForm = ({ target: { type, value, checked, id } }) => {\n const sets = JSON.parse(JSON.stringify(settings))\n\n if (type === 'number' || type === 'select-one') {\n sets[id] = Number(value)\n } else if (type === 'checkbox') {\n if (\n id === 'DisableTCP' ||\n id === 'DisableUTP' ||\n id === 'DisableUPNP' ||\n id === 'DisableDHT' ||\n id === 'DisablePEX' ||\n id === 'DisableUpload'\n )\n sets[id] = Boolean(!checked)\n else sets[id] = Boolean(checked)\n } else if (type === 'url') {\n sets[id] = value\n }\n setSettings(sets)\n }\n\n const { CacheSize, ReaderReadAHead, PreloadCache } = settings || {}\n\n useEffect(() => {\n if (isNaN(CacheSize) || isNaN(ReaderReadAHead) || isNaN(PreloadCache)) return\n\n setCacheSize(CacheSize)\n setCachePercentage(ReaderReadAHead)\n setPreloadCachePercentage(PreloadCache)\n }, [CacheSize, ReaderReadAHead, PreloadCache])\n\n const updateSettings = newProps => setSettings({ ...settings, ...newProps })\n const handleChange = (_, newValue) => setSelectedTab(newValue)\n const handleChangeIndex = index => setSelectedTab(index)\n\n return (\n \n \n
{t('SettingsDialog.Settings')}
\n {\n setIsProMode(checked)\n localStorage.setItem('isProMode', checked)\n if (!checked) setSelectedTab(0)\n }}\n style={{ color: 'white' }}\n />\n }\n label={t('SettingsDialog.ProMode')}\n />\n
\n\n \n \n \n\n \n
{t('SettingsDialog.Tabs.Additional')}
\n {!isProMode &&
{t('SettingsDialog.Tabs.AdditionalDisabled')}
}\n \n }\n {...a11yProps(1)}\n />\n \n
\n\n \n {settings ? (\n <>\n \n \n \n \n\n \n \n \n \n \n ) : (\n \n )}\n \n\n \n \n\n {\n setCacheSize(defaultSettings.CacheSize)\n setCachePercentage(defaultSettings.ReaderReadAHead)\n setPreloadCachePercentage(defaultSettings.PreloadCache)\n updateSettings(defaultSettings)\n }}\n color='secondary'\n variant='outlined'\n >\n {t('SettingsDialog.ResetToDefault')}\n \n\n \n \n
\n )\n}\n","import ListItem from '@material-ui/core/ListItem'\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\nimport ListItemText from '@material-ui/core/ListItemText'\nimport { useState } from 'react'\nimport SettingsIcon from '@material-ui/icons/Settings'\nimport { useTranslation } from 'react-i18next'\n\nimport SettingsDialog from './SettingsDialog'\n\nexport default function SettingsDialogButton({ isOffline, isLoading }) {\n const { t } = useTranslation()\n const [isDialogOpen, setIsDialogOpen] = useState(false)\n\n const handleClickOpen = () => setIsDialogOpen(true)\n const handleClose = () => setIsDialogOpen(false)\n\n return (\n
\n \n \n \n \n \n \n\n {isDialogOpen && }\n
\n )\n}\n","import { Button, Dialog, DialogActions, DialogTitle } from '@material-ui/core'\nimport ListItem from '@material-ui/core/ListItem'\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\nimport ListItemText from '@material-ui/core/ListItemText'\nimport DeleteIcon from '@material-ui/icons/Delete'\nimport { useState } from 'react'\nimport { torrentsHost } from 'utils/Hosts'\nimport { useTranslation } from 'react-i18next'\n\nconst fnRemoveAll = () => {\n fetch(torrentsHost(), {\n method: 'post',\n body: JSON.stringify({ action: 'list' }),\n headers: {\n Accept: 'application/json, text/plain, */*',\n 'Content-Type': 'application/json',\n },\n })\n .then(res => res.json())\n .then(json => {\n json.forEach(torr => {\n fetch(torrentsHost(), {\n method: 'post',\n body: JSON.stringify({ action: 'rem', hash: torr.hash }),\n headers: {\n Accept: 'application/json, text/plain, */*',\n 'Content-Type': 'application/json',\n },\n })\n })\n })\n}\n\nexport default function RemoveAll({ isOffline, isLoading }) {\n const { t } = useTranslation()\n const [open, setOpen] = useState(false)\n const closeDialog = () => setOpen(false)\n const openDialog = () => setOpen(true)\n\n return (\n <>\n \n \n \n \n\n \n \n\n \n {t('DeleteTorrents?')}\n \n \n\n {\n fnRemoveAll()\n closeDialog()\n }}\n color='secondary'\n autoFocus\n >\n {t('OK')}\n \n \n \n \n )\n}\n","import styled, { css } from 'styled-components'\n\nexport const DialogWrapper = styled.div`\n height: 100%;\n display: grid;\n grid-template-rows: max-content 1fr max-content;\n`\n\nexport const HeaderSection = styled.section`\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 36px;\n font-weight: 300;\n padding: 20px;\n\n img {\n width: 64px;\n }\n\n @media (max-width: 930px) {\n font-size: 24px;\n padding: 10px 20px;\n\n img {\n width: 60px;\n }\n }\n`\n\nexport const ThanksSection = styled.section`\n padding: 20px;\n text-align: center;\n font-size: 24px;\n font-weight: 300;\n background: #e8e5eb;\n color: #323637;\n\n @media (max-width: 930px) {\n font-size: 20px;\n padding: 30px 20px;\n }\n`\n\nexport const Section = styled.section`\n padding: 20px;\n\n > span {\n font-size: 22px;\n display: block;\n margin-bottom: 15px;\n }\n\n a {\n text-decoration: none;\n }\n\n > div {\n display: grid;\n gap: 10px;\n grid-template-columns: repeat(4, max-content);\n\n @media (max-width: 930px) {\n grid-template-columns: repeat(3, 1fr);\n }\n\n @media (max-width: 780px) {\n grid-template-columns: repeat(2, 1fr);\n }\n\n @media (max-width: 550px) {\n grid-template-columns: 1fr;\n }\n }\n`\n\nexport const FooterSection = styled.div`\n padding: 20px;\n display: flex;\n justify-content: flex-end;\n background: #e8e5eb;\n`\n\nexport const LinkWrapper = styled.a`\n ${({ isLink }) => css`\n display: inline-flex;\n align-items: center;\n justify-content: start;\n border: 1px solid;\n padding: 7px 10px;\n border-radius: 5px;\n text-transform: uppercase;\n text-decoration: none;\n background: #545a5e;\n color: #f1eff3;\n transition: 0.2s;\n\n > * {\n transition: 0.2s;\n }\n\n ${isLink\n ? css`\n :hover {\n filter: brightness(1.1);\n\n > * {\n transform: translateY(0px);\n }\n }\n `\n : css`\n cursor: default;\n `}\n `}\n`\n\nexport const LinkIcon = styled.div`\n display: grid;\n margin-right: 10px;\n`\n","import { GitHub as GitHubIcon } from '@material-ui/icons'\n\nimport { LinkWrapper, LinkIcon } from './style'\n\nexport default function LinkComponent({ name, link }) {\n return (\n \n {link && (\n \n \n \n )}\n\n
{name}
\n
\n )\n}\n","import axios from 'axios'\nimport { useEffect, useState } from 'react'\nimport Button from '@material-ui/core/Button'\nimport Dialog from '@material-ui/core/Dialog'\nimport InfoIcon from '@material-ui/icons/Info'\nimport ListItem from '@material-ui/core/ListItem'\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\nimport ListItemText from '@material-ui/core/ListItemText'\nimport { useTranslation } from 'react-i18next'\nimport { useMediaQuery } from '@material-ui/core'\nimport { echoHost } from 'utils/Hosts'\n\nimport LinkComponent from './LinkComponent'\nimport { DialogWrapper, HeaderSection, ThanksSection, Section, FooterSection } from './style'\n\nexport default function AboutDialog() {\n const { t } = useTranslation()\n const [open, setOpen] = useState(false)\n const [torrServerVersion, setTorrServerVersion] = useState('')\n const fullScreen = useMediaQuery('@media (max-width:930px)')\n useEffect(() => {\n axios.get(echoHost()).then(({ data }) => setTorrServerVersion(data))\n }, [])\n\n return (\n <>\n setOpen(true)}>\n \n \n \n \n \n\n setOpen(false)}\n aria-labelledby='form-dialog-title'\n fullScreen={fullScreen}\n maxWidth='xl'\n >\n \n \n
{t('About')}
\n {torrServerVersion}\n ts-icon\n
\n\n
\n {t('ThanksToEveryone')}\n\n
\n {t('Links')}\n\n
\n \n \n
\n
\n\n
\n {t('SpecialThanks')}\n\n
\n \n \n \n \n \n
\n
\n
\n\n \n \n \n
\n \n \n )\n}\n","import { useState } from 'react'\nimport { Button, Dialog, DialogActions, DialogTitle, ListItem, ListItemIcon, ListItemText } from '@material-ui/core'\nimport { PowerSettingsNew as PowerSettingsNewIcon } from '@material-ui/icons'\nimport { shutdownHost } from 'utils/Hosts'\nimport { useTranslation } from 'react-i18next'\n\nexport default function CloseServer({ isOffline, isLoading }) {\n const { t } = useTranslation()\n const [open, setOpen] = useState(false)\n const closeDialog = () => setOpen(false)\n const openDialog = () => setOpen(true)\n\n return (\n <>\n \n \n \n \n\n \n \n\n \n {t('CloseServer?')}\n \n \n\n {\n fetch(shutdownHost())\n closeDialog()\n }}\n color='secondary'\n autoFocus\n >\n {t('TurnOff')}\n \n \n \n \n )\n}\n","import Divider from '@material-ui/core/Divider'\nimport ListItem from '@material-ui/core/ListItem'\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\nimport ListItemText from '@material-ui/core/ListItemText'\nimport { CreditCard as CreditCardIcon } from '@material-ui/icons'\nimport List from '@material-ui/core/List'\nimport { useTranslation } from 'react-i18next'\nimport AddDialogButton from 'components/Add'\nimport SettingsDialog from 'components/Settings'\nimport RemoveAll from 'components/RemoveAll'\nimport AboutDialog from 'components/About'\nimport CloseServer from 'components/CloseServer'\nimport { memo } from 'react'\n\nimport { AppSidebarStyle } from './style'\n\nconst Sidebar = ({ isDrawerOpen, setIsDonationDialogOpen, isOffline, isLoading }) => {\n const { t } = useTranslation()\n\n return (\n \n \n \n\n \n \n\n \n\n \n \n\n \n\n setIsDonationDialogOpen(true)}>\n \n \n \n\n \n \n\n \n \n \n )\n}\n\nexport default memo(Sidebar)\n","import CssBaseline from '@material-ui/core/CssBaseline'\nimport { createContext, useEffect, useState } from 'react'\nimport Typography from '@material-ui/core/Typography'\nimport IconButton from '@material-ui/core/IconButton'\nimport {\n Menu as MenuIcon,\n Close as CloseIcon,\n Brightness4 as Brightness4Icon,\n Brightness5 as Brightness5Icon,\n BrightnessAuto as BrightnessAutoIcon,\n} from '@material-ui/icons'\nimport { echoHost } from 'utils/Hosts'\nimport Div100vh from 'react-div-100vh'\nimport axios from 'axios'\nimport TorrentList from 'components/TorrentList'\nimport DonateSnackbar from 'components/Donate'\nimport DonateDialog from 'components/Donate/DonateDialog'\nimport useChangeLanguage from 'utils/useChangeLanguage'\nimport { ThemeProvider as MuiThemeProvider } from '@material-ui/core/styles'\nimport { ThemeProvider as StyledComponentsThemeProvider } from 'styled-components'\nimport { useQuery } from 'react-query'\nimport { getTorrents } from 'utils/Utils'\nimport GlobalStyle from 'style/GlobalStyle'\n\nimport { AppWrapper, AppHeader, HeaderToggle } from './style'\nimport Sidebar from './Sidebar'\nimport { lightTheme, THEME_MODES, useMaterialUITheme } from '../../style/materialUISetup'\nimport getStyledComponentsTheme from '../../style/getStyledComponentsTheme'\n\nexport const DarkModeContext = createContext()\n\nexport default function App() {\n const [isDrawerOpen, setIsDrawerOpen] = useState(false)\n const [isDonationDialogOpen, setIsDonationDialogOpen] = useState(false)\n const [torrServerVersion, setTorrServerVersion] = useState('')\n\n const [isDarkMode, currentThemeMode, updateThemeMode, muiTheme] = useMaterialUITheme()\n const [currentLang, changeLang] = useChangeLanguage()\n const [isOffline, setIsOffline] = useState(false)\n const { data: torrents, isLoading } = useQuery('torrents', getTorrents, {\n retry: 1,\n refetchInterval: 1000,\n onError: () => setIsOffline(true),\n onSuccess: () => setIsOffline(false),\n })\n\n useEffect(() => {\n axios.get(echoHost()).then(({ data }) => setTorrServerVersion(data))\n }, [])\n\n return (\n <>\n \n\n \n \n \n \n\n {/* Div100vh - iOS WebKit fix */}\n \n \n \n setIsDrawerOpen(!isDrawerOpen)}\n style={{ marginRight: '6px' }}\n >\n {isDrawerOpen ? : }\n \n\n \n TorrServer {torrServerVersion}\n \n\n \n {\n if (currentThemeMode === THEME_MODES.LIGHT) updateThemeMode(THEME_MODES.DARK)\n if (currentThemeMode === THEME_MODES.DARK) updateThemeMode(THEME_MODES.AUTO)\n if (currentThemeMode === THEME_MODES.AUTO) updateThemeMode(THEME_MODES.LIGHT)\n }}\n >\n {currentThemeMode === THEME_MODES.LIGHT ? (\n \n ) : currentThemeMode === THEME_MODES.DARK ? (\n \n ) : (\n \n )}\n \n\n \n currentLang === 'en'\n ? changeLang('ru')\n : currentLang === 'ru'\n ? changeLang('ua')\n : changeLang('en')\n }\n >\n {currentLang.toUpperCase()}\n \n \n \n\n \n\n \n\n \n {isDonationDialogOpen && setIsDonationDialogOpen(false)} />}\n \n\n {!JSON.parse(localStorage.getItem('snackbarIsClosed')) && }\n \n \n \n \n \n \n )\n}\n","import { mainColors, themeColors } from './colors'\n\nexport default type => ({ ...themeColors[type], ...mainColors[type] })\n","import { StrictMode } from 'react'\nimport ReactDOM from 'react-dom'\nimport { QueryClientProvider, QueryClient } from 'react-query'\n\nimport App from './components/App'\nimport 'i18n'\n\nconst queryClient = new QueryClient()\n\nReactDOM.render(\n \n \n \n \n ,\n document.getElementById('root'),\n)\n"],"sourceRoot":""} \ No newline at end of file diff --git a/web/src/utils/useChangeLanguage.js b/web/src/utils/useChangeLanguage.js index 6d31049..5c8dfda 100644 --- a/web/src/utils/useChangeLanguage.js +++ b/web/src/utils/useChangeLanguage.js @@ -2,12 +2,7 @@ import { useTranslation } from 'react-i18next' export default () => { const { i18n } = useTranslation() - const currentLanguage = - i18n.language === 'en-US' || i18n.language === 'en' - ? 'en' - : i18n.language === 'ru-RU' || i18n.language === 'ru' - ? 'ru' - : i18n.language + const currentLanguage = i18n.language.substr(0, 2) return [currentLanguage, lang => i18n.changeLanguage(lang)] }