<commit_before>import * as xhr from 'common/xhr';

type LinkType = 'youtube' | 'study' | 'game' | 'twitter';

interface Parsed {
  type: LinkType;
  src: string;
}
interface Candidate {
  element: HTMLAnchorElement;
  parent: HTMLElement;
  type: LinkType;
  src: string;
}

interface Group {
  parent: HTMLElement | null;
  index: number;
}

function toYouTubeEmbedUrl(url: string) {
  const m = url?.match(
    /(?:https?:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch)?(?:\?v=)?([^"&?/ ]{11})(?:\?|&|)(\S*)/i
  );
  if (!m) return;
  let start = 0;
  m[2].split('&').forEach(p => {
    const s = p.split('=');
    if (s[0] === 't' || s[0] === 'start') {
      if (s[1].match(/^\d+$/)) start = parseInt(s[1]);
      else {
        const n = s[1].match(/(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?/);
        start = n ? (parseInt(n[1]) || 0) * 3600 + (parseInt(n[2]) || 0) * 60 + (parseInt(n[3]) || 0) : 0;
      }
    }
  });
  const params = 'modestbranding=1&rel=0&controls=2&iv_load_policy=3&start=' + start;
  return 'https://www.youtube.com/embed/' + m[1] + '?' + params;
}

function toTwitterEmbedUrl(url: string) {
  const m = url?.match(/(?:https?:\/\/)?(?:www\.)?(?:twitter\.com)\/([^/]+\/status\/\d+)/i);
  return m && `https://twitter.com/${m[1]}`;
}

lichess.load.then(() => {
  const domain = window.location.host,
    chapterRegex = new RegExp(domain + '/study/(?:embed/)?(\\w{8})/(\\w{8})(#\\d+)?\\b'),
    studyRegex = new RegExp(domain + '/study/(?:embed/)?(\\w{8})(#\\d+)?\\b'),
    gameRegex = new RegExp(domain + '/(?:embed/)?(\\w{8})(?:(?:/(white|black))|\\w{4}|)(#\\d+)?\\b'),
    notGames = ['training', 'analysis', 'insights', 'practice', 'features', 'password', 'streamer', 'timeline'];

  function parseLink(a: HTMLAnchorElement): Parsed | undefined {
    const tw = toTwitterEmbedUrl(a.href);
    if (tw)
      return {
        type: 'twitter',
        src: tw,
      };
    const yt = toYouTubeEmbedUrl(a.href);
    if (yt)
      return {
        type: 'youtube',
        src: yt,
      };
    let matches = a.href.match(chapterRegex);
    if (matches && matches[2] && a.text.match(chapterRegex))
      return {
        type: 'study',
        src: `/study/embed/${matches[1]}/${matches[2]}${matches[3] || ''}`,
      };
    matches = a.href.match(studyRegex);
    if (matches && matches[1] && a.text.match(studyRegex))
      return {
        type: 'study',
        src: `/study/embed/${matches[1]}/autochap${matches[2] || ''}`,
      };
    matches = a.href.match(gameRegex);
    if (matches && matches[1] && !notGames.includes(matches[1]) && a.text.match(gameRegex)) {
      let src = '/embed/game/' + matches[1];
      if (matches[2]) src += '/' + matches[2]; // orientation
      if (matches[3]) src += matches[3]; // ply hash
      return {
        type: 'game',
        src: src,
      };
    }
  }

  function expandYoutube(a: Candidate) {
    const $iframe = $('<div class="embed"><iframe src="' + a.src + '"></iframe></div>');
    $(a.element).replaceWith($iframe);
    return $iframe;
  }

  function expandYoutubes(as: Candidate[], wait = 100) {
    wait = Math.min(1500, wait);
    const a = as.shift();
    if (a)
      expandYoutube(a)
        .find('iframe')
        .on('load', function () {
          setTimeout(function () {
            expandYoutubes(as, wait + 200);
          }, wait);
        });
  }

  let twitterLoaded = false;
  function expandTwitter(a: Candidate) {
    const theme = $('body').data('theme') == 'light' ? 'light' : 'dark';
    $(a.element).replaceWith(
      $(
        `<blockquote class="twitter-tweet" data-dnt="true" data-theme="${theme}"><a href="${a.src}">${a.src}</a></blockquote>`
      )
    );
    if (!twitterLoaded) {
      twitterLoaded = true;
      xhr.script('https://platform.twitter.com/widgets.js');
    }
  }

  function expand(a: Candidate) {
    const $iframe: any = $('<iframe>')
      .addClass('analyse ' + a.type)
      .attr('src', a.src);
    $(a.element).replaceWith($('<div class="embed embed--game">').prepend($iframe));
    return $iframe
      .on('load', function (this: HTMLIFrameElement) {<commit_msg>TS code golf<commit_after>import * as xhr from 'common/xhr';

type LinkType = 'youtube' | 'study' | 'game' | 'twitter';

interface Parsed {
  type: LinkType;
  src: string;
}
interface Candidate {
  element: HTMLAnchorElement;
  parent: HTMLElement;
  type: LinkType;
  src: string;
}

interface Group {
  parent: HTMLElement | null;
  index: number;
}

function toYouTubeEmbedUrl(url: string) {
  const m = url?.match(
    /(?:https?:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch)?(?:\?v=)?([^"&?/ ]{11})(?:\?|&|)(\S*)/i
  );
  if (!m) return;
  let start = 0;
  m[2].split('&').forEach(p => {
    const s = p.split('=');
    if (s[0] === 't' || s[0] === 'start') {
      if (s[1].match(/^\d+$/)) start = parseInt(s[1]);
      else {
        const n = s[1].match(/(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?/);
        start = n ? (parseInt(n[1]) || 0) * 3600 + (parseInt(n[2]) || 0) * 60 + (parseInt(n[3]) || 0) : 0;
      }
    }
  });
  const params = 'modestbranding=1&rel=0&controls=2&iv_load_policy=3&start=' + start;
  return 'https://www.youtube.com/embed/' + m[1] + '?' + params;
}

function toTwitterEmbedUrl(url: string) {
  const m = url?.match(/(?:https?:\/\/)?(?:www\.)?(?:twitter\.com)\/([^/]+\/status\/\d+)/i);
  return m && `https://twitter.com/${m[1]}`;
}

lichess.load.then(() => {
  const domain = window.location.host,
    chapterRegex = new RegExp(domain + '/study/(?:embed/)?(\\w{8})/(\\w{8})(#\\d+)?\\b'),
    studyRegex = new RegExp(domain + '/study/(?:embed/)?(\\w{8})(#\\d+)?\\b'),
    gameRegex = new RegExp(domain + '/(?:embed/)?(\\w{8})(?:(?:/(white|black))|\\w{4}|)(#\\d+)?\\b'),
    notGames = ['training', 'analysis', 'insights', 'practice', 'features', 'password', 'streamer', 'timeline'];

  function parseLink(a: HTMLAnchorElement): Parsed | undefined {
    const tw = toTwitterEmbedUrl(a.href);
    if (tw)
      return {
        type: 'twitter',
        src: tw,
      };
    const yt = toYouTubeEmbedUrl(a.href);
    if (yt)
      return {
        type: 'youtube',
        src: yt,
      };
    let matches = a.href.match(chapterRegex);
    if (matches && matches[2] && a.text.match(chapterRegex))
      return {
        type: 'study',
        src: `/study/embed/${matches[1]}/${matches[2]}${matches[3] || ''}`,
      };
    matches = a.href.match(studyRegex);
    if (matches && matches[1] && a.text.match(studyRegex))
      return {
        type: 'study',
        src: `/study/embed/${matches[1]}/autochap${matches[2] || ''}`,
      };
    matches = a.href.match(gameRegex);
    if (matches && matches[1] && !notGames.includes(matches[1]) && a.text.match(gameRegex)) {
      let src = '/embed/game/' + matches[1];
      if (matches[2]) src += '/' + matches[2]; // orientation
      if (matches[3]) src += matches[3]; // ply hash
      return {
        type: 'game',
        src: src,
      };
    }
  }

  function expandYoutube(a: Candidate) {
    const $iframe = $('<div class="embed"><iframe src="' + a.src + '"></iframe></div>');
    $(a.element).replaceWith($iframe);
    return $iframe;
  }

  function expandYoutubes(as: Candidate[], wait = 100) {
    wait = Math.min(1500, wait);
    const a = as.shift();
    if (a)
      expandYoutube(a)
        .find('iframe')
        .on('load', () => setTimeout(() => expandYoutubes(as, wait + 200), wait));
  }

  let twitterLoaded = false;
  function expandTwitter(a: Candidate) {
    const theme = $('body').data('theme') == 'light' ? 'light' : 'dark';
    $(a.element).replaceWith(
      $(
        `<blockquote class="twitter-tweet" data-dnt="true" data-theme="${theme}"><a href="${a.src}">${a.src}</a></blockquote>`
      )
    );
    if (!twitterLoaded) {
      twitterLoaded = true;
      xhr.script('https://platform.twitter.com/widgets.js');
    }
  }

  function expand(a: Candidate) {
    const $iframe: any = $('<iframe>')
      .addClass('analyse ' + a.type)
      .attr('src', a.src);
    $(a.element).replaceWith($('<div class="embed embed--game">').prepend($iframe));
    return $iframe
      .on('load', function (this: HTMLIFrameElement) {
{'fraction_non_alphanumeric': 0.24119739909213594, 'fraction_numerical': 0.013986013986013986, 'mean_word_length': 2.8690080683436165, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 29, 'https://': 6, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5254988', 'n_tokens_mistral': 3062, 'n_tokens_neox': 2947, 'n_words': 543}