';
}
box.html(html);
box.find('img').on('error', function () {
var letter = box.find('.fxapi-profile__title').text().charAt(0).toUpperCase() || '?';
$(this).replaceWith('
' + letter + '
');
});
}
function fetchUserProfile(token, callback, onError) {
var network = new Lampa.Reguest();
network.timeout(8000);
network.silent(Lampa.Utils.addUrlComponent(apiPath('user_profile'), devToken(token)), function (json) {
if (json && json.user_data) {
applyQualityFromProfile(json.user_data);
Lampa.Storage.set('fxapi_status', json.user_data);
var profile = normalizeProfile(json);
if (callback) callback(profile, json.user_data);
} else {
Lampa.Storage.set('fxapi_status', {});
window.fxapi.max_qualitie = 720;
window.fxapi.is_max_qualitie = false;
if (callback) callback(null);
}
renderFxProfile();
}, function (a, c) {
if (onError) onError(a, c);
else Lampa.Noty.show(network.errorDecode(a, c));
});
}
function parseLinkQualities(link) {
var match = link && link.match(/\[([\d,\s]*)\]/);
if (!match) return [];
return match[1].split(',').map(function (q) {
return parseInt(q, 10);
}).filter(function (q) {
return q > 0 && q <= window.fxapi.max_qualitie;
});
}
function maxQuality(list) {
if (!list || !list.length) return 0;
return Math.max.apply(null, list);
}
if (!window.fxapi) {
window.fxapi = {
max_qualitie: 720,
is_max_qualitie: false
};
}
function fxapi(component, _object) {
var network = new Lampa.Reguest();
var extract = {};
var results = [];
var object = _object;
var wait_similars;
var filter_items = {};
var choice = {
season: 0,
voice: 0,
voice_name: ''
};
this.search = function (_object, sim) {
if (wait_similars) this.find(sim[0].id);
};
function normalizeString(str) {
return str.toLowerCase().replace(/[^a-zа-я0-9]/g, '');
}
this.searchByTitle = function (_object, query) {
var _this = this;
object = _object;
var year = parseInt(((object.movie.release_date || object.movie.first_air_date || '0000') + '').slice(0, 4));
var orig = object.movie.original_name || object.movie.original_title;
var url = Lampa.Utils.addUrlComponent(apiPath('search'), 'story=' + encodeURIComponent(query));
url = Lampa.Utils.addUrlComponent(url, devToken());
network.clear();
network.timeout(10000);
network.silent(url, function (json) {
if (!json || !Array.isArray(json)) {
component.doesNotAnswer();
return;
}
var cards = json.filter(function (c) {
c.year = parseInt(c.year || c.alt_name.split('-').pop());
return c.year > year - 2 && c.year < year + 2;
});
var card = cards.find(function (c) {
return c.year == year && normalizeString(c.original_title) == normalizeString(orig);
});
if (!card) {
card = cards.find(function (c) {
return normalizeString(c.original_title) == normalizeString(orig);
});
}
if (!card && cards.length == 1) card = cards[0];
if (card) _this.find(card.id);
else if (json.length) {
wait_similars = true;
component.similars(json);
component.loading(false);
} else component.doesNotAnswer();
}, function (a, c) {
component.doesNotAnswer();
});
};
this.find = function (filmix_id) {
var token = getToken();
if (!window.fxapi.is_max_qualitie && token) {
window.fxapi.is_max_qualitie = true;
network.clear();
network.timeout(10000);
network.silent(Lampa.Utils.addUrlComponent(apiPath('user_profile'), devToken(token)), function (found) {
if (found && found.user_data) {
if (found.user_data.is_pro) window.fxapi.max_qualitie = 1080;
if (found.user_data.is_pro_plus) window.fxapi.max_qualitie = 2160;
}
end_search(filmix_id);
}, function () {
end_search(filmix_id);
});
} else {
end_search(filmix_id);
}
function end_search(filmix_id) {
network.clear();
network.timeout(10000);
network.silent(Lampa.Utils.addUrlComponent(apiPath('post/' + filmix_id), devToken()), function (found) {
found = normalizePostResponse(found);
if (found && hasStreamLinks(found)) {
success(found);
component.loading(false);
} else if (found && found.id) component.empty(Lampa.Lang.translate('online_nostreams'));
else component.doesNotAnswer();
}, function (a, c) {
component.doesNotAnswer();
});
}
};
this.extendChoice = function (saved) {
Lampa.Arrays.extend(choice, saved, true);
};
this.reset = function () {
component.reset();
choice = {
season: 0,
voice: 0,
voice_name: ''
};
extractData(results);
filter();
append(filtred());
component.saveChoice(choice);
};
this.filter = function (type, a, b) {
choice[a.stype] = b.index;
if (a.stype == 'voice') choice.voice_name = filter_items.voice[b.index];
component.reset();
extractData(results);
filter();
append(filtred());
component.saveChoice(choice);
};
this.destroy = function () {
network.clear();
results = null;
};
function success(json) {
results = json;
extractData(json);
filter();
var items = filtred();
if (!items.length) {
component.doesNotAnswer();
return;
}
append(items);
}
function extractData(data) {
extract = {};
var pl_links = data.player_links;
if (isPlaylistMap(pl_links.playlist)) {
var seas_num = 0;
for (var season in pl_links.playlist) {
var episode = pl_links.playlist[season];
++seas_num;
var transl_id = 0;
var season_num = parseInt(season === '-1' ? '1' : season, 10);
for (var voice in episode) {
var episode_voice = episodeMap(episode[voice]);
++transl_id;
var items = [];
for (var ID in episode_voice) {
var file_episod = episode_voice[ID];
if (!file_episod || !file_episod.link) continue;
var quality_eps = file_episod.qualities.filter(function (qualitys) {
return qualitys > 0 && qualitys <= window.fxapi.max_qualitie;
});
if (!quality_eps.length) continue;
var max_quality = maxQuality(quality_eps);
var stream_url = file_episod.link.replace('%s.mp4', max_quality + '.mp4');
var s_e = stream_url.slice(0 - stream_url.length + stream_url.lastIndexOf('/'));
var str_s_e = s_e.match(/s(\d+)e(\d+?)_\d+\.mp4/i);
var _seas_num = season_num;
var _epis_num = parseInt(ID, 10);
if (str_s_e) {
_seas_num = parseInt(str_s_e[1], 10);
_epis_num = parseInt(str_s_e[2], 10);
} else if (isNaN(_epis_num)) {
continue;
}
items.push({
id: _seas_num + '_' + _epis_num,
comment: _epis_num + ' ' + Lampa.Lang.translate('torrent_serial_episode') + ' ' + ID + '',
file: stream_url,
episode: _epis_num,
season: _seas_num,
quality: max_quality,
qualities: quality_eps,
translation: transl_id
});
}
if (!extract[transl_id]) extract[transl_id] = {
json: [],
file: ''
};
extract[transl_id].json.push({
id: seas_num,
comment: seas_num + ' ' + Lampa.Lang.translate('torrent_serial_season'),
folder: items,
translation: transl_id
});
}
}
} else if (pl_links.movie && pl_links.movie.length > 0) {
if (pl_links.movie.length === 1 && isBlockedTranslation(pl_links.movie[0].translation)) {
return;
}
var _transl_id = 0;
for (var _ID in pl_links.movie) {
var _file_episod = pl_links.movie[_ID];
if (isBlockedTranslation(_file_episod.translation)) continue;
++_transl_id;
var _quality_eps = parseLinkQualities(_file_episod.link);
var _max_quality = maxQuality(_quality_eps);
if (!_max_quality) continue;
var file_url = _file_episod.link.replace(/_\[([\d,\s]*)\]\.mp4/i, '_' + _max_quality + '.mp4');
extract[_transl_id] = {
file: file_url,
translation: _file_episod.translation,
quality: _max_quality,
qualities: _quality_eps
};
}
}
}
function getFile(element, max_quality) {
var translat = extract[element.translation];
var id = element.season + '_' + element.episode;
var file = '';
var quality = false;
if (translat) {
if (element.season)
for (var i in translat.json) {
var elem = translat.json[i];
if (elem.folder)
for (var f in elem.folder) {
var folder = elem.folder[f];
if (folder.id == id) {
file = folder.file;
break;
}
} else {
if (elem.id == id) {
file = elem.file;
break;
}
}
} else file = translat.file;
}
max_quality = parseInt(max_quality);
if (file) {
var link = file.slice(0, file.lastIndexOf('_')) + '_';
var orin = file.split('?');
orin = orin.length > 1 ? '?' + orin.slice(1).join('?') : '';
if (file.split('_').pop().replace('.mp4', '') !== max_quality) {
file = link + max_quality + '.mp4' + orin;
}
quality = {};
var mass = [2160, 1440, 1080, 720, 480, 360];
mass = mass.slice(mass.indexOf(max_quality));
mass.forEach(function (n) {
quality[n + 'p'] = link + n + '.mp4' + orin;
});
var preferably = Lampa.Storage.get('video_quality_default', '1080') + 'p';
if (quality[preferably]) file = quality[preferably];
}
return {
file: file,
quality: quality
};
}
function filter() {
filter_items = {
season: [],
voice: [],
voice_info: []
};
var playlist = results.player_links.playlist;
if (isPlaylistMap(playlist)) {
playlistSeasonKeys(playlist).forEach(function (key) {
filter_items.season.push(Lampa.Lang.translate('torrent_serial_season') + ' ' + seasonLabel(key));
});
var seasonKeys = playlistSeasonKeys(playlist);
var seasonKey = seasonKeys[choice.season] || seasonKeys[0];
var seasonData = playlist[seasonKey];
var d = 0;
if (seasonData) {
for (var voic in seasonData) {
++d;
filter_items.voice.push(voic);
filter_items.voice_info.push({
id: d
});
}
}
} else if (results.last_episode && results.last_episode.season) {
var lastSeason = parseInt(results.last_episode.season, 10);
if (lastSeason > 0) {
var s = lastSeason;
while (s--) {
filter_items.season.push(Lampa.Lang.translate('torrent_serial_season') + ' ' + (lastSeason - s));
}
}
}
if (choice.voice_name) {
var inx = filter_items.voice.map(function (v) {
return v.toLowerCase();
}).indexOf(choice.voice_name.toLowerCase());
if (inx == -1) choice.voice = 0;
else if (inx !== choice.voice) {
choice.voice = inx;
}
}
if (choice.voice >= filter_items.voice.length) {
choice.voice = 0;
}
if (filter_items.voice.length) {
choice.voice_name = filter_items.voice[choice.voice] || '';
}
component.filter(filter_items, choice);
}
function filtred() {
var filtred = [];
if (isPlaylistMap(results.player_links.playlist)) {
for (var transl in extract) {
var element = extract[transl];
for (var season_id in element.json) {
var episode = element.json[season_id];
if (episode.id == choice.season + 1) {
episode.folder.forEach(function (media) {
if (media.translation == filter_items.voice_info[choice.voice].id) {
filtred.push({
episode: parseInt(media.episode),
season: media.season,
title: Lampa.Lang.translate('torrent_serial_episode') + ' ' + media.episode + (media.title ? ' - ' + media.title : ''),
quality: media.quality + 'p ',
translation: media.translation,
voice_name: filter_items.voice[choice.voice],
info: filter_items.voice[choice.voice]
});
}
});
}
}
}
} else if (Object.keys(results.player_links.movie).length) {
for (var transl_id in extract) {
var _element = extract[transl_id];
filtred.push({
title: _element.translation,
quality: _element.quality + 'p ',
qualitys: _element.qualities,
translation: transl_id,
voice_name: _element.translation
});
}
}
return filtred;
}
function toPlayElement(element) {
var extra = getFile(element, element.quality);
var play = {
title: element.title,
url: extra.file,
quality: extra.quality,
timeline: element.timeline,
callback: element.mark
};
return play;
}
function append(items) {
component.reset();
component.draw(items, {
similars: wait_similars,
onEnter: function onEnter(item, html) {
var extra = getFile(item, item.quality);
if (extra.file) {
var playlist = [];
var first = toPlayElement(item);
if (item.season) {
items.forEach(function (elem) {
playlist.push(toPlayElement(elem));
});
} else {
playlist.push(first);
}
if (playlist.length > 1) first.playlist = playlist;
Lampa.Player.play(first);
Lampa.Player.playlist(playlist);
item.mark();
} else Lampa.Noty.show(Lampa.Lang.translate('online_nolink'));
},
onContextMenu: function onContextMenu(item, html, data, call) {
call(getFile(item, item.quality));
}
});
}
}
function component(object) {
var network = new Lampa.Reguest();
var scroll = new Lampa.Scroll({
mask: true,
over: true
});
var files = new Lampa.Explorer(object);
var filter = new Lampa.Filter(object);
var sources = {
fxapi: fxapi
};
var last;
var extended;
var selected_id;
var source;
var balanser = 'fxapi';
var initialized;
var balanser_timer;
var images = [];
var filter_translate = {
season: Lampa.Lang.translate('torrent_serial_season'),
voice: Lampa.Lang.translate('torrent_parser_voice'),
source: Lampa.Lang.translate('settings_rest_source')
};
this.initialize = function () {
var _this = this;
source = this.createSource();
filter.onSearch = function (value) {
Lampa.Activity.replace({
search: value,
clarification: true
});
};
filter.onBack = function () {
_this.start();
};
filter.render().find('.selector').on('hover:enter', function () {
clearInterval(balanser_timer);
});
filter.onSelect = function (type, a, b) {
if (type == 'filter') {
if (a.reset) {
if (extended) source.reset();
else _this.start();
} else {
source.filter(type, a, b);
}
} else if (type == 'sort') {
Lampa.Select.close();
}
};
if (filter.addButtonBack) filter.addButtonBack();
filter.render().find('.filter--sort').remove();
files.appendFiles(scroll.render());
files.appendHead(filter.render());
scroll.body().addClass('torrent-list');
scroll.minus(files.render().find('.explorer__files-head'));
this.search();
};
this.createSource = function () {
return new sources[balanser](this, object);
};
/**
* Подготовка
*/
this.create = function () {
return this.render();
};
/**
* Начать поиск
*/
this.search = function () {
this.activity.loader(true);
this.find();
};
this.find = function () {
if (source.searchByTitle) {
this.extendChoice();
source.searchByTitle(object, object.search || object.movie.original_title || object.movie.original_name || object.movie.title || object.movie.name);
}
};
this.getChoice = function (for_balanser) {
var data = Lampa.Storage.cache('online_choice_' + (for_balanser || balanser), 3000, {});
var save = data[selected_id || object.movie.id] || {};
Lampa.Arrays.extend(save, {
season: 0,
voice: 0,
voice_name: '',
voice_id: 0,
episodes_view: {},
movie_view: ''
});
return save;
};
this.extendChoice = function () {
extended = true;
source.extendChoice(this.getChoice());
};
this.saveChoice = function (choice, for_balanser) {
var data = Lampa.Storage.cache('online_choice_' + (for_balanser || balanser), 3000, {});
data[selected_id || object.movie.id] = choice;
Lampa.Storage.set('online_choice_' + (for_balanser || balanser), data);
};
/**
* Есть похожие карточки
* @param {Object} json
*/
this.similars = function (json) {
var _this3 = this;
json.forEach(function (elem) {
var info = [];
var year = ((elem.start_date || elem.year || '') + '').slice(0, 4);
if (elem.rating && elem.rating !== 'null' && elem.filmId) info.push(Lampa.Template.get('online_prestige_rate', {
rate: elem.rating
}, true));
if (year) info.push(year);
if (elem.countries && elem.countries.length) {
info.push((elem.filmId ? elem.countries.map(function (c) {
return c.country;
}) : elem.countries).join(', '));
}
if (elem.categories && elem.categories.length) {
info.push(elem.categories.slice(0, 4).join(', '));
}
var name = elem.title || elem.ru_title || elem.en_title || elem.nameRu || elem.nameEn;
var orig = elem.orig_title || elem.nameEn || '';
elem.title = name + (orig && orig !== name ? ' / ' + orig : '');
elem.time = elem.filmLength || '';
elem.info = info.join('●');
var item = Lampa.Template.get('online_prestige_folder', elem);
item.on('hover:enter', function () {
_this3.activity.loader(true);
_this3.reset();
object.search_date = year;
selected_id = elem.id;
_this3.extendChoice();
if (source.search) {
source.search(object, [elem]);
} else {
_this3.doesNotAnswer();
}
}).on('hover:focus', function (e) {
last = e.target;
scroll.update($(e.target), true);
});
scroll.append(item);
});
};
this.clearImages = function () {
images.forEach(function (img) {
img.onerror = function () { };
img.onload = function () { };
img.src = '';
});
images = [];
};
/**
* Очистить список файлов
*/
this.reset = function () {
last = false;
clearInterval(balanser_timer);
network.clear();
this.clearImages();
scroll.render().find('.empty').remove();
scroll.clear();
};
/**
* Загрузка
*/
this.loading = function (status) {
if (status) this.activity.loader(true);
else {
this.activity.loader(false);
this.activity.toggle();
}
};
/**
* Построить фильтр
*/
this.filter = function (filter_items, choice) {
var _this4 = this;
var select = [];
var add = function add(type, title) {
var need = _this4.getChoice();
var items = filter_items[type];
var subitems = [];
var value = need[type];
items.forEach(function (name, i) {
subitems.push({
title: name,
selected: value == i,
index: i
});
});
select.push({
title: title,
subtitle: items[value],
items: subitems,
stype: type
});
};
select.push({
title: Lampa.Lang.translate('torrent_parser_reset'),
reset: true
});
this.saveChoice(choice);
if (filter_items.voice && filter_items.voice.length) add('voice', Lampa.Lang.translate('torrent_parser_voice'));
if (filter_items.season && filter_items.season.length) add('season', Lampa.Lang.translate('torrent_serial_season'));
filter.set('filter', select);
this.selected(filter_items);
};
/**
* Закрыть фильтр
*/
this.closeFilter = function () {
if ($('body').hasClass('selectbox--open')) Lampa.Select.close();
};
/**
* Показать что выбрано в фильтре
*/
this.selected = function (filter_items) {
var need = this.getChoice(),
select = [];
for (var i in need) {
if (filter_items[i] && filter_items[i].length) {
if (i == 'voice') {
select.push(filter_translate[i] + ': ' + filter_items[i][need[i]]);
} else if (i !== 'source') {
if (filter_items.season.length >= 1) {
select.push(filter_translate.season + ': ' + filter_items[i][need[i]]);
}
}
}
}
filter.chosen('filter', select);
filter.chosen('sort', [balanser]);
};
this.getEpisodes = function (season, call) {
var episodes = [];
if (typeof object.movie.id == 'number' && object.movie.name) {
var tmdburl = 'tv/' + object.movie.id + '/season/' + season + '?api_key=' + Lampa.TMDB.key() + '&language=' + Lampa.Storage.get('language', 'ru');
var baseurl = Lampa.TMDB.api(tmdburl);
network.timeout(1000 * 10);
network["native"](baseurl, function (data) {
episodes = data.episodes || [];
call(episodes);
}, function (a, c) {
call(episodes);
});
} else call(episodes);
};
/**
* Добавить элементы в список
*/
this.append = function (item) {
item.on('hover:focus', function (e) {
last = e.target;
scroll.update($(e.target), true);
});
scroll.append(item);
};
this.watched = function (set) {
var file_id = Lampa.Utils.hash(object.movie.number_of_seasons ? object.movie.original_name : object.movie.original_title);
var watched = Lampa.Storage.cache('online_watched_last', 5000, {});
if (set) {
if (!watched[file_id]) watched[file_id] = {};
Lampa.Arrays.extend(watched[file_id], set, true);
Lampa.Storage.set('online_watched_last', watched);
} else {
return watched[file_id];
}
};
/**
* Отрисовка файлов
*/
this.draw = function (items) {
var _this5 = this;
var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (!items.length) return this.empty();
this.getEpisodes(items[0].season, function (episodes) {
var viewed = Lampa.Storage.cache('online_view', 5000, []);
var serial = object.movie.name ? true : false;
var choice = _this5.getChoice();
var fully = window.innerWidth > 480;
var scroll_to_element = false;
var scroll_to_mark = false;
items.forEach(function (element, index) {
var episode = serial && episodes.length && !params.similars ? episodes.find(function (e) {
return e.episode_number == element.episode;
}) : false;
var episode_num = element.episode || index + 1;
var episode_last = choice.episodes_view[element.season];
Lampa.Arrays.extend(element, {
info: '',
quality: '',
time: Lampa.Utils.secondsToTime((episode ? episode.runtime : object.movie.runtime) * 60, true)
});
var hash_timeline = Lampa.Utils.hash(element.season ? [element.season, element.episode, object.movie.original_title].join('') : object.movie.original_title);
var hash_behold = Lampa.Utils.hash(element.season ? [element.season, element.episode, object.movie.original_title, element.voice_name].join('') : object.movie.original_title + element.voice_name);
var data = {
hash_timeline: hash_timeline,
hash_behold: hash_behold
};
var info = [];
if (element.season) {
element.translate_episode_end = _this5.getLastEpisode(items);
element.translate_voice = element.voice_name;
}
element.timeline = Lampa.Timeline.view(hash_timeline);
if (episode) {
element.title = episode.name;
if (element.info.length < 30 && episode.vote_average) info.push(Lampa.Template.get('online_prestige_rate', {
rate: parseFloat(episode.vote_average + '').toFixed(1)
}, true));
if (episode.air_date && fully) info.push(Lampa.Utils.parseTime(episode.air_date).full);
} else if (object.movie.release_date && fully) {
info.push(Lampa.Utils.parseTime(object.movie.release_date).full);
}
if (!serial && object.movie.tagline && element.info.length < 30) info.push(object.movie.tagline);
if (element.info) info.push(element.info);
if (info.length) element.info = info.map(function (i) {
return '' + i + '';
}).join('●');
var html = Lampa.Template.get('online_prestige_full', element);
var loader = html.find('.online-prestige__loader');
var image = html.find('.online-prestige__img');
if (!serial) {
if (choice.movie_view == hash_behold) scroll_to_element = html;
} else if (typeof episode_last !== 'undefined' && episode_last == episode_num) {
scroll_to_element = html;
}
if (serial && !episode) {
image.append('