<commit_before>﻿var hoverZoomPlugins = hoverZoomPlugins || [];
hoverZoomPlugins.push({
    name:'YouTube',
    prepareImgLinks:function (callback) {
        var res = [];

        function getSource(sources, type, quality) {
            var lowest = null, exact = null;
            for (var source of sources) {
                if (source.mimeType.indexOf(type) !== -1) {
                    if (source.quality.indexOf(quality) !== -1) {
                        exact = source;
                    } else {
                        lowest = source;
                    }
                }
            }
            return exact || lowest;
        }

        function prepareVideoPreview(link, id) {
            if (link.hasClass('hoverZoomLoading') || link.hasClass('hoverZoomLink') || link.hasClass('ytp-title-link')) return;
            link.addClass('hoverZoomLoading');

            var match = link.attr('href').match(/[\?&]t=([\dhm]+)/);
            var start = match && match.length >= 2 ? match[1] : null;
            if (start && start.indexOf('m') !== -1) {
                var parts = start.split('m');
                if (parts.length == 2) {
                    var parts2 = start.split('h');
                    if (parts2.length == 2)
                        parts[0] = parseInt(parts2[0]) * 60 + parseInt(parts2[1]);
                    start = parseInt(parts[0]) * 60 + parseInt(parts[1] || 0);
                }
            }

            chrome.runtime.sendMessage({action:'ajaxGet', url: 'https://www.youtube.com/watch?v=' + id}, function(data) {
                link.removeClass('hoverZoomLoading');
                const match = data.match(/ytInitialPlayerResponse\s*=\s*(\{.+?\})\s*;/);
                if (match && match.length >= 2) {
                    const json = JSON.parse(match[1]);
                    const formats = json.streamingData.formats;
//                    const adaptiveFormats = json.streamingData.adaptiveFormats;
                    let src = getSource(formats, "mp4", "hd1080") || getSource(formats, "webm", "hd1080");
//                        || getSource(adaptiveFormats, "webm", "hd720") || getSource(adaptiveFormats, "mp4", "hd720");
                    if (src && src.url) {
                        link.data().hoverZoomSrc = [start ? src.url + '#t=' + start : src.url];
                        link.addClass('hoverZoomLink');
                        hoverZoom.displayPicFromElement(link);
                    }
                }
            });
        }

        $('a[href*="youtu.be/"]').one('mouseenter', function () {
            var link = $(this), match = this.href.match(/^.*youtu.be\/([\w-]+).*$/);
            if (!match || match.length < 2) return;
            prepareVideoPreview(link, match[1]);
        });

        $('a[href*="youtube.com/shorts/"]').one('mouseenter', function () {
            var link = $(this), match = this.href.match(/^.*\/shorts\/([\w-]+).*$/);
            if (!match || match.length < 2) return;
            prepareVideoPreview(link, match[1]);
        });<commit_msg>Add a todo for youtube plugin<commit_after>﻿var hoverZoomPlugins = hoverZoomPlugins || [];
hoverZoomPlugins.push({
    name:'YouTube',
    prepareImgLinks:function (callback) {
        var res = [];

        function getSource(sources, type, quality) {
            var lowest = null, exact = null;
            for (var source of sources) {
                if (source.mimeType.indexOf(type) !== -1) {
                    if (source.quality.indexOf(quality) !== -1) {
                        exact = source;
                    } else {
                        lowest = source;
                    }
                }
            }
            return exact || lowest;
        }

        function prepareVideoPreview(link, id) {
            if (link.hasClass('hoverZoomLoading') || link.hasClass('hoverZoomLink') || link.hasClass('ytp-title-link')) return;
            link.addClass('hoverZoomLoading');

            var match = link.attr('href').match(/[\?&]t=([\dhm]+)/);
            var start = match && match.length >= 2 ? match[1] : null;
            if (start && start.indexOf('m') !== -1) {
                var parts = start.split('m');
                if (parts.length == 2) {
                    var parts2 = start.split('h');
                    if (parts2.length == 2)
                        parts[0] = parseInt(parts2[0]) * 60 + parseInt(parts2[1]);
                    start = parseInt(parts[0]) * 60 + parseInt(parts[1] || 0);
                }
            }

            chrome.runtime.sendMessage({action:'ajaxGet', url: 'https://www.youtube.com/watch?v=' + id}, function(data) {
                link.removeClass('hoverZoomLoading');
                const match = data.match(/ytInitialPlayerResponse\s*=\s*(\{.+?\})\s*;/);
                if (match && match.length >= 2) {
                    const json = JSON.parse(match[1]);
                    const formats = json.streamingData.formats;
                    const adaptiveFormats = json.streamingData.adaptiveFormats;
                    let src = getSource(formats, "mp4", "hd1080") || getSource(formats, "webm", "hd1080")
                        || getSource(adaptiveFormats, "webm", "hd720") || getSource(adaptiveFormats, "mp4", "hd720");
                    // TODO: Figure out how to decode youtube signature for embedded players
                    // if (!src.url && src.signatureCipher) {
                    //     let parts = src.signatureCipher.split('&');
                    //     let sig = null;
                    //     for (const part of parts) {
                    //         console.log(part);
                    //         let sides = part.split('=');
                    //         if (sides[0] === 's') {
                    //             sig = decodeURIComponent(sides[1]);
                    //         }
                    //         if (sides[0] === 'url') {
                    //             src.url = decodeURIComponent(sides[1]);
                    //         }
                    //     }
                    // }
                    if (src && src.url) {
                        link.data().hoverZoomSrc = [start ? src.url + '#t=' + start : src.url];
                        link.addClass('hoverZoomLink');
                        hoverZoom.displayPicFromElement(link);
                    }
                }
            });
        }

        $('a[href*="youtu.be/"]').one('mouseenter', function () {
            var link = $(this), match = this.href.match(/^.*youtu.be\/([\w-]+).*$/);
            if (!match || match.length < 2) return;
            prepareVideoPreview(link, match[1]);
        });

        $('a[href*="youtube.com/shorts/"]').one('mouseenter', function () {
            var link = $(this), match = this.href.match(/^.*\/shorts\/([\w-]+).*$/);
            if (!match || match.length < 2) return;
            prepareVideoPreview(link, match[1]);
        });
{'fraction_non_alphanumeric': 0.1605471562275018, 'fraction_numerical': 0.012958963282937365, 'mean_word_length': 1.4176818656456665, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1417336', 'n_tokens_mistral': 1982, 'n_tokens_neox': 1850, 'n_words': 356}