<commit_before>// ==UserScript==
// @name         find-me-at-thbwiki
// @namespace    Gizeta.Debris.FindMeAtTHBWiki
// @version      0.1
// @description  Find selection text on THBWiki
// @author       Gizeta
// @match        *://*/*
// @grant        none
// ==/UserScript==

/* jshint esversion: 6 */

const API = 'https://thwiki.cc/api.php?action=query&format=json&uselang=zh&list=search&srlimit=1&srsearch=';

function getTooltipTarget(create = false) {
  const target = document.getElementById('find-me-at-thbwiki-tooltip');
  if (!create || target)
    return target;
  const tooltip = document.createElement('div');
  tooltip.id = 'find-me-at-thbwiki-tooltip';
  tooltip.style.position = 'absolute';
  tooltip.style.backgroundColor = '#ddd';
  tooltip.style.maxWidth = '50%';
  tooltip.style.padding = '5px';
  document.body.appendChild(tooltip);
  return tooltip;
}

function getPosition() {
  const rect = document.getSelection().getRangeAt(0).getBoundingClientRect();
  const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  const top = Math.floor(scrollTop + rect.top + rect.height);
  const left = Math.floor(rect.left);
  return [top, left];
}

function showTooltip(title, content) {
  const tooltip = getTooltipTarget(true);
  const [top, left] = getPosition();
  tooltip.style.display = 'block';
  tooltip.style.top = `${top}px`;
  tooltip.style.left = `${left}px`;
  tooltip.innerHTML = `<h3><a href="https://thwiki.cc/${title}" target="_blank" rel="noopener noreferrer">${title}</a></h3><div>${content}</div>`;
}

function hideToolip() {
  if (getTooltipTarget())
    getTooltipTarget().style.display = 'none';
}

document.body.addEventListener("mouseup", () => {
  const selection = document.getSelection();
  if (!selection || selection.type === "Caret") {
    hideToolip();
    return;
  }
  fetch(API + selection.toString().trim()).then(resp => resp.json()).then(data => {
    if (data.query && data.query.search && data.query.search.length > 0)
      showTooltip(data.query.search[0].title, data.query.search[0].snippet);
    else
      showTooltip('', 'not found');
  });
});
<commit_msg>Update find-me-at-thbwiki.user.js<commit_after>// ==UserScript==
// @name         find-me-at-thbwiki
// @namespace    Gizeta.Debris.FindMeAtTHBWiki
// @version      0.1.1
// @description  Find selection text on THBWiki
// @author       Gizeta
// @match        *://*/*
// @grant        none
// ==/UserScript==

/* jshint esversion: 6 */

const API = 'https://thwiki.cc/api.php?action=query&format=json&uselang=zh&list=search&srlimit=5&srsearch=';

function getTooltipTarget(create = false) {
  const target = document.getElementById('find-me-at-thbwiki-tooltip');
  if (!create || target)
    return target;
  const tooltip = document.createElement('div');
  tooltip.id = 'find-me-at-thbwiki-tooltip';
  tooltip.style.position = 'absolute';
  tooltip.style.backgroundColor = '#ddd';
  tooltip.style.maxWidth = '50%';
  tooltip.style.padding = '5px';
  document.body.appendChild(tooltip);
  return tooltip;
}

function getPosition() {
  const rect = document.getSelection().getRangeAt(0).getBoundingClientRect();
  const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  const top = Math.floor(scrollTop + rect.top + rect.height);
  const left = Math.floor(rect.left);
  return [top, left];
}

function showTooltip(result) {
  const tooltip = getTooltipTarget(true);
  const [top, left] = getPosition();
  tooltip.style.display = 'block';
  tooltip.style.fontSize = '14px';
  tooltip.style.color = 'black';
  tooltip.style.top = `${top}px`;
  tooltip.style.left = `${left}px`;
  tooltip.innerHTML = result.map(([title, content]) => `<h3><a href="https://thwiki.cc/${title}" target="_blank" rel="noopener noreferrer">${title}</a></h3><div>${content}</div>`);
}

function hideToolip() {
  if (getTooltipTarget())
    getTooltipTarget().style.display = 'none';
}

document.body.addEventListener("mouseup", () => {
  const selection = document.getSelection();
  if (!selection || selection.type === "Caret") {
    hideToolip();
    return;
  }
  fetch(API + selection.toString().trim()).then(resp => resp.json()).then(data => {
    if (data.query && data.query.search && data.query.search.length > 0)
      showTooltip(data.query.search.map(x => [x.title, x.snippet]));
    else
      showTooltip('', 'not found');
  });
});
<|endoftext|>


<commit_before>var eassApp = angular.module(
	"eassApp",
	[
		'ngAnimate'
	]
);

eassApp
.controller('HomeImgCtrl',
[
'$scope', '$timeout',
function($scope, $timeout)
{
	$scope.slides = [
		{name: 'renhold'},
		{name: 'kantine'},
		{name: 'vaktmesterservice'}
	];

	$scope.id = 1;

	$scope.to = null;

	$scope.change = function( id ) {
		$scope.id = id;

		$timeout.cancel($scope.to);
	};

	$scope.isCurrent = function (index) {
		return $scope.id === index;
	};

	$scope.reset = function() {
		$scope.to = $timeout($scope.tick, 2000);
	};

	$scope.tick = function () {
		if ( $scope.id == 2 ) {
			$scope.id = 0;
		} else {
			$scope.id++;
		}

		$scope.to = $timeout($scope.tick, 2000);
	};

	$scope.tick();
}
]
);

eassApp
.controller('SidebarPageCtrl',
[
'$scope', '$location', '$compile',
function($scope, $location, $compile)
{
	var headers = angular.element(".panel-body h3" );

	if ( headers.length <= 1 ) {
		// Nothing to partition
		return;
	}

	$scope.choices = [];

	var checkExisting = function( name ) {
		if ( $scope.choices.length == 0 ) return false;

		for ( var i=0; i<$scope.choices.length; i++ ) {
			if ( $scope.choices[i].id == name ) return true;
		}

		return false;
	};

	var i = 0;

	angular.forEach(headers, function(value, key){
		i++;

		var element = {
			id: angular.element(value).html().toLowerCase().replace(/[^a-z0-9]/gi,''),
			title: angular.element(value).html()
		};

		if ( !checkExisting(element.id) ) {
			$scope.choices.push(element);
		}

		var content = angular.element(value).nextUntil("h3").andSelf();

		var newhtml = '';

		var replace;

		for ( var j=0; j<content.length; j++ ) {
			newhtml += angular.element(content[j]).clone().wrap('
').parent().html();

			if ( j < content.length-1 ) {
				angular.element(content[j]).remove();

				delete content[j];
			} else {
				replace = content[j];
			}
		}

		newhtml.replace('

', '
').replace('

', '
');

		angular.element(replace).replaceWith(
			$compile(
				'
'
				+ newhtml
				+ '
'
			)($scope)
		);
	});

	$scope.change = function( name ) {
		if ( $scope.id === name ) {
			return;
		} else {
			$scope.id = name;
		}

		$location.hash($scope.id);
	};

	$scope.isDeselected = function ( name ) {
		return $scope.id !== name && $scope.id != '';
	};

	$scope.isSelected = function ( name ) {
		return $scope.id === name;
	};

	$scope.id = $location.hash();

	if ( $scope.id == '' ) {
		$scope.change( $scope.choices[0].id );
	}
}
]
);

eassApp
.controller('SidebarPageListCtrl',
[
'$scope', '$location', '$compile',
function($scope, $location, $compile)
{
	var list = angular.element(".panel-body ul li");

	if ( list.length <= 1 ) {
		// Nothing to partition
		return;
	}

	var headers = angular.element(".panel-body h4" );

	if ( headers.length <= 1 ) {
		// Nothing to partition
		return;
	}

	$scope.choices = [];

	angular.forEach(list, function(value, key) {
		$scope.choices.push(
			{
				id: angular.element(value).html().toLowerCase().replace(/[^a-z0-9]/gi,''),
				title: angular.element(value).html()
			}
		);
	});

	angular.element(".panel-body ul" ).remove();

	var i = 0;
	angular.forEach(headers, function(value, key) {
		i++;

		var element = {
			id: angular.element(value).html().toLowerCase().replace(/[^a-z0-9]/gi,''),
			title: angular.element(value).html()
		};

		var content = angular.element(value).nextUntil("h4").andSelf();

		var newhtml = '';

		var id;

		var replace;

		var name = '';

		var inner = '';

		for ( var j=0; j<content.length; j++ ) {
			var el = angular.element(content[j]);

			inner = el.clone().wrap('
').parent().html();

			if ( name == '' ) {
				elname = el.html().toLowerCase().replace(/[^a-z0-9]/gi,'');

				angular.forEach($scope.choices, function(value, key) {
					if ( elname == value.id ) {
						name = value.id;

						if ( el.context.localName != 'h4' ) {
							inner = '';
						}
					}
				});
			}

			newhtml += inner;

			if ( j < content.length-1 ) {
				angular.element(content[j]).remove();

				delete content[j];
			} else {
				replace = content[j];
			}
		}

		newhtml.replace('

', '
').replace('

', '
');

		angular.element(replace).replaceWith(
			$compile(
				'
'
					+ newhtml
					+ '
'
			)($scope)
		);
	});

	$scope.change = function( name ) {
		if ( $scope.id === name ) {
			$scope.id = '';
		} else {
			$scope.id = name;
		}

		$location.hash($scope.id);
	};

	$scope.isDeselected = function ( name ) {
		return $scope.id !== name && $scope.id != '';
	};

	$scope.isSelected = function ( name ) {
		return $scope.id === name;
	};

	$scope.id = $location.hash();
}
]
);

eassApp
.controller('ContactCtrl',
[
'$scope',
function($scope) {
	$scope.id = '';

	$scope.change = function( name ) {
		if ( $scope.id === name ) {
			$scope.id = '';
		} else {
			$scope.id = name;
		}
	};

	$scope.isDeselected = function ( name ) {
		return $scope.id !== name && $scope.id != '';
	};

	$scope.isSelected = function ( name ) {
		return $scope.id === name;
	};
}
]
);
<commit_msg>fixing
eaks, dangit<commit_after>var eassApp = angular.module(
	"eassApp",
	[
		'ngAnimate'
	]
);

eassApp
.controller('HomeImgCtrl',
[
'$scope', '$timeout',
function($scope, $timeout)
{
	$scope.slides = [
		{name: 'renhold'},
		{name: 'kantine'},
		{name: 'vaktmesterservice'}
	];

	$scope.id = 1;

	$scope.to = null;

	$scope.change = function( id ) {
		$scope.id = id;

		$timeout.cancel($scope.to);
	};

	$scope.isCurrent = function (index) {
		return $scope.id === index;
	};

	$scope.reset = function() {
		$scope.to = $timeout($scope.tick, 2000);
	};

	$scope.tick = function () {
		if ( $scope.id == 2 ) {
			$scope.id = 0;
		} else {
			$scope.id++;
		}

		$scope.to = $timeout($scope.tick, 2000);
	};

	$scope.tick();
}
]
);

eassApp
.controller('SidebarPageCtrl',
[
'$scope', '$location', '$compile',
function($scope, $location, $compile)
{
	var headers = angular.element(".panel-body h3" );

	if ( headers.length <= 1 ) {
		// Nothing to partition
		return;
	}

	$scope.choices = [];

	var checkExisting = function( name ) {
		if ( $scope.choices.length == 0 ) return false;

		for ( var i=0; i<$scope.choices.length; i++ ) {
			if ( $scope.choices[i].id == name ) return true;
		}

		return false;
	};

	var i = 0;

	angular.forEach(headers, function(value, key){
		i++;

		var element = {
			id: angular.element(value).html().toLowerCase().replace(/[^a-z0-9]/gi,''),
			title: angular.element(value).html()
		};

		if ( !checkExisting(element.id) ) {
			$scope.choices.push(element);
		}

		var content = angular.element(value).nextUntil("h3").andSelf();

		var newhtml = '';

		var replace;

		for ( var j=0; j<content.length; j++ ) {
			newhtml += angular.element(content[j]).clone().wrap('
').parent().html();

			if ( j < content.length-1 ) {
				angular.element(content[j]).remove();

				delete content[j];
			} else {
				replace = content[j];
			}
		}

		newhtml = newhtml.replace('

', '
');

		angular.element(replace).replaceWith(
			$compile(
				'
'
				+ newhtml
				+ '
'
			)($scope)
		);
	});

	$scope.change = function( name ) {
		if ( $scope.id === name ) {
			return;
		} else {
			$scope.id = name;
		}

		$location.hash($scope.id);
	};

	$scope.isDeselected = function ( name ) {
		return $scope.id !== name && $scope.id != '';
	};

	$scope.isSelected = function ( name ) {
		return $scope.id === name;
	};

	$scope.id = $location.hash();

	if ( $scope.id == '' ) {
		$scope.change( $scope.choices[0].id );
	}
}
]
);

eassApp
.controller('SidebarPageListCtrl',
[
'$scope', '$location', '$compile',
function($scope, $location, $compile)
{
	var list = angular.element(".panel-body ul li");

	if ( list.length <= 1 ) {
		// Nothing to partition
		return;
	}

	var headers = angular.element(".panel-body h4" );

	if ( headers.length <= 1 ) {
		// Nothing to partition
		return;
	}

	$scope.choices = [];

	angular.forEach(list, function(value, key) {
		$scope.choices.push(
			{
				id: angular.element(value).html().toLowerCase().replace(/[^a-z0-9]/gi,''),
				title: angular.element(value).html()
			}
		);
	});

	angular.element(".panel-body ul" ).remove();

	var i = 0;
	angular.forEach(headers, function(value, key) {
		i++;

		var element = {
			id: angular.element(value).html().toLowerCase().replace(/[^a-z0-9]/gi,''),
			title: angular.element(value).html()
		};

		var content = angular.element(value).nextUntil("h4").andSelf();

		var newhtml = '';

		var id;

		var replace;

		var name = '';

		var inner = '';

		for ( var j=0; j<content.length; j++ ) {
			var el = angular.element(content[j]);

			inner = el.clone().wrap('
').parent().html();

			if ( name == '' ) {
				elname = el.html().toLowerCase().replace(/[^a-z0-9]/gi,'');

				angular.forEach($scope.choices, function(value, key) {
					if ( elname == value.id ) {
						name = value.id;

						if ( el.context.localName != 'h4' ) {
							inner = '';
						}
					}
				});
			}

			newhtml += inner;

			if ( j < content.length-1 ) {
				angular.element(content[j]).remove();

				delete content[j];
			} else {
				replace = content[j];
			}
		}

		newhtml = newhtml.replace('

', '
');

		angular.element(replace).replaceWith(
			$compile(
				'
'
					+ newhtml
					+ '
'
			)($scope)
		);
	});

	$scope.change = function( name ) {
		if ( $scope.id === name ) {
			$scope.id = '';
		} else {
			$scope.id = name;
		}

		$location.hash($scope.id);
	};

	$scope.isDeselected = function ( name ) {
		return $scope.id !== name && $scope.id != '';
	};

	$scope.isSelected = function ( name ) {
		return $scope.id === name;
	};

	$scope.id = $location.hash();
}
]
);

eassApp
.controller('ContactCtrl',
[
'$scope',
function($scope) {
	$scope.id = '';

	$scope.change = function( name ) {
		if ( $scope.id === name ) {
			$scope.id = '';
		} else {
			$scope.id = name;
		}
	};

	$scope.isDeselected = function ( name ) {
		return $scope.id !== name && $scope.id != '';
	};

	$scope.isSelected = function ( name ) {
		return $scope.id === name;
	};
}
]
);
<|endoftext|>


<commit_before>/*
 * This file defines the API for the core Kolibri app.
 */

// module must be specified.
// module maps a module into the API, at the specified path.
// By default any module specified will be aliased to allow for require statements
// namespaced in a way analogous to the API spec below.
//
// These modules will now be referenceable as e.g.: import logger from 'kolibri.lib.logging';
//
// N.B. You cannot use keys that require quotation marks in this object.
// e.g. 'content-icon' (although this can be used as a value in module).

import vue from 'vue';
import vuex from 'vuex';
import UiAlert from 'kolibri-design-system/lib/keen/UiAlert';
import responsiveWindowMixin from 'kolibri-design-system/lib/KResponsiveWindowMixin';
import responsiveElementMixin from 'kolibri-design-system/lib/KResponsiveElementMixin';
import scriptLoader from 'kolibri-design-system/lib/utils/scriptLoader';
import UiIconButton from 'kolibri-design-system/lib/keen/UiIconButton'; // temp hack
import * as vueCompositionApi from '@vue/composition-api';
import logging from '../logging';
import * as apiResource from '../api-resource';
import * as constants from '../constants';
import * as getters from '../state/modules/core/getters';
import * as actions from '../state/modules/core/actions';
import store from '../state/store';
import * as mappers from '../state/mappers';
import DownloadButton from '../views/ContentRenderer/DownloadButton';
import ProgressBar from '../views/ProgressBar';
import ContentIcon from '../views/ContentIcon';
import ProgressIcon from '../views/ProgressIcon';
import PermissionsIcon from '../views/PermissionsIcon';
import CoreBase from '../views/CoreBase';
import AppBarPage from '../views/CorePage/AppBarPage';
import AppBar from '../views/AppBar';
import ImmersivePage from '../views/CorePage/ImmersivePage';
import ScrollingHeader from '../views/CoreBase/ScrollingHeader';
import SidePanelModal from '../views/SidePanelModal';
import SideNav from '../views/SideNav';
import Navbar from '../views/Navbar';
import NavbarLink from '../views/Navbar/NavbarLink';
import CoreLogo from '../views/CoreLogo';
import LanguageSwitcherList from '../views/language-switcher/LanguageSwitcherList';
import LanguageSwitcherModal from '../views/language-switcher/LanguageSwitcherModal';
import ElapsedTime from '../views/ElapsedTime';
import PointsIcon from '../views/PointsIcon';
import AuthMessage from '../views/AuthMessage';
import FilterTextbox from '../views/FilterTextbox';
import router from '../router';
import commonCoreStrings from '../mixins/commonCoreStrings'; // eslint-disable-line import/no-duplicates
import { coreStrings } from '../mixins/commonCoreStrings'; // eslint-disable-line import/no-duplicates
import commonTaskStrings from '../mixins/taskStrings';
import commonSyncElements from '../mixins/commonSyncElements';
import CoreFullscreen from '../views/CoreFullscreen';
import * as exams from '../exams/utils';
import * as validators from '../validators';
import * as objectSpecs from '../objectSpecs';
import * as serverClock from '../serverClock';
import * as resources from '../api-resources';
import * as i18n from '../utils/i18n';
import * as browserInfo from '../utils/browserInfo';
import redirectBrowser from '../utils/redirectBrowser';
import * as licenseTranslations from '../utils/licenseTranslations';
import bytesForHumans from '../utils/bytesForHumans';
import UserType from '../utils/UserType';
import samePageCheckGenerator from '../utils/samePageCheckGenerator';
import Backdrop from '../views/Backdrop';
import CoreSnackbar from '../views/CoreSnackbar';
import CoreMenu from '../views/CoreMenu';
import CoreMenuDivider from '../views/CoreMenu/CoreMenuDivider';
import CoreMenuOption from '../views/CoreMenu/CoreMenuOption';
import heartbeat from '../heartbeat';
import CoreTable from '../views/CoreTable';
import CoachContentLabel from '../views/CoachContentLabel';
import PrivacyInfoModal from '../views/PrivacyInfoModal';
import UserTypeDisplay from '../views/UserTypeDisplay';
import TechnicalTextBlock from '../views/AppError/TechnicalTextBlock';
import Draggable from '../views/sortable/Draggable';
import DragHandle from '../views/sortable/DragHandle';
import DragContainer from '../views/sortable/DragContainer';
import DragSortWidget from '../views/sortable/DragSortWidget';
import FocusTrap from '../views/FocusTrap';
import BottomAppBar from '../views/BottomAppBar';
import BaseToolbar from '../views/BaseToolbar';
import GenderSelect from '../views/userAccounts/GenderSelect';
import BirthYearSelect from '../views/userAccounts/BirthYearSelect';
import FullNameTextbox from '../views/userAccounts/FullNameTextbox';
import UsernameTextbox from '../views/userAccounts/UsernameTextbox';
import PasswordTextbox from '../views/userAccounts/PasswordTextbox';
import GenderDisplayText from '../views/userAccounts/GenderDisplayText';
import BirthYearDisplayText from '../views/userAccounts/BirthYearDisplayText';
import PrivacyLinkAndModal from '../views/userAccounts/PrivacyLinkAndModal.vue';
import PaginatedListContainer from '../views/PaginatedListContainer';
import MasteryModel from '../views/MasteryModel';
import LearnOnlyDeviceNotice from '../views/LearnOnlyDeviceNotice';
import themeConfig from '../styles/themeConfig';
import sortLanguages from '../utils/sortLanguages';
import * as sync from '../views/sync/syncComponentSet';
import PageRoot from '../views/PageRoot';
import NotificationsRoot from '../views/NotificationsRoot';

// webpack optimization
import CoreInfoIcon from '../views/CoreInfoIcon';
import * as contentNode from '../utils/contentNodeUtils';
import InteractionList from '../views/InteractionList';
import ExamReport from '../views/ExamReport';
import SlotTruncator from '../views/SlotTruncator';
import TextTruncator from '../views/TextTruncator';
import TextTruncatorCss from '../views/TextTruncatorCss';
import TimeDuration from '../views/TimeDuration';
import SuggestedTime from '../views/SuggestedTime';

import MultiPaneLayout from '../views/MultiPaneLayout';
import filterUsersByNames from '../utils/filterUsersByNames';
import navComponents from '../utils/navComponents';
import loginComponents from '../utils/loginComponents';
import coreBannerContent from '../utils/coreBannerContent';
import CatchErrors from '../utils/CatchErrors';
import UiToolbar from '../views/KeenUiToolbar.vue';
import shuffled from '../utils/shuffled';
import appCapabilities from '../utils/appCapabilities';
import * as client from './client';
import clientFactory from './baseClient';

import urls from './urls';

export default {
  client,
  heartbeat,
  lib: {
    logging,
    vue,
    vuex,
    vueCompositionApi,
    apiResource,
  },
  coreVue: {
    vuex: {
      constants,
      getters,
      actions,
      store,
      mappers,
    },
    components: {
      ScrollingHeader,
      Backdrop,
      CoachContentLabel,
      DownloadButton,
      ProgressBar,
      ContentIcon,
      ProgressIcon,
      PermissionsIcon,
      AppBar,
      AppBarPage,
      AppBar,
      ImmersivePage,
      CoreBase,
      SidePanelModal,
      SideNav,
      Navbar,
      NavbarLink,
      LanguageSwitcherModal,
      LanguageSwitcherList,
      ElapsedTime,
      PointsIcon,
      AuthMessage,
      FilterTextbox,
      CoreSnackbar,
      CoreMenu,
      CoreMenuDivider,
      CoreMenuOption,
      CoreTable,
      CoreInfoIcon,
      InteractionList,
      ExamReport,
      SlotTruncator,
      TextTruncator,
      TextTruncatorCss,
      TimeDuration,
      MultiPaneLayout,
      CoreFullscreen,
      CoreLogo,
      UiAlert,
      UiIconButton,
      UiToolbar,
      PrivacyInfoModal,
      UserTypeDisplay,
      TechnicalTextBlock,
      Draggable,
      DragHandle,
      DragContainer,
      DragSortWidget,
      FocusTrap,
      BottomAppBar,
      BaseToolbar,
      GenderSelect,
      GenderDisplayText,
      BirthYearSelect,
      FullNameTextbox,
      UsernameTextbox,
      PasswordTextbox,
      BirthYearDisplayText,
      PaginatedListContainer,
      PrivacyLinkAndModal,
      LearnOnlyDeviceNotice,
      SuggestedTime,
      PageRoot,
      MasteryModel,
      NotificationsRoot,
    },
    componentSets: {
      sync,
    },
    router,
    mixins: {
      responsiveWindowMixin,
      responsiveElementMixin,
      commonCoreStrings,
      commonTaskStrings,
      commonSyncElements,
    },
  },
  resources,
  themeConfig,
  urls,
  utils: {
    appCapabilities,
    browserInfo,
    bytesForHumans,
    CatchErrors,
    clientFactory,
    contentNode,
    coreBannerContent,
    exams,
    filterUsersByNames,
    i18n,
    licenseTranslations,
    loginComponents,
    navComponents,
    redirectBrowser,
    samePageCheckGenerator,
    scriptLoader,
    serverClock,
    shuffled,
    sortLanguages,
    UserType,
    validators,
    coreStrings,
    objectSpecs,
  },
};
<commit_msg>remove dupe key<commit_after>/*
 * This file defines the API for the core Kolibri app.
 */

// module must be specified.
// module maps a module into the API, at the specified path.
// By default any module specified will be aliased to allow for require statements
// namespaced in a way analogous to the API spec below.
//
// These modules will now be referenceable as e.g.: import logger from 'kolibri.lib.logging';
//
// N.B. You cannot use keys that require quotation marks in this object.
// e.g. 'content-icon' (although this can be used as a value in module).

import vue from 'vue';
import vuex from 'vuex';
import UiAlert from 'kolibri-design-system/lib/keen/UiAlert';
import responsiveWindowMixin from 'kolibri-design-system/lib/KResponsiveWindowMixin';
import responsiveElementMixin from 'kolibri-design-system/lib/KResponsiveElementMixin';
import scriptLoader from 'kolibri-design-system/lib/utils/scriptLoader';
import UiIconButton from 'kolibri-design-system/lib/keen/UiIconButton'; // temp hack
import * as vueCompositionApi from '@vue/composition-api';
import logging from '../logging';
import * as apiResource from '../api-resource';
import * as constants from '../constants';
import * as getters from '../state/modules/core/getters';
import * as actions from '../state/modules/core/actions';
import store from '../state/store';
import * as mappers from '../state/mappers';
import DownloadButton from '../views/ContentRenderer/DownloadButton';
import ProgressBar from '../views/ProgressBar';
import ContentIcon from '../views/ContentIcon';
import ProgressIcon from '../views/ProgressIcon';
import PermissionsIcon from '../views/PermissionsIcon';
import CoreBase from '../views/CoreBase';
import AppBarPage from '../views/CorePage/AppBarPage';
import AppBar from '../views/AppBar';
import ImmersivePage from '../views/CorePage/ImmersivePage';
import ScrollingHeader from '../views/CoreBase/ScrollingHeader';
import SidePanelModal from '../views/SidePanelModal';
import SideNav from '../views/SideNav';
import Navbar from '../views/Navbar';
import NavbarLink from '../views/Navbar/NavbarLink';
import CoreLogo from '../views/CoreLogo';
import LanguageSwitcherList from '../views/language-switcher/LanguageSwitcherList';
import LanguageSwitcherModal from '../views/language-switcher/LanguageSwitcherModal';
import ElapsedTime from '../views/ElapsedTime';
import PointsIcon from '../views/PointsIcon';
import AuthMessage from '../views/AuthMessage';
import FilterTextbox from '../views/FilterTextbox';
import router from '../router';
import commonCoreStrings from '../mixins/commonCoreStrings'; // eslint-disable-line import/no-duplicates
import { coreStrings } from '../mixins/commonCoreStrings'; // eslint-disable-line import/no-duplicates
import commonTaskStrings from '../mixins/taskStrings';
import commonSyncElements from '../mixins/commonSyncElements';
import CoreFullscreen from '../views/CoreFullscreen';
import * as exams from '../exams/utils';
import * as validators from '../validators';
import * as objectSpecs from '../objectSpecs';
import * as serverClock from '../serverClock';
import * as resources from '../api-resources';
import * as i18n from '../utils/i18n';
import * as browserInfo from '../utils/browserInfo';
import redirectBrowser from '../utils/redirectBrowser';
import * as licenseTranslations from '../utils/licenseTranslations';
import bytesForHumans from '../utils/bytesForHumans';
import UserType from '../utils/UserType';
import samePageCheckGenerator from '../utils/samePageCheckGenerator';
import Backdrop from '../views/Backdrop';
import CoreSnackbar from '../views/CoreSnackbar';
import CoreMenu from '../views/CoreMenu';
import CoreMenuDivider from '../views/CoreMenu/CoreMenuDivider';
import CoreMenuOption from '../views/CoreMenu/CoreMenuOption';
import heartbeat from '../heartbeat';
import CoreTable from '../views/CoreTable';
import CoachContentLabel from '../views/CoachContentLabel';
import PrivacyInfoModal from '../views/PrivacyInfoModal';
import UserTypeDisplay from '../views/UserTypeDisplay';
import TechnicalTextBlock from '../views/AppError/TechnicalTextBlock';
import Draggable from '../views/sortable/Draggable';
import DragHandle from '../views/sortable/DragHandle';
import DragContainer from '../views/sortable/DragContainer';
import DragSortWidget from '../views/sortable/DragSortWidget';
import FocusTrap from '../views/FocusTrap';
import BottomAppBar from '../views/BottomAppBar';
import BaseToolbar from '../views/BaseToolbar';
import GenderSelect from '../views/userAccounts/GenderSelect';
import BirthYearSelect from '../views/userAccounts/BirthYearSelect';
import FullNameTextbox from '../views/userAccounts/FullNameTextbox';
import UsernameTextbox from '../views/userAccounts/UsernameTextbox';
import PasswordTextbox from '../views/userAccounts/PasswordTextbox';
import GenderDisplayText from '../views/userAccounts/GenderDisplayText';
import BirthYearDisplayText from '../views/userAccounts/BirthYearDisplayText';
import PrivacyLinkAndModal from '../views/userAccounts/PrivacyLinkAndModal.vue';
import PaginatedListContainer from '../views/PaginatedListContainer';
import MasteryModel from '../views/MasteryModel';
import LearnOnlyDeviceNotice from '../views/LearnOnlyDeviceNotice';
import themeConfig from '../styles/themeConfig';
import sortLanguages from '../utils/sortLanguages';
import * as sync from '../views/sync/syncComponentSet';
import PageRoot from '../views/PageRoot';
import NotificationsRoot from '../views/NotificationsRoot';

// webpack optimization
import CoreInfoIcon from '../views/CoreInfoIcon';
import * as contentNode from '../utils/contentNodeUtils';
import InteractionList from '../views/InteractionList';
import ExamReport from '../views/ExamReport';
import SlotTruncator from '../views/SlotTruncator';
import TextTruncator from '../views/TextTruncator';
import TextTruncatorCss from '../views/TextTruncatorCss';
import TimeDuration from '../views/TimeDuration';
import SuggestedTime from '../views/SuggestedTime';

import MultiPaneLayout from '../views/MultiPaneLayout';
import filterUsersByNames from '../utils/filterUsersByNames';
import navComponents from '../utils/navComponents';
import loginComponents from '../utils/loginComponents';
import coreBannerContent from '../utils/coreBannerContent';
import CatchErrors from '../utils/CatchErrors';
import UiToolbar from '../views/KeenUiToolbar.vue';
import shuffled from '../utils/shuffled';
import appCapabilities from '../utils/appCapabilities';
import * as client from './client';
import clientFactory from './baseClient';

import urls from './urls';

export default {
  client,
  heartbeat,
  lib: {
    logging,
    vue,
    vuex,
    vueCompositionApi,
    apiResource,
  },
  coreVue: {
    vuex: {
      constants,
      getters,
      actions,
      store,
      mappers,
    },
    components: {
      ScrollingHeader,
      Backdrop,
      CoachContentLabel,
      DownloadButton,
      ProgressBar,
      ContentIcon,
      ProgressIcon,
      PermissionsIcon,
      AppBar,
      AppBarPage,
      ImmersivePage,
      CoreBase,
      SidePanelModal,
      SideNav,
      Navbar,
      NavbarLink,
      LanguageSwitcherModal,
      LanguageSwitcherList,
      ElapsedTime,
      PointsIcon,
      AuthMessage,
      FilterTextbox,
      CoreSnackbar,
      CoreMenu,
      CoreMenuDivider,
      CoreMenuOption,
      CoreTable,
      CoreInfoIcon,
      InteractionList,
      ExamReport,
      SlotTruncator,
      TextTruncator,
      TextTruncatorCss,
      TimeDuration,
      MultiPaneLayout,
      CoreFullscreen,
      CoreLogo,
      UiAlert,
      UiIconButton,
      UiToolbar,
      PrivacyInfoModal,
      UserTypeDisplay,
      TechnicalTextBlock,
      Draggable,
      DragHandle,
      DragContainer,
      DragSortWidget,
      FocusTrap,
      BottomAppBar,
      BaseToolbar,
      GenderSelect,
      GenderDisplayText,
      BirthYearSelect,
      FullNameTextbox,
      UsernameTextbox,
      PasswordTextbox,
      BirthYearDisplayText,
      PaginatedListContainer,
      PrivacyLinkAndModal,
      LearnOnlyDeviceNotice,
      SuggestedTime,
      PageRoot,
      MasteryModel,
      NotificationsRoot,
    },
    componentSets: {
      sync,
    },
    router,
    mixins: {
      responsiveWindowMixin,
      responsiveElementMixin,
      commonCoreStrings,
      commonTaskStrings,
      commonSyncElements,
    },
  },
  resources,
  themeConfig,
  urls,
  utils: {
    appCapabilities,
    browserInfo,
    bytesForHumans,
    CatchErrors,
    clientFactory,
    contentNode,
    coreBannerContent,
    exams,
    filterUsersByNames,
    i18n,
    licenseTranslations,
    loginComponents,
    navComponents,
    redirectBrowser,
    samePageCheckGenerator,
    scriptLoader,
    serverClock,
    shuffled,
    sortLanguages,
    UserType,
    validators,
    coreStrings,
    objectSpecs,
  },
};
<|endoftext|>


<commit_before>/*
 * backbone-krankshaft.js 0.1
 *
 * Copyright 2013 Dan LaMotte <lamotte85@gmail.com>
 *
 * This software may be used and distributed according to the terms of the
 * MIT License.
 *
 * Depends on: krankshaft.js
 */
(function($, bb, _, undefined) {
  'use strict';

  bb.ks = {};

  bb.ks.cache = {
    add: function(inst) {
      bb.ks.get_or_create_collection(inst.constructor)
            .set([inst], {remove: false});
    },
    cached: [],
    clear: function(model) {
      if (model) {
        bb.ks.cache.get_or_create_collection(model).reset();
      }
      else {
        bb.ks.cached = [];
      }
    },
    get: function(model, id) {
      return
        bb.ks.get_or_create_collection(model)
              .get(id);
    },
    get_or_create_collection: function(model) {
      var collection = _.find(bb.ks.cache.cached, function(collection) {
        return collection.model == model;
      });

      if (! collection) {
        collection = new bb.Collection();
        collection.model = model;
        bb.ks.cache.cached.push(collection);
      }

      return collection;
    }
  };

  bb.ks.sync = function(method, model, opts) {
    opts = opts || {};

    if (model.api) {
      opts = model.api.auth.update(opts);
    }

    return ks.deferred_to_promise(bb.sync(method, model, opts))
    .then(function(xhr) {
      var location = xhr.getResponseHeader('Location');
      if (! xhr.data
          && location
          && (
            xhr.status === 201
            || xhr.status === 202
            || xhr.status === 204
          )
      ) {
        return ks.deferred_to_promise(bb.sync('read', model, {
          url: location,
          headers: opts.headers
        }));
      }

      return xhr;
    });
  };

  /*
   * Ideally, once you have a krankshaft js API object, you attach it to a
   * Model like:
   *
   *  var MyModel = Backbone.ks.Model.extend({
   *   api: api,
   *   resource: 'mymodel'
   *  });
   *
   * This will automatically construct your `urlRoot` for the model as well
   * as its required for some methods overwritten in this module.
   */

  bb.ks.Model = bb.Model.extend({
    idAttribute: '_uri',
    sync: bb.ks.sync,

    constructor: function() {
      this.urlRoot = this.api.reverse(this.resource);

      bb.Model.apply(this, arguments);
    },

    fetch: function(opts) {
      var me = this;
      var request = bb.Model.prototype.fetch.call(this, opts);

      if (this.constructor.cached === true) {
        request.done(function() {
          bb.ks.cache.add(me);
        });
      }

      return request;
    },

    url: function() {
      return this.id || this.urlRoot || null;
    }
  }, {
    fetch: function(uri, opts) {
      opts = opts || {};

      var ctor = this;
      var cache = opts.ks_cache === undefined ? true : opts.ks_cache;

      if (this.cached === true && cache) {
        var instance = bb.ks.cache.get(this, uri);
        if (instance) {
          return Q.resolve(instance);
        }
      }

      return ks.deferred_to_promise($.ajax(_.extend({
        url: uri
      }, opts)))
      .then(function(xhr) {
        return new ctor(xhr.data);
      });
    }
  });

  bb.ks.Collection = bb.Collection.extend({
    sync: bb.ks.sync,

    constructor: function() {
      var model = this.model.prototype;

      if (! this.api) {
        this.api = model.api;
      }
      if (! this.resource) {
        this.resource = model.resource;
      }
      if (! this.urlRoot) {
        if (model.urlRoot) {
          this.urlRoot = model.urlRoot;
        }
        else {
          this.urlRoot = this.api.reverse(this.resource);
        }
      }

      bb.Collection.apply(this, arguments);
    },

    fetch: function(opts) {
      var me = this;
      var request = bb.Collection.prototype.fetch.call(this, opts);

      if (this.model.cached === true) {
        request.done(function() {
          bb.ks.cache.get_or_create_collection(me.model)
            .set(me.models, {remove: false});
        });
      }

      return request;
    },

    parse: function(data) {
      if (! data) {
        return;
      }

      if (data.meta) {
        this.meta = data.meta;
      }

      return data.objects;
    },

    url: function(models) {
      var uri = this.urlRoot;

      if (! models || ! models.length) {
        return uri;
      }

      uri = this.api.reverse(this.resource + ':set',
        _.map(models, function(model) { return model.get('id'); }).join(';')
      );

      return uri || null;
    }
  });
}(jQuery, Backbone, _));
<commit_msg>js/bb-ks: cache fixes<commit_after>/*
 * backbone-krankshaft.js 0.1
 *
 * Copyright 2013 Dan LaMotte <lamotte85@gmail.com>
 *
 * This software may be used and distributed according to the terms of the
 * MIT License.
 *
 * Depends on: krankshaft.js
 */
(function($, bb, _, undefined) {
  'use strict';

  bb.ks = {};

  bb.ks.cache = {
    add: function(inst) {
      bb.ks.get_or_create_collection(inst.constructor)
            .set([inst], {remove: false});
    },
    cached: [],
    clear: function(model) {
      if (model) {
        bb.ks.cache.get_or_create_collection(model).reset();
      }
      else {
        bb.ks.cached = [];
      }
    },
    get: function(model, id) {
      return
        bb.ks.get_or_create_collection(model)
              .get(id);
    },
    get_or_create_collection: function(model) {
      var collection = _.find(bb.ks.cache.cached, function(collection) {
        return collection.model == model;
      });

      if (! collection) {
        collection = new bb.ks.Collection();
        collection.model = model;
        bb.ks.cache.cached.push(collection);
      }

      return collection;
    }
  };

  bb.ks.sync = function(method, model, opts) {
    opts = opts || {};

    if (model.api) {
      opts = model.api.auth.update(opts);
    }

    return ks.deferred_to_promise(bb.sync(method, model, opts))
    .then(function(xhr) {
      var location = xhr.getResponseHeader('Location');
      if (! xhr.data
          && location
          && (
            xhr.status === 201
            || xhr.status === 202
            || xhr.status === 204
          )
      ) {
        return ks.deferred_to_promise(bb.sync('read', model, {
          url: location,
          headers: opts.headers
        }));
      }

      return xhr;
    });
  };

  /*
   * Ideally, once you have a krankshaft js API object, you attach it to a
   * Model like:
   *
   *  var MyModel = Backbone.ks.Model.extend({
   *   api: api,
   *   resource: 'mymodel'
   *  });
   *
   * This will automatically construct your `urlRoot` for the model as well
   * as its required for some methods overwritten in this module.
   */

  bb.ks.Model = bb.Model.extend({
    idAttribute: '_uri',
    sync: bb.ks.sync,

    constructor: function() {
      this.urlRoot = this.api.reverse(this.resource);

      bb.Model.apply(this, arguments);
    },

    fetch: function(opts) {
      var me = this;
      var request = bb.Model.prototype.fetch.call(this, opts);

      if (this.cached === true) {
        request.done(function() {
          bb.ks.cache.add(me);
        });
      }

      return request;
    },

    url: function() {
      return this.id || this.urlRoot || null;
    }
  }, {
    fetch: function(uri, opts) {
      opts = opts || {};

      var ctor = this;
      var cache = opts.ks_cache === undefined ? true : opts.ks_cache;

      if (this.prototype.cached === true && cache) {
        var instance = bb.ks.cache.get(this, uri);
        if (instance) {
          return Q.resolve(instance);
        }
      }

      return ks.deferred_to_promise($.ajax(_.extend({
        url: uri
      }, opts)))
      .then(function(xhr) {
        return new ctor(xhr.data);
      });
    }
  });

  bb.ks.Collection = bb.Collection.extend({
    sync: bb.ks.sync,

    constructor: function() {
      var model = this.model.prototype;

      if (! this.api) {
        this.api = model.api;
      }
      if (! this.resource) {
        this.resource = model.resource;
      }
      if (! this.urlRoot) {
        if (model.urlRoot) {
          this.urlRoot = model.urlRoot;
        }
        else if (this.api) {
          this.urlRoot = this.api.reverse(this.resource);
        }
      }

      bb.Collection.apply(this, arguments);
    },

    fetch: function(opts) {
      var me = this;
      var request = bb.Collection.prototype.fetch.call(this, opts);

      if (this.model.prototype.cached === true) {
        request.done(function() {
          bb.ks.cache.get_or_create_collection(me.model)
            .set(me.models, {remove: false});
        });
      }

      return request;
    },

    parse: function(data) {
      if (! data) {
        return;
      }

      if (data.meta) {
        this.meta = data.meta;
      }

      return data.objects;
    },

    url: function(models) {
      var uri = this.urlRoot;

      if (! models || ! models.length) {
        return uri;
      }

      uri = this.api.reverse(this.resource + ':set',
        _.map(models, function(model) { return model.get('id'); }).join(';')
      );

      return uri || null;
    }
  });
}(jQuery, Backbone, _));
<|endoftext|>


<commit_before>/* jshint node:true */
"use strict";

var ms_tile, lower_range, width, height,
  bridge_length, current_tile, map_config,
  exec = require('child_process').exec,
  fs = require('fs'),
  _ = require('underscore'),
  grid = [],
  tile_config = [],
  jsio = require('jsio'),
  writable = fs.createWriteStream('./maps/final_map.json'),
  i = 0,
  j = 0,
  row_data = [],
  current_ms = 1,
  bridge_count = 0,
  create_map_group = function (i, loop_data, length) {
    current_tile = current_tile - (length * width);

    for (var j = loop_data.length; j-- > 0;) {
      _.each(loop_data[j], function (tile) {
        return check_object(tile);
      });
    }
  },
  check_object = function (tile) {
    var ms_obj = {
      node: '1',
      'friends': {
        'position': 'bottom'
      },
      'tags':{
        'milestone': true
      }
    };

    if (_.isObject(tile)) {
      ms_tile = current_tile + tile.map;
      ms_obj.map = ms_tile;
      ms_obj.id = current_ms;
      map_data.grid[Math.floor(ms_tile / width)][ms_tile % width] = ms_obj;
      current_ms++;
      if (tile.x) {
        ms_obj.x = tile.x;
      }
      if (tile.y) {
        ms_obj.y = tile.y;
      }

      return ms_obj;
    } else {
      return tile + current_tile;
    }
  };

// Setup empty map
exec('node create_empty_map.js');

map_config = require('./map_config.json');
width = map_config.width,
height = map_config.height,
bridge_length = map_config.bridge.length;
current_tile = height * width;

jsio('import .maps.map_empty as map_data');

tile_config.push({
  range: [0, 4],
  folder: 'comingsoon'
})

_.each(map_config.maps, function (data, num) {
  var map_name = 'map' + (num + 1),
    map_loc = './maps/' + map_name,
    file_data = require(map_loc),
    loop_data = file_data.grid,
    milestones = {},
    map_writable = fs.createWriteStream(map_loc + '.json');

  map_writable.write(JSON.stringify(file_data, null, 2));
  map_writable.end();

  _.times(data.repeat, function (i) {
    create_map_group(i, loop_data, data.length);
  });

  // For map tile config
  lower_range = Math.floor(current_tile / width);
  tile_config.splice(1, 0, {
    range: [lower_range, lower_range + data.length * data.repeat - 1],
    folder: map_name,
    length: data.length
  });

  // For bridge tile config
  lower_range--;
  current_tile = current_tile - (bridge_length * width);
  bridge_count++;
  tile_config.splice(1, 0, {
    range: [lower_range - bridge_length + 1, lower_range],
    folder: 'bridge' + bridge_count,
    length: bridge_length
  });
});

// Remove last bridge
tile_config.splice(1, 1);
writable.write('exports = ' + JSON.stringify(map_data, null, 2));
writable.end();
<commit_msg>Add parameter support<commit_after>/* jshint node:true */
"use strict";

var ms_tile, lower_range, width, height,
  bridge_length, current_tile, map_config,
  exec = require('child_process').exec,
  path = require('path'),
  fs = require('fs'),
  _ = require('underscore'),
  grid = [],
  tile_config = [],
  jsio = require('jsio'),
  final_map = process.argv[3] ? process.argv[3] :
    path.join(__dirname, 'maps/final_map.js'),
  empty_map_path = path.join(__dirname, 'create_empty_map.js'),
  map_config_path = process.argv[4] ? process.argv[4] :
    path.join(__dirname, 'map_config.json'),
  writable = fs.createWriteStream(final_map),
  i = 0,
  j = 0,
  row_data = [],
  current_ms = 1,
  bridge_count = 0,
  create_map_group = function (i, loop_data, length) {
    current_tile = current_tile - (length * width);

    for (var j = loop_data.length; j-- > 0;) {
      _.each(loop_data[j], function (tile) {
        return check_object(tile);
      });
    }
  },
  check_object = function (tile) {
    var ms_obj = {
      node: '1',
      'friends': {
        'position': 'bottom'
      },
      'tags':{
        'milestone': true
      }
    };

    if (_.isObject(tile)) {
      ms_tile = current_tile + tile.map;
      ms_obj.map = ms_tile;
      ms_obj.id = current_ms;
      map_data.grid[Math.floor(ms_tile / width)][ms_tile % width] = ms_obj;
      current_ms++;
      if (tile.x) {
        ms_obj.x = tile.x;
      }
      if (tile.y) {
        ms_obj.y = tile.y;
      }

      return ms_obj;
    } else {
      return tile + current_tile;
    }
  },
  map_data_path = path.join(__dirname, 'maps/map_empty');

// Setup empty map
exec('node ' + empty_map_path).stdout.pipe(process.stdout);

map_config = require(map_config_path);
width = map_config.width,
height = map_config.height,
bridge_length = map_config.bridge.length;
current_tile = height * width;

jsio.path.add('../');
jsio('import adventuremap.scripts.maps.map_empty as map_data');

tile_config.push({
  range: [0, 4],
  folder: 'comingsoon'
})

_.each(map_config.maps, function (data, num) {
  var map_name = 'map' + (num + 1),
    map_loc = path.join(process.cwd(), process.argv[2]) + '/' + map_name,
    file_data = require(map_loc),
    loop_data = file_data.grid,
    milestones = {},
    map_writable = fs.createWriteStream(map_loc + '.json');

  map_writable.write(JSON.stringify(file_data, null, 2));
  map_writable.end();

  _.times(data.repeat, function (i) {
    create_map_group(i, loop_data, data.length);
  });

  // For map tile config
  lower_range = Math.floor(current_tile / width);
  tile_config.splice(1, 0, {
    range: [lower_range, lower_range + data.length * data.repeat - 1],
    folder: map_name,
    length: data.length
  });

  // For bridge tile config
  lower_range--;
  current_tile = current_tile - (bridge_length * width);
  bridge_count++;
  tile_config.splice(1, 0, {
    range: [lower_range - bridge_length + 1, lower_range],
    folder: 'bridge' + bridge_count,
    length: bridge_length
  });
});

// Remove last bridge
tile_config.splice(1, 1);
writable.write('exports = ' + JSON.stringify(map_data, null, 2) + ';');
writable.end();
<|endoftext|>


<commit_before>var taxcalculator_app = angular.module('taxcalculatorApp', ['employee', 'jobresult', 'ui.bootstrap', 'ngRoute']);

taxcalculator_app.config(['$routeProvider', function ($routeProvider) {
  $routeProvider
    .when('/employees', {templateUrl: 'partials/employees-overview.html', controller: 'EmployeesOverviewCtrl'})
    .when('/jobResults', {templateUrl: 'partials/job-results.html', controller: 'JobResultsCtrl'})
    .when('/generateEmployees/:employeesCount', {templateUrl: 'partials/generate-employees.html', controller: 'GenerateEmployeesCtrl'})
    .otherwise({redirectTo: '/'});
}]);<commit_msg>[Monica, Andrei] Include directives.<commit_after>var taxcalculator_app = angular.module('taxcalculatorApp', ['employee', 'jobresult', 'taxcalculatorDirectives', 'ui.bootstrap', 'ngRoute']);

taxcalculator_app.config(['$routeProvider', function ($routeProvider) {
  $routeProvider
    .when('/employees', {templateUrl: 'partials/employees-overview.html', controller: 'EmployeesOverviewCtrl'})
    .when('/jobResults', {templateUrl: 'partials/job-results.html', controller: 'JobResultsCtrl'})
    .when('/generateEmployees/:employeesCount', {templateUrl: 'partials/generate-employees.html', controller: 'GenerateEmployeesCtrl'})
    .otherwise({redirectTo: '/'});
}]);<|endoftext|>


<commit_before>import EventsNormalizer from 'parser/core/EventsNormalizer';
import { encodeTargetString } from 'parser/shared/modules/EnemyInstances';
import SPELLS from 'common/SPELLS';
import { PERMANENT_PET_ABILITIES_TO_SUMMON_MAP, PET_SUMMON_ABILITY_IDS } from '../CONSTANTS';
import { isPermanentPet } from '../helpers';
import PETS from '../PETS';

const MAX_TEMPORARY_PET_DURATION = 30000;
const CHECKED_EVENT_TYPES = ['begincast', 'cast', 'damage'];
const debug = false;

class PrepullPetNormalizer extends EventsNormalizer {
  // Warlock DemoPets.js depends on `summon` events for their inner works
  // Sometimes it happens, that some pets exist at the combat start, but without their `summon` event
  // Which means that for the module they don't exists, which in turn messes up other mechanics (such as casting Power Siphon (which NEEDS Wild Imps) when we shouldn't have any)
  // This can happen most likely because of 2 things - permanent pet summoned pre-pull, trash mobs right before boss (pets didn't disappear yet), or because of Inner Demons (which periodically summons pets even outside of combat)

  // This normalizer looks at first 30 seconds (because that's hypothetically the longest any temporary pet can live, given a 15 second duration and 15 second extension via Demonic Tyrant, realistically lower because of GCD and cast time of DT)
  // And if it finds begincast, cast or damage events from a pet that isn't summoned yet, fabricates a summon event for them

  // Sometimes pet's first cast happens before it's summon event(for example demonic consumption), both the event and the summon happens at the same time
  // checkForPetsWhichSummonWasLaterThanItsFirstCast will check if they both have the same time, then it deletes the fabricated event

  normalize(events) {
    debug && console.log('playerPets', this.owner.playerPets.sort((pet1, pet2) => pet1.id - pet2.id));
    const maxTimestamp = this.owner.fight.start_time + MAX_TEMPORARY_PET_DURATION;
    const summonedPets = []; // contains encoded target strings of summoned pets - if pet doesn't exist, fabricate an event, and push encoded target string here to mark them as summoned
    const fabricatedEvents = [];

    for (let i = 0; i < events.length; i += 1) {
      const event = events[i];
      if (event.timestamp > maxTimestamp) {
        break;
      }
      debug && console.log(`(${this.owner.formatTimestamp(event.timestamp, 3)}) Event`, event);
      if (event.type === 'summon' && event.ability && PET_SUMMON_ABILITY_IDS.includes(event.ability.guid)) {
        this.checkForPetsWhichSummonWasLaterThanItsFirstCast(event, fabricatedEvents)
        summonedPets.push(encodeTargetString(event.targetID, event.targetInstance));
        debug && console.log(`(${this.owner.formatTimestamp(event.timestamp, 3)}) Pet summon, added to array. Current array: `, JSON.parse(JSON.stringify(summonedPets)));
      }
      else if (CHECKED_EVENT_TYPES.includes(event.type) && this.owner.byPlayerPet(event)) {
        debug && console.log(`(${this.owner.formatTimestamp(event.timestamp, 3)}) begincast, cast or damage event`);
        const petId = event.sourceID;
        const petInstance = event.sourceInstance;
        const petString = encodeTargetString(petId, petInstance);
        if (!summonedPets.includes(petString)) {
          debug && console.log(`(${this.owner.formatTimestamp(event.timestamp, 3)}) Pet ${petString} not summoned yet`);
          // fabricate event for it, push to summonedPets
          let spell;
          if (this._verifyPermanentPet(petId)) {
            if (!PERMANENT_PET_ABILITIES_TO_SUMMON_MAP[event.ability.guid]) {
              debug && console.error(`(${this.owner.formatTimestamp(event.timestamp, 3)}) ERROR - unknown ability`, event);
              continue;
            }
            spell = SPELLS[PERMANENT_PET_ABILITIES_TO_SUMMON_MAP[event.ability.guid]];
          }
          else {
            const guid = this._getPetGuid(petId);
            if (!PETS[guid]) {
              debug && console.error(`(${this.owner.formatTimestamp(event.timestamp, 3)}) ERROR - unknown pet`, event);
              continue;
            }
            spell = SPELLS[PETS[guid].summonAbility];
          }
          const fabricatedEvent = {
            timestamp: this.owner.fight.start_time,
            type: 'summon',
            sourceID: this.owner.playerId,
            targetID: petId,
            targetInstance: petInstance,
            sourceIsFriendly: true,
            targetIsFriendly: true,
            ability: {
              guid: spell.id,
              name: spell.name,
              abilityIcon: spell.icon,
            },
            __fabricated: true,
            __originalTimeStamp: event.timestamp,
          };

          summonedPets.push(petString);
          fabricatedEvents.push(fabricatedEvent);
          debug && console.log(`(${this.owner.formatTimestamp(event.timestamp, 3)}) Fabricated summon event. Current array: `, JSON.parse(JSON.stringify(summonedPets)), ', fabricated events:', JSON.parse(JSON.stringify(fabricatedEvents)));
        }
        else {
          debug && console.log(`(${this.owner.formatTimestamp(event.timestamp, 3)}) Pet ${petString} already in summoned pets`);
        }
      }
    }
    events.unshift(...fabricatedEvents);
    return events;
  }
  checkForPetsWhichSummonWasLaterThanItsFirstCast(event, fabricatedEvents) {
    // delete fabricated event, the pet immediately started casting something and events were pushed before the summon
    for (let k = 0; k < fabricatedEvents.length; k++) {
      if (fabricatedEvents[k].__originalTimeStamp === event.timestamp) {
        debug && console.log(`(${this.owner.formatTimestamp(event.timestamp, 3)}) Deleting fabricated summon of pet`);
        fabricatedEvents.splice(k, 1);
      }
    }
  }

  _getPetGuid(id) {
    return this.owner.playerPets.find(pet => pet.id === id).guid;
  }

  _verifyPermanentPet(id) {
    const guid = this._getPetGuid(id);
    return isPermanentPet(guid);
  }
}

export default PrepullPetNormalizer;
<commit_msg>fix missing semicolon<commit_after>import EventsNormalizer from 'parser/core/EventsNormalizer';
import { encodeTargetString } from 'parser/shared/modules/EnemyInstances';
import SPELLS from 'common/SPELLS';
import { PERMANENT_PET_ABILITIES_TO_SUMMON_MAP, PET_SUMMON_ABILITY_IDS } from '../CONSTANTS';
import { isPermanentPet } from '../helpers';
import PETS from '../PETS';

const MAX_TEMPORARY_PET_DURATION = 30000;
const CHECKED_EVENT_TYPES = ['begincast', 'cast', 'damage'];
const debug = false;

class PrepullPetNormalizer extends EventsNormalizer {
  // Warlock DemoPets.js depends on `summon` events for their inner works
  // Sometimes it happens, that some pets exist at the combat start, but without their `summon` event
  // Which means that for the module they don't exists, which in turn messes up other mechanics (such as casting Power Siphon (which NEEDS Wild Imps) when we shouldn't have any)
  // This can happen most likely because of 2 things - permanent pet summoned pre-pull, trash mobs right before boss (pets didn't disappear yet), or because of Inner Demons (which periodically summons pets even outside of combat)

  // This normalizer looks at first 30 seconds (because that's hypothetically the longest any temporary pet can live, given a 15 second duration and 15 second extension via Demonic Tyrant, realistically lower because of GCD and cast time of DT)
  // And if it finds begincast, cast or damage events from a pet that isn't summoned yet, fabricates a summon event for them

  // Sometimes pet's first cast happens before it's summon event(for example demonic consumption), both the event and the summon happens at the same time
  // checkForPetsWhichSummonWasLaterThanItsFirstCast will check if they both have the same time, then it deletes the fabricated event

  normalize(events) {
    debug && console.log('playerPets', this.owner.playerPets.sort((pet1, pet2) => pet1.id - pet2.id));
    const maxTimestamp = this.owner.fight.start_time + MAX_TEMPORARY_PET_DURATION;
    const summonedPets = []; // contains encoded target strings of summoned pets - if pet doesn't exist, fabricate an event, and push encoded target string here to mark them as summoned
    const fabricatedEvents = [];

    for (let i = 0; i < events.length; i += 1) {
      const event = events[i];
      if (event.timestamp > maxTimestamp) {
        break;
      }
      debug && console.log(`(${this.owner.formatTimestamp(event.timestamp, 3)}) Event`, event);
      if (event.type === 'summon' && event.ability && PET_SUMMON_ABILITY_IDS.includes(event.ability.guid)) {
        this.checkForPetsWhichSummonWasLaterThanItsFirstCast(event, fabricatedEvents);
        summonedPets.push(encodeTargetString(event.targetID, event.targetInstance));
        debug && console.log(`(${this.owner.formatTimestamp(event.timestamp, 3)}) Pet summon, added to array. Current array: `, JSON.parse(JSON.stringify(summonedPets)));
      }
      else if (CHECKED_EVENT_TYPES.includes(event.type) && this.owner.byPlayerPet(event)) {
        debug && console.log(`(${this.owner.formatTimestamp(event.timestamp, 3)}) begincast, cast or damage event`);
        const petId = event.sourceID;
        const petInstance = event.sourceInstance;
        const petString = encodeTargetString(petId, petInstance);
        if (!summonedPets.includes(petString)) {
          debug && console.log(`(${this.owner.formatTimestamp(event.timestamp, 3)}) Pet ${petString} not summoned yet`);
          // fabricate event for it, push to summonedPets
          let spell;
          if (this._verifyPermanentPet(petId)) {
            if (!PERMANENT_PET_ABILITIES_TO_SUMMON_MAP[event.ability.guid]) {
              debug && console.error(`(${this.owner.formatTimestamp(event.timestamp, 3)}) ERROR - unknown ability`, event);
              continue;
            }
            spell = SPELLS[PERMANENT_PET_ABILITIES_TO_SUMMON_MAP[event.ability.guid]];
          }
          else {
            const guid = this._getPetGuid(petId);
            if (!PETS[guid]) {
              debug && console.error(`(${this.owner.formatTimestamp(event.timestamp, 3)}) ERROR - unknown pet`, event);
              continue;
            }
            spell = SPELLS[PETS[guid].summonAbility];
          }
          const fabricatedEvent = {
            timestamp: this.owner.fight.start_time,
            type: 'summon',
            sourceID: this.owner.playerId,
            targetID: petId,
            targetInstance: petInstance,
            sourceIsFriendly: true,
            targetIsFriendly: true,
            ability: {
              guid: spell.id,
              name: spell.name,
              abilityIcon: spell.icon,
            },
            __fabricated: true,
            __originalTimeStamp: event.timestamp,
          };

          summonedPets.push(petString);
          fabricatedEvents.push(fabricatedEvent);
          debug && console.log(`(${this.owner.formatTimestamp(event.timestamp, 3)}) Fabricated summon event. Current array: `, JSON.parse(JSON.stringify(summonedPets)), ', fabricated events:', JSON.parse(JSON.stringify(fabricatedEvents)));
        }
        else {
          debug && console.log(`(${this.owner.formatTimestamp(event.timestamp, 3)}) Pet ${petString} already in summoned pets`);
        }
      }
    }
    events.unshift(...fabricatedEvents);
    return events;
  }
  checkForPetsWhichSummonWasLaterThanItsFirstCast(event, fabricatedEvents) {
    // delete fabricated event, the pet immediately started casting something and events were pushed before the summon
    for (let k = 0; k < fabricatedEvents.length; k++) {
      if (fabricatedEvents[k].__originalTimeStamp === event.timestamp) {
        debug && console.log(`(${this.owner.formatTimestamp(event.timestamp, 3)}) Deleting fabricated summon of pet`);
        fabricatedEvents.splice(k, 1);
      }
    }
  }

  _getPetGuid(id) {
    return this.owner.playerPets.find(pet => pet.id === id).guid;
  }

  _verifyPermanentPet(id) {
    const guid = this._getPetGuid(id);
    return isPermanentPet(guid);
  }
}

export default PrepullPetNormalizer;
<|endoftext|>


<commit_before><commit_msg>Added scripts to search for entry<commit_after><|endoftext|>


<commit_before>'use strict';

/* global queryRegExSelector, queryRegExSelectorAll, getYouTubeHtml5VideoUrl */
Polymer('polymer-hypervideo', {
  publish: {
    currentTime: 0,
    duration: null,
    actorsOffset: {}
  },
  created: function() {
  },
  ready: function() {
    var that = this;
    var spinner;
    var video = that.$.hypervideo;

    var onMutation = function(observer, mutations) {
      var nodes = [];
      var chapters = [];
      for (var i = 0, lenI = mutations.length; i < lenI; i++) {
        var mutation = mutations[i];
        if (mutation.addedNodes) {
          for (var j = 0, lenJ = mutation.addedNodes.length; j < lenJ; j++) {
            if (/^polymer-data-/gi.test(mutation.addedNodes[j].nodeName)) {
              nodes.push(mutation.addedNodes[j]);
            }
          }
        }
      }
      if (nodes.length) {
        positionDataAnnotations(nodes);
        updateTimelineAnnotations(nodes);
      }
      that.onMutation(that, onMutation);
    };

    that.onMutation(that, onMutation);

    var CORS_PROXY = document.location.origin + '/cors/';
    document.addEventListener('trackready', function(e) {
      console.log('Received event (document): trackready');
      var data = e.detail;
      var track = document.createElement('track');
      var cuesRead = false;
      track.addEventListener('load', function(e) {
        if (!cuesRead) {
          console.log('Received event (track): load');
          cuesRead = true;
          return readCues(e.target.track.cues, data.kind);
        }
      }, false);
      track.addEventListener('cuechange', function() {
        console.log('Fired event: hypervideocuechange');
        that.fire(
          'hypervideocuechange',
          {
            activeCues: track.track.activeCues
          }
        );
      });
      var trackLoadedInterval = setInterval(function() {
        if (track.readyState >= 2) {
          clearInterval(trackLoadedInterval);
          if (!cuesRead) {
            console.log('Received event (track): readyState');
            cuesRead = true;
            return readCues(track.track.cues, data.kind);
          }
        }
      }, 100);
      track.src = data.src;
      track.default = true;
      track.kind = data.kind;
      if (track.kind === 'subtitles' || track.kind === 'captions') {
        track.srclang = 'en';
        track.track.mode = 'showing';
      } else if (track.kind === 'chapters') {
        var canvas = document.createElement('canvas');
        canvas.width = video.width;
        canvas.height = video.height;
        var ctx = canvas.getContext('2d');
        that.ctx = ctx;
        that.canvas = canvas;
      }
      video.appendChild(track);
    }, false);

    document.addEventListener('webcomponentstocready', function() {
      console.log('Received event (document): webcomponentstocready');
      // get all child <polymer-*> child nodes
      var webComponents = queryRegExSelectorAll(that, /^polymer-/gi);
      console.log('Fired event: webcomponentstoc');
      that.fire(
        'webcomponentstoc',
        {
          webComponentsToC: webComponents
        }
      );
    }, false);

    var updateTimelineAnnotations = function(opt_nodes) {
      // get all child <polymer-data-*> child nodes
      var dataAnnotations =
          opt_nodes || queryRegExSelectorAll(that, /^polymer-data-/gi);
      var annotations = [];
      dataAnnotations.forEach(function(annotation) {
        var type;
        if (/actor/gi.test(annotation.nodeName)) {
          type = 'actors';
        } else if (/overlay/gi.test(annotation.nodeName)) {
          type = 'overlays';
        } else {
          type = 'annotations';
        }
        annotations.push({
          start: parseInt(annotation.getAttribute('start'), 10),
          end: parseInt(annotation.getAttribute('end'), 10),
          type: type
        });
      });
      console.log('Fired event: dataannotations');
      that.fire(
        'dataannotations',
        {
          dataAnnotations: annotations
        }
      );

    };

    document.addEventListener('timelineready', function() {
      console.log('Received event (document): timelineready');
      updateTimelineAnnotations();
    }, false);

    // listen for events coming from the timeline component
    document.addEventListener('currenttimeupdate', function(e) {
      // console.log('Received event (document): currenttimeupdate');
      var data = e.detail;
      video.currentTime = data.currentTime;
      video.play();
    }, false);

    document.addEventListener('requeststillframes', function(e) {
      console.log('Received event (document): requeststillframes');
      spinner = showSpinner();
      var cues = e.detail.cues;
      if (!cues) {
        return;
      }
      var functions = [];
      cues.forEach(function(cue) {
        var start = cue.start;
        if (start > video.duration) {
          return;
        }
        functions.push({
          cue: cue,
          func: function() {
            video.currentTime = start;
          }
        });
      });
      var getNextStillFrame = function() {
        console.log('Received event (video): seeked');
        that.ctx.drawImage(video, 0, 0, video.clientWidth,
            video.clientHeight);
        var img = document.createElement('img');
        img.setAttribute('class', 'hypervideo');
        var url = that.canvas.toDataURL();
        img.src = url;
        var cue = functions[processedStillFrames].cue;
        console.log('Fired event: receivestillframe');
        that.fire(
          'receivestillframe',
          {
            img: img,
            text: cue.text,
            start: cue.start,
            end: cue.end
          }
        );
        processedStillFrames++;
        if (functions[processedStillFrames]) {
          return functions[processedStillFrames].func();
        } else {
          video.removeEventListener('seeked', getNextStillFrame);
          video.currentTime = 0;
          that.fire('allstillframesreceived');
          spinner.remove();
        }
      };
      var processedStillFrames = 0;
      video.addEventListener('seeked', getNextStillFrame);
      functions[processedStillFrames].func();
    });

    var initializeVideo = function() {
      // either add sources for regular video
      if (that.src) {
        that.src.split(/\s/g).forEach(function(src) {
          var source = document.createElement('source');
          source.src = src;
          video.appendChild(source);
        });
      // or add sources for YouTube video
      } else if (that.youtubevideoid) {
        getYouTubeHtml5VideoUrl(that.youtubevideoid,
            function(err, videoSources) {
          if (err) {
            return;
          }
          for (var videoSource in videoSources) {
            videoSource = videoSources[videoSource];
            var source = document.createElement('source');
            source.src = CORS_PROXY +
                encodeURIComponent(videoSource.original_url);
            source.type = videoSource.type.replace(/\+/g, ' ')
                .replace(/"/g, '\"');
            video.appendChild(source);
          }
        });
      }
      // determine video dimensions
      if (that.width) {
        that.width = parseInt(that.width, 10);
      } else {
        that.width = 400;
      }
      video.width = that.width;
      if (that.height) {
        that.height = parseInt(that.height, 10);
      } else {
        that.height = 225;
      }
      video.height = that.height;
      // add poster
      if (that.poster) {
        video.poster = that.poster;
      }
      // mute video
      if (that.muted !== null && that.muted !== 'false') {
        video.muted = true;
      }
    };

    var showSpinner = function() {
      // show spinner while the hypervideo gets prepared
      var splashDiv = document.createElement('div');
      splashDiv.classList.add('spinner');
      var splashSpinner = document.createElement('div');
      splashSpinner.classList.add('progress');
      splashDiv.appendChild(splashSpinner);
      splashDiv.style.width = video.width + 'px';
      splashDiv.style.height = video.height + 'px';
      splashDiv.style.position = 'absolute';
      splashDiv.style.top = video.offsetTop + 'px';
      splashDiv.style.left = video.offsetLeft + 'px';
      splashSpinner.style.position = 'relative';
      splashSpinner.style.top = (video.offsetHeight / 2 - 60 / 2) + 'px';
      splashSpinner.style.left = (video.offsetWidth / 2 - 60 / 2) + 'px';
      var loadingDiv = document.createElement('div');
      loadingDiv.textContent = '*';
      splashSpinner.appendChild(loadingDiv);
      var container = that.$.container;
      container.appendChild(splashDiv);
      return splashDiv;
    };

    var positionDataAnnotations = function(opt_nodes) {
      // positions data annotations on top of the video
      var polymerData =
          opt_nodes || queryRegExSelectorAll(that, /^polymer-data-/gi);
      polymerData.forEach(function(node) {
        node.style.position = 'absolute';
        node.style.top = (video.offsetTop + 0.66 * video.offsetHeight) +
            'px';
        node.style.left = (video.offsetLeft + (0.05 * that.width)) + 'px';
        node.style.width = (0.9 * that.width) + 'px';
        node.style.display = 'none';
      });
    };

    var readCues = function(cues, kind) {
      if (!cues) {
        return;
      }
      var cueData = [];
      for (var i = 0, lenI = cues.length; i < lenI; i++) {
        var cue = cues.item ? cues.item(i) : cues[i];
        cueData.push({
          start: parseInt(cue.startTime, 10),
          end: parseInt(cue.endTime, 10),
          text: cue.text,
          id: cue.id,
          type: kind
        });
      }
      console.log('Fired event: cuesread');
      that.fire(
        'cuesread',
        {
          cueData: cueData,
          kind: kind
        }
      );
    };

    video.addEventListener('loadedmetadata', function() {
      console.log('Received event (video): loadedmetadata');
      that.duration = video.duration;
      // adjust the timeline dimensions according to the video duration
      var polymerTimelines = that.querySelectorAll('polymer-timeline');
      for (var i = 0, lenI = polymerTimelines.length; i < lenI; i++) {
        polymerTimelines[i].style.left = (video.offsetLeft +
            (0.05 * that.width)) + 'px';
      }
      var polymerData = queryRegExSelector(that, /^polymer-data-/gi);
      console.log('Fired event: hypervideoloadedmetadata');
      that.fire(
        'hypervideoloadedmetadata',
        {
          duration: that.duration,
          height: that.height,
          width: that.width,
          actorsOffset: {
            left: polymerData ? polymerData.style.left.replace('px', '') : null,
            top: polymerData ? polymerData.style.top.replace('px', '') : null
          }
        }
      );

      // alternative views
      if (that.alternativeviews) {
        var videos = [video];
        var videoWidth = Math.floor(that.width / 5);

        function showControls(e) {
          return e.target.setAttribute('controls', true);
        }

        var hideControls = function hideControls(e) {
          return e.target.removeAttribute('controls');
        };

        var playAll = function playAll() {
          for (var i = 0; i < videos.length; i++) {
            videos[i].play();
          }
        };

        var pauseAll = function pauseAll() {
          for (var i = 0; i < videos.length; i++) {
            videos[i].pause();
          }
        };

        var seekAll = function seekAll(e) {
          for (var i = 0; i < videos.length; i++) {
            var currentVideo = videos[i];
            if (currentVideo === e.target) {
              continue;
            }
            currentVideo.currentTime = e.target.currentTime;
          }
        };

        var makeBig = function makeBig(e) {
          for (var i = 0, j = 0; i < videos.length; i++) {
            var currentVideo = videos[i];
            if (currentVideo === e.target) {
              currentVideo.classList.remove('small');
              currentVideo.classList.add('big');
              currentVideo.addEventListener('mouseover', showControls);
              currentVideo.addEventListener('mouseout', hideControls);
              currentVideo.addEventListener('seeked', seekAll);
              currentVideo.style.left = 0;
            } else {
              currentVideo.classList.remove('big');
              currentVideo.classList.add('small');
              currentVideo.removeEventListener('mouseover', showControls);
              currentVideo.removeEventListener('mouseout', hideControls);
              currentVideo.removeEventListener('seeked', seekAll);
              currentVideo.style.left = (j * videoWidth) + 'px';
              currentVideo.removeAttribute('controls');
              j++;
            }
          }
        };

        that.alternativeviews.split(/\s/).forEach(function(views) {
          views = JSON.parse(views);
          var content = container.querySelector('content');
          for (var videoSource in views) {
            if (video.currentSrc.indexOf(videoSource) === -1) {
              continue;
            }
            for (var id in views[videoSource]) {
              var alternativeView = views[videoSource][id];
              console.log(alternativeView);
              var viewVideo = document.createElement('video');
              var viewSource = document.createElement('source');
              viewSource.src = alternativeView.src;
              viewVideo.appendChild(viewSource);
              viewVideo.id = id;
              viewVideo.setAttribute('title', alternativeView.title);
              video.parentNode.insertBefore(viewVideo, content);
              videos.push(viewVideo);
            }
          }
        });

        (function init() {
          for (var i = 0; i < videos.length; i++) {
            var currentVideo = videos[i];

            currentVideo.addEventListener('play', playAll);

            currentVideo.addEventListener('pause', pauseAll);

            currentVideo.addEventListener('click', makeBig);

            if (i === 0) {
              currentVideo.classList.add('big');
              currentVideo.addEventListener('mouseover', showControls);
              currentVideo.addEventListener('mouseout', hideControls);
              currentVideo.addEventListener('seeked', seekAll);
              currentVideo.muted = false;
            } else {
              currentVideo.classList.add('small');
              currentVideo.style.left = ((i - 1) * videoWidth - that.width) +
                  'px';
              currentVideo.muted = true;
            }
          }
        })();
      }

    }, false);

    // publish timeupdate events
    video.addEventListener('timeupdate', function() {
      // console.log('Received event (video): timeupdate');
      that.currentTime = video.currentTime;
      // console.log('Fired event: hypervideotimeupdate');
      that.fire(
        'hypervideotimeupdate',
        {
          currentTime: that.currentTime
        }
      );
    }, false);

    spinner = showSpinner();
    setTimeout(function() {
      initializeVideo();
      positionDataAnnotations();
      spinner.remove();
    }, 50);
  },
  pause: function() {
    return this.$.hypervideo.pause();
  },
  play: function() {
    return this.$.hypervideo.play();
  }
});<commit_msg>Made container variable visible.<commit_after>'use strict';

/* global queryRegExSelector, queryRegExSelectorAll, getYouTubeHtml5VideoUrl */
Polymer('polymer-hypervideo', {
  publish: {
    currentTime: 0,
    duration: null,
    actorsOffset: {}
  },
  created: function() {
  },
  ready: function() {
    var that = this;
    var spinner;
    var video = that.$.hypervideo;
    var container = that.$.container;

    var onMutation = function(observer, mutations) {
      var nodes = [];
      var chapters = [];
      for (var i = 0, lenI = mutations.length; i < lenI; i++) {
        var mutation = mutations[i];
        if (mutation.addedNodes) {
          for (var j = 0, lenJ = mutation.addedNodes.length; j < lenJ; j++) {
            if (/^polymer-data-/gi.test(mutation.addedNodes[j].nodeName)) {
              nodes.push(mutation.addedNodes[j]);
            }
          }
        }
      }
      if (nodes.length) {
        positionDataAnnotations(nodes);
        updateTimelineAnnotations(nodes);
      }
      that.onMutation(that, onMutation);
    };

    that.onMutation(that, onMutation);

    var CORS_PROXY = document.location.origin + '/cors/';
    document.addEventListener('trackready', function(e) {
      console.log('Received event (document): trackready');
      var data = e.detail;
      var track = document.createElement('track');
      var cuesRead = false;
      track.addEventListener('load', function(e) {
        if (!cuesRead) {
          console.log('Received event (track): load');
          cuesRead = true;
          return readCues(e.target.track.cues, data.kind);
        }
      }, false);
      track.addEventListener('cuechange', function() {
        console.log('Fired event: hypervideocuechange');
        that.fire(
          'hypervideocuechange',
          {
            activeCues: track.track.activeCues
          }
        );
      });
      var trackLoadedInterval = setInterval(function() {
        if (track.readyState >= 2) {
          clearInterval(trackLoadedInterval);
          if (!cuesRead) {
            console.log('Received event (track): readyState');
            cuesRead = true;
            return readCues(track.track.cues, data.kind);
          }
        }
      }, 100);
      track.src = data.src;
      track.default = true;
      track.kind = data.kind;
      if (track.kind === 'subtitles' || track.kind === 'captions') {
        track.srclang = 'en';
        track.track.mode = 'showing';
      } else if (track.kind === 'chapters') {
        var canvas = document.createElement('canvas');
        canvas.width = video.width;
        canvas.height = video.height;
        var ctx = canvas.getContext('2d');
        that.ctx = ctx;
        that.canvas = canvas;
      }
      video.appendChild(track);
    }, false);

    document.addEventListener('webcomponentstocready', function() {
      console.log('Received event (document): webcomponentstocready');
      // get all child <polymer-*> child nodes
      var webComponents = queryRegExSelectorAll(that, /^polymer-/gi);
      console.log('Fired event: webcomponentstoc');
      that.fire(
        'webcomponentstoc',
        {
          webComponentsToC: webComponents
        }
      );
    }, false);

    var updateTimelineAnnotations = function(opt_nodes) {
      // get all child <polymer-data-*> child nodes
      var dataAnnotations =
          opt_nodes || queryRegExSelectorAll(that, /^polymer-data-/gi);
      var annotations = [];
      dataAnnotations.forEach(function(annotation) {
        var type;
        if (/actor/gi.test(annotation.nodeName)) {
          type = 'actors';
        } else if (/overlay/gi.test(annotation.nodeName)) {
          type = 'overlays';
        } else {
          type = 'annotations';
        }
        annotations.push({
          start: parseInt(annotation.getAttribute('start'), 10),
          end: parseInt(annotation.getAttribute('end'), 10),
          type: type
        });
      });
      console.log('Fired event: dataannotations');
      that.fire(
        'dataannotations',
        {
          dataAnnotations: annotations
        }
      );

    };

    document.addEventListener('timelineready', function() {
      console.log('Received event (document): timelineready');
      updateTimelineAnnotations();
    }, false);

    // listen for events coming from the timeline component
    document.addEventListener('currenttimeupdate', function(e) {
      // console.log('Received event (document): currenttimeupdate');
      var data = e.detail;
      video.currentTime = data.currentTime;
      video.play();
    }, false);

    document.addEventListener('requeststillframes', function(e) {
      console.log('Received event (document): requeststillframes');
      spinner = showSpinner();
      var cues = e.detail.cues;
      if (!cues) {
        return;
      }
      var functions = [];
      cues.forEach(function(cue) {
        var start = cue.start;
        if (start > video.duration) {
          return;
        }
        functions.push({
          cue: cue,
          func: function() {
            video.currentTime = start;
          }
        });
      });
      var getNextStillFrame = function() {
        console.log('Received event (video): seeked');
        that.ctx.drawImage(video, 0, 0, video.clientWidth,
            video.clientHeight);
        var img = document.createElement('img');
        img.setAttribute('class', 'hypervideo');
        var url = that.canvas.toDataURL();
        img.src = url;
        var cue = functions[processedStillFrames].cue;
        console.log('Fired event: receivestillframe');
        that.fire(
          'receivestillframe',
          {
            img: img,
            text: cue.text,
            start: cue.start,
            end: cue.end
          }
        );
        processedStillFrames++;
        if (functions[processedStillFrames]) {
          return functions[processedStillFrames].func();
        } else {
          video.removeEventListener('seeked', getNextStillFrame);
          video.currentTime = 0;
          that.fire('allstillframesreceived');
          spinner.remove();
        }
      };
      var processedStillFrames = 0;
      video.addEventListener('seeked', getNextStillFrame);
      functions[processedStillFrames].func();
    });

    var initializeVideo = function() {
      // either add sources for regular video
      if (that.src) {
        that.src.split(/\s/g).forEach(function(src) {
          var source = document.createElement('source');
          source.src = src;
          video.appendChild(source);
        });
      // or add sources for YouTube video
      } else if (that.youtubevideoid) {
        getYouTubeHtml5VideoUrl(that.youtubevideoid,
            function(err, videoSources) {
          if (err) {
            return;
          }
          for (var videoSource in videoSources) {
            videoSource = videoSources[videoSource];
            var source = document.createElement('source');
            source.src = CORS_PROXY +
                encodeURIComponent(videoSource.original_url);
            source.type = videoSource.type.replace(/\+/g, ' ')
                .replace(/"/g, '\"');
            video.appendChild(source);
          }
        });
      }
      // determine video dimensions
      if (that.width) {
        that.width = parseInt(that.width, 10);
      } else {
        that.width = 400;
      }
      video.width = that.width;
      if (that.height) {
        that.height = parseInt(that.height, 10);
      } else {
        that.height = 225;
      }
      video.height = that.height;
      // add poster
      if (that.poster) {
        video.poster = that.poster;
      }
      // mute video
      if (that.muted !== null && that.muted !== 'false') {
        video.muted = true;
      }
    };

    var showSpinner = function() {
      // show spinner while the hypervideo gets prepared
      var splashDiv = document.createElement('div');
      splashDiv.classList.add('spinner');
      var splashSpinner = document.createElement('div');
      splashSpinner.classList.add('progress');
      splashDiv.appendChild(splashSpinner);
      splashDiv.style.width = video.width + 'px';
      splashDiv.style.height = video.height + 'px';
      splashDiv.style.position = 'absolute';
      splashDiv.style.top = video.offsetTop + 'px';
      splashDiv.style.left = video.offsetLeft + 'px';
      splashSpinner.style.position = 'relative';
      splashSpinner.style.top = (video.offsetHeight / 2 - 60 / 2) + 'px';
      splashSpinner.style.left = (video.offsetWidth / 2 - 60 / 2) + 'px';
      var loadingDiv = document.createElement('div');
      loadingDiv.textContent = '*';
      splashSpinner.appendChild(loadingDiv);
      container.appendChild(splashDiv);
      return splashDiv;
    };

    var positionDataAnnotations = function(opt_nodes) {
      // positions data annotations on top of the video
      var polymerData =
          opt_nodes || queryRegExSelectorAll(that, /^polymer-data-/gi);
      polymerData.forEach(function(node) {
        node.style.position = 'absolute';
        node.style.top = (video.offsetTop + 0.66 * video.offsetHeight) +
            'px';
        node.style.left = (video.offsetLeft + (0.05 * that.width)) + 'px';
        node.style.width = (0.9 * that.width) + 'px';
        node.style.display = 'none';
      });
    };

    var readCues = function(cues, kind) {
      if (!cues) {
        return;
      }
      var cueData = [];
      for (var i = 0, lenI = cues.length; i < lenI; i++) {
        var cue = cues.item ? cues.item(i) : cues[i];
        cueData.push({
          start: parseInt(cue.startTime, 10),
          end: parseInt(cue.endTime, 10),
          text: cue.text,
          id: cue.id,
          type: kind
        });
      }
      console.log('Fired event: cuesread');
      that.fire(
        'cuesread',
        {
          cueData: cueData,
          kind: kind
        }
      );
    };

    video.addEventListener('loadedmetadata', function() {
      console.log('Received event (video): loadedmetadata');
      that.duration = video.duration;
      // adjust the timeline dimensions according to the video duration
      var polymerTimelines = that.querySelectorAll('polymer-timeline');
      for (var i = 0, lenI = polymerTimelines.length; i < lenI; i++) {
        polymerTimelines[i].style.left = (video.offsetLeft +
            (0.05 * that.width)) + 'px';
      }
      var polymerData = queryRegExSelector(that, /^polymer-data-/gi);
      console.log('Fired event: hypervideoloadedmetadata');
      that.fire(
        'hypervideoloadedmetadata',
        {
          duration: that.duration,
          height: that.height,
          width: that.width,
          actorsOffset: {
            left: polymerData ? polymerData.style.left.replace('px', '') : null,
            top: polymerData ? polymerData.style.top.replace('px', '') : null
          }
        }
      );

      // alternative views
      if (that.alternativeviews) {
        var videos = [video];
        var videoWidth = Math.floor(that.width / 5);

        function showControls(e) {
          return e.target.setAttribute('controls', true);
        }

        var hideControls = function hideControls(e) {
          return e.target.removeAttribute('controls');
        };

        var playAll = function playAll() {
          for (var i = 0; i < videos.length; i++) {
            videos[i].play();
          }
        };

        var pauseAll = function pauseAll() {
          for (var i = 0; i < videos.length; i++) {
            videos[i].pause();
          }
        };

        var seekAll = function seekAll(e) {
          for (var i = 0; i < videos.length; i++) {
            var currentVideo = videos[i];
            if (currentVideo === e.target) {
              continue;
            }
            currentVideo.currentTime = e.target.currentTime;
          }
        };

        var makeBig = function makeBig(e) {
          for (var i = 0, j = 0; i < videos.length; i++) {
            var currentVideo = videos[i];
            if (currentVideo === e.target) {
              currentVideo.classList.remove('small');
              currentVideo.classList.add('big');
              currentVideo.addEventListener('mouseover', showControls);
              currentVideo.addEventListener('mouseout', hideControls);
              currentVideo.addEventListener('seeked', seekAll);
              currentVideo.style.left = 0;
            } else {
              currentVideo.classList.remove('big');
              currentVideo.classList.add('small');
              currentVideo.removeEventListener('mouseover', showControls);
              currentVideo.removeEventListener('mouseout', hideControls);
              currentVideo.removeEventListener('seeked', seekAll);
              currentVideo.style.left = (j * videoWidth) + 'px';
              currentVideo.removeAttribute('controls');
              j++;
            }
          }
        };

        that.alternativeviews.split(/\s/).forEach(function(views) {
          views = JSON.parse(views);
          var content = container.querySelector('content');
          for (var videoSource in views) {
            if (video.currentSrc.indexOf(videoSource) === -1) {
              continue;
            }
            for (var id in views[videoSource]) {
              var alternativeView = views[videoSource][id];
              console.log(alternativeView);
              var viewVideo = document.createElement('video');
              var viewSource = document.createElement('source');
              viewSource.src = alternativeView.src;
              viewVideo.appendChild(viewSource);
              viewVideo.id = id;
              viewVideo.setAttribute('title', alternativeView.title);
              video.parentNode.insertBefore(viewVideo, content);
              videos.push(viewVideo);
            }
          }
        });

        (function init() {
          for (var i = 0; i < videos.length; i++) {
            var currentVideo = videos[i];

            currentVideo.addEventListener('play', playAll);

            currentVideo.addEventListener('pause', pauseAll);

            currentVideo.addEventListener('click', makeBig);

            if (i === 0) {
              currentVideo.classList.add('big');
              currentVideo.addEventListener('mouseover', showControls);
              currentVideo.addEventListener('mouseout', hideControls);
              currentVideo.addEventListener('seeked', seekAll);
              currentVideo.muted = false;
            } else {
              currentVideo.classList.add('small');
              currentVideo.style.left = ((i - 1) * videoWidth - that.width) +
                  'px';
              currentVideo.muted = true;
            }
          }
        })();
      }

    }, false);

    // publish timeupdate events
    video.addEventListener('timeupdate', function() {
      // console.log('Received event (video): timeupdate');
      that.currentTime = video.currentTime;
      // console.log('Fired event: hypervideotimeupdate');
      that.fire(
        'hypervideotimeupdate',
        {
          currentTime: that.currentTime
        }
      );
    }, false);

    spinner = showSpinner();
    setTimeout(function() {
      initializeVideo();
      positionDataAnnotations();
      spinner.remove();
    }, 50);
  },
  pause: function() {
    return this.$.hypervideo.pause();
  },
  play: function() {
    return this.$.hypervideo.play();
  }
});<|endoftext|>