/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// create a fake namespace object
/******/ 	// mode & 1: value is a module id, require it
/******/ 	// mode & 2: merge all properties of value into the ns
/******/ 	// mode & 4: return value when already ns object
/******/ 	// mode & 8|1: behave like require
/******/ 	__webpack_require__.t = function(value, mode) {
/******/ 		if(mode & 1) value = __webpack_require__(value);
/******/ 		if(mode & 8) return value;
/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ 		var ns = Object.create(null);
/******/ 		__webpack_require__.r(ns);
/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ 		return ns;
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = "./src/tabScript/index.ts");
/******/ })
/************************************************************************/
/******/ ({

/***/ "./node_modules/query-selector-shadow-dom/src/querySelectorDeep.js":
/*!*************************************************************************!*\
  !*** ./node_modules/query-selector-shadow-dom/src/querySelectorDeep.js ***!
  \*************************************************************************/
/*! exports provided: querySelectorAllDeep, querySelectorDeep */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "querySelectorAllDeep", function() { return querySelectorAllDeep; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "querySelectorDeep", function() { return querySelectorDeep; });
/**
 * @author Georgegriff@ (George Griffiths)
 * License Apache-2.0
 */

/**
* Finds first matching elements on the page that may be in a shadow root using a complex selector of n-depth
*
* Don't have to specify all shadow roots to button, tree is travered to find the correct element
*
* Example querySelectorAllDeep('downloads-item:nth-child(4) #remove');
*
* Example should work on chrome://downloads outputting the remove button inside of a download card component
*
* Example find first active download link element querySelectorDeep('#downloads-list .is-active a[href^="https://"]');
*
* Another example querySelectorAllDeep('#downloads-list div#title-area + a');
e.g.
*/
function querySelectorAllDeep(selector, root = document) {
    return _querySelectorDeep(selector, true, root);
}

function querySelectorDeep(selector, root = document) {
    return _querySelectorDeep(selector, false, root);
}

function _querySelectorDeep(selector, findMany, root) {
    selector = normalizeSelector(selector)
    let lightElement = root.querySelector(selector);

    if (document.head.createShadowRoot || document.head.attachShadow) {
        // no need to do any special if selector matches something specific in light-dom
        if (!findMany && lightElement) {
            return lightElement;
        }

        // split on commas because those are a logical divide in the operation
        const selectionsToMake = splitByCharacterUnlessQuoted(selector, ',');

        return selectionsToMake.reduce((acc, minimalSelector) => {
            // if not finding many just reduce the first match
            if (!findMany && acc) {
                return acc;
            }
            // do best to support complex selectors and split the query
            const splitSelector = splitByCharacterUnlessQuoted(minimalSelector
                    //remove white space at start of selector
                    .replace(/^\s+/g, '')
                    .replace(/\s*([>+~]+)\s*/g, '$1'), ' ')
                // filter out entry white selectors
                .filter((entry) => !!entry);
            const possibleElementsIndex = splitSelector.length - 1;
            const possibleElements = collectAllElementsDeep(splitSelector[possibleElementsIndex], root);
            const findElements = findMatchingElement(splitSelector, possibleElementsIndex, root);
            if (findMany) {
                acc = acc.concat(possibleElements.filter(findElements));
                return acc;
            } else {
                acc = possibleElements.find(findElements);
                return acc || null;
            }
        }, findMany ? [] : null);


    } else {
        if (!findMany) {
            return lightElement;
        } else {
            return root.querySelectorAll(selector);
        }
    }

}

function findMatchingElement(splitSelector, possibleElementsIndex, root) {
    return (element) => {
        let position = possibleElementsIndex;
        let parent = element;
        let foundElement = false;
        while (parent && !isDocumentNode(parent)) {
            const foundMatch = parent.matches(splitSelector[position]);
            if (foundMatch && position === 0) {
                foundElement = true;
                break;
            }
            if (foundMatch) {
                position--;
            }
            parent = findParentOrHost(parent, root);
        }
        return foundElement;
    };

}

function splitByCharacterUnlessQuoted(selector, character) {
    return selector.match(/\\?.|^$/g).reduce((p, c) => {
        if (c === '"' && !p.sQuote) {
            p.quote ^= 1;
            p.a[p.a.length - 1] += c;
        } else if (c === '\'' && !p.quote) {
            p.sQuote ^= 1;
            p.a[p.a.length - 1] += c;

        } else if (!p.quote && !p.sQuote && c === character) {
            p.a.push('');
        } else {
            p.a[p.a.length - 1] += c;
        }
        return p;
    }, { a: [''] }).a;
}

/**
 * Checks if the node is a document node or not.
 * @param {Node} node
 * @returns {node is Document | DocumentFragment}
 */
function isDocumentNode(node) {
    return node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.DOCUMENT_NODE;
}

function findParentOrHost(element, root) {
    const parentNode = element.parentNode;
    return (parentNode && parentNode.host && parentNode.nodeType === 11) ? parentNode.host : parentNode === root ? null : parentNode;
}

/**
 * Finds all elements on the page, inclusive of those within shadow roots.
 * @param {string=} selector Simple selector to filter the elements by. e.g. 'a', 'div.main'
 * @return {!Array<string>} List of anchor hrefs.
 * @author ebidel@ (Eric Bidelman)
 * License Apache-2.0
 */
function collectAllElementsDeep(selector = null, root) {
    const allElements = [];

    const findAllElements = function(nodes) {
        for (let i = 0, el; el = nodes[i]; ++i) {
            allElements.push(el);
            // If the element has a shadow root, dig deeper.
            if (el.shadowRoot) {
                findAllElements(el.shadowRoot.querySelectorAll('*'));
            }
        }
    };
    if(root.shadowRoot) {
        findAllElements(root.shadowRoot.querySelectorAll('*'));
    }
    findAllElements(root.querySelectorAll('*'));

    return selector ? allElements.filter(el => el.matches(selector)) : allElements;
}


// normalize-selector-rev-02.js
/*
  author: kyle simpson (@getify)
  original source: https://gist.github.com/getify/9679380

  modified for tests by david kaye (@dfkaye)
  21 march 2014

  rev-02 incorporate kyle's changes 3/2/42014
*/
  /*  istanbul ignore next */
  function normalizeSelector(sel) {

    // save unmatched text, if any
    function saveUnmatched() {
      if (unmatched) {
        // whitespace needed after combinator?
        if (tokens.length > 0 &&
          /^[~+>]$/.test(tokens[tokens.length-1])
        ) {
          tokens.push(" ");
        }

        // save unmatched text
        tokens.push(unmatched);
      }
    }

    var tokens = [], match, unmatched, regex, state = [0],
      next_match_idx = 0, prev_match_idx,
      not_escaped_pattern = /(?:[^\\]|(?:^|[^\\])(?:\\\\)+)$/,
      whitespace_pattern = /^\s+$/,
      state_patterns = [
        /\s+|\/\*|["'>~+\[\(]/g, // general
        /\s+|\/\*|["'\[\]\(\)]/g, // [..] set
        /\s+|\/\*|["'\[\]\(\)]/g, // (..) set
        null, // string literal (placeholder)
        /\*\//g // comment
      ]
    ;

    sel = sel.trim();

    while (true) {
      unmatched = "";

      regex = state_patterns[state[state.length-1]];

      regex.lastIndex = next_match_idx;
      match = regex.exec(sel);

      // matched text to process?
      if (match) {
        prev_match_idx = next_match_idx;
        next_match_idx = regex.lastIndex;

        // collect the previous string chunk not matched before this token
        if (prev_match_idx < next_match_idx - match[0].length) {
          unmatched = sel.substring(prev_match_idx,next_match_idx - match[0].length);
        }

        // general, [ ] pair, ( ) pair?
        if (state[state.length-1] < 3) {
          saveUnmatched();

          // starting a [ ] pair?
          if (match[0] === "[") {
            state.push(1);
          }
          // starting a ( ) pair?
          else if (match[0] === "(") {
            state.push(2);
          }
          // starting a string literal?
          else if (/^["']$/.test(match[0])) {
            state.push(3);
            state_patterns[3] = new RegExp(match[0],"g");
          }
          // starting a comment?
          else if (match[0] === "/*") {
            state.push(4);
          }
          // ending a [ ] or ( ) pair?
          else if (/^[\]\)]$/.test(match[0]) && state.length > 0) {
            state.pop();
          }
          // handling whitespace or a combinator?
          else if (/^(?:\s+|[~+>])$/.test(match[0])) {

            // need to insert whitespace before?
            if (tokens.length > 0 &&
              !whitespace_pattern.test(tokens[tokens.length-1]) &&
              state[state.length-1] === 0
            ) {
              // add normalized whitespace
              tokens.push(" ");
            }

            // case-insensitive attribute selector CSS L4
            if (state[state.length-1] === 1 &&
                tokens.length === 5 &&
                tokens[2].charAt(tokens[2].length-1) === '=') {
                tokens[4] = " " + tokens[4];
            }

            // whitespace token we can skip?
            if (whitespace_pattern.test(match[0])) {
              continue;
            }
          }

          // save matched text
          tokens.push(match[0]);
        }
        // otherwise, string literal or comment
        else {
          // save unmatched text
          tokens[tokens.length-1] += unmatched;

          // unescaped terminator to string literal or comment?
          if (not_escaped_pattern.test(tokens[tokens.length-1])) {
            // comment terminator?
            if (state[state.length-1] === 4) {
              // ok to drop comment?
              if (tokens.length < 2 ||
                whitespace_pattern.test(tokens[tokens.length-2])
              ) {
                tokens.pop();
              }
              // otherwise, turn comment into whitespace
              else {
                tokens[tokens.length-1] = " ";
              }

              // handled already
              match[0] = "";
            }

            state.pop();
          }

          // append matched text to existing token
          tokens[tokens.length-1] += match[0];
        }
      }
      // otherwise, end of processing (no more matches)
      else {
        unmatched = sel.substr(next_match_idx);
        saveUnmatched();

        break;
      }
    }

    return tokens.join("").trim();
  }

/***/ }),

/***/ "./src/tabScript/_infra/ChromeBackgroundMessageService.ts":
/*!****************************************************************!*\
  !*** ./src/tabScript/_infra/ChromeBackgroundMessageService.ts ***!
  \****************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const State_1 = __importDefault(__webpack_require__(/*! ../domain/State */ "./src/tabScript/domain/State.ts"));
const ActionProbabilityMap_1 = __importDefault(__webpack_require__(/*! ../domain/ActionProbabilityMap */ "./src/tabScript/domain/ActionProbabilityMap.ts"));
const Comment_1 = __importDefault(__webpack_require__(/*! ../domain/Comment */ "./src/tabScript/domain/Comment.ts"));
const Action_1 = __importDefault(__webpack_require__(/*! ../domain/Action */ "./src/tabScript/domain/Action.ts"));
class ChromeBackgroundService {
    getState() {
        return new Promise((resolve, reject) => {
            chrome.runtime.sendMessage({
                kind: 'getStateForTabScript'
            }, {}, data => {
                const error = chrome.runtime.lastError;
                if (error) {
                    return reject(error);
                }
                else {
                    let isActive = data.isRecording ? true : false;
                    const state = new State_1.default(data.commentsUp, data.isDisplayingComments, isActive, data.webSite, data.popupCommentPosition);
                    return resolve(state);
                }
            });
        });
    }
    getProbabilityMap() {
        return new Promise((resolve, reject) => {
            chrome.runtime.sendMessage({
                kind: 'getProbabilities'
            }, {}, data => {
                const error = chrome.runtime.lastError;
                if (error) {
                    return reject(error);
                }
                if (data === null || data === void 0 ? void 0 : data.probabilityMap) {
                    return resolve(new ActionProbabilityMap_1.default(data.probabilityMap));
                }
                else {
                    return resolve(new ActionProbabilityMap_1.default(new Map()));
                }
            });
        });
    }
    getCommentList() {
        return new Promise((resolve, reject) => {
            chrome.runtime.sendMessage({
                kind: 'getComments'
            }, {}, data => {
                const error = chrome.runtime.lastError;
                if (error) {
                    return reject(error);
                }
                const comments = [];
                if (data === null || data === void 0 ? void 0 : data.commentDistributionList) {
                    let commentDistributionList = data.commentDistributionList;
                    for (const commentData of commentDistributionList) {
                        const comment = Comment_1.default.parseComment(commentData.note);
                        for (const distribution of commentData.distributions) {
                            comment.addDistribution(distribution.noteOccurence, distribution.contextOccurence, distribution.context.map(actionText => Action_1.default.parseAction(actionText)));
                        }
                        comments.push(comment);
                    }
                }
                return resolve(comments);
            });
        });
    }
    setCommentPopupPosition(newPosition) {
        return new Promise((resolve, reject) => {
            chrome.runtime.sendMessage({
                kind: 'setPopupCommentPosition',
                popupCommentPosition: newPosition
            }, {}, () => {
                const error = chrome.runtime.lastError;
                if (error) {
                    return reject(error);
                }
                else {
                    return resolve();
                }
            });
        });
    }
    upComment(comment) {
        return new Promise((resolve, reject) => {
            chrome.runtime.sendMessage({
                kind: 'upComment',
                type: comment.type,
                value: comment.note
            }, {}, () => {
                const error = chrome.runtime.lastError;
                if (error) {
                    return reject(error);
                }
                else {
                    return resolve();
                }
            });
        });
    }
    sendAction(action) {
        return new Promise((resolve, reject) => {
            chrome.runtime.sendMessage({
                action,
                kind: 'pushAction'
            }, {}, () => {
                const error = chrome.runtime.lastError;
                if (error) {
                    return reject(error);
                }
                else {
                    return resolve();
                }
            });
        });
    }
}
exports.default = ChromeBackgroundService;


/***/ }),

/***/ "./src/tabScript/_infra/ChromeMessageListener.ts":
/*!*******************************************************!*\
  !*** ./src/tabScript/_infra/ChromeMessageListener.ts ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
class ChromeMessageListener {
    constructor(styleApplication, eventListener) {
        this.styleApplication = styleApplication;
        this.eventListener = eventListener;
    }
    listenBackground() {
        chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
            const error = chrome.runtime.lastError;
            if (error) {
                console.error(error);
            }
            switch (msg.kind) {
                case "explorationStarted":
                    this.styleApplication.onExplorationStarted();
                    this.eventListener.onExplorationStarted();
                    sendResponse("ok");
                    break;
                case "explorationStopped":
                    this.styleApplication.onExplorationStopped();
                    this.eventListener.onExplorationStopped();
                    sendResponse("ok");
                    break;
                case "reload":
                    this.styleApplication.onReload();
                    this.eventListener.onReload();
                    sendResponse("ok");
                    break;
                case "checkRunning":
                    sendResponse("ok");
                    break;
                default:
                    console.log("unhandled message ", msg);
                    sendResponse("ok");
            }
        });
    }
}
exports.default = ChromeMessageListener;


/***/ }),

/***/ "./src/tabScript/_ui/ActionBorderView.ts":
/*!***********************************************!*\
  !*** ./src/tabScript/_ui/ActionBorderView.ts ***!
  \***********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const query_selector_shadow_dom_1 = __webpack_require__(/*! query-selector-shadow-dom */ "./node_modules/query-selector-shadow-dom/src/querySelectorDeep.js");
const cssStyle_1 = __importDefault(__webpack_require__(/*! ./cssStyle */ "./src/tabScript/_ui/cssStyle.ts"));
class ActionBorderView {
    constructor() {
        this.stylesheetElement = null;
    }
    init(state, ruleService) {
        return new Promise(resolve => {
            this.attachStyleSheet(document.head);
            ruleService.attachRulesToElements();
            for (const [dom_element, rules] of ruleService.elementRules) {
                const rootNode = dom_element.getRootNode();
                if (rootNode !== document) {
                    this.attachStyleSheet(rootNode);
                }
                dom_element.setAttribute("aifex_frequency", null);
                if (state.isActive) {
                    dom_element.setAttribute("aifex_style", "true");
                }
                else {
                    dom_element.setAttribute("aifex_style", "false");
                }
                for (const rule of rules) {
                    dom_element.setAttribute(`aifex_${rule.prefix}`, "true");
                }
            }
            resolve();
        });
    }
    refresh(state, ruleService) {
        return this.init(state, ruleService).then(() => {
            const promises = [];
            for (const [element, actionList] of state.elementActionListMap) {
                promises.push(new Promise(resolve => {
                    let maxProbability = 0;
                    for (let action of actionList) {
                        if (action.probability > maxProbability) {
                            maxProbability = action.probability;
                        }
                    }
                    if (maxProbability > 0.6) {
                        element.setAttribute("aifex_frequency", "often");
                    }
                    else if (maxProbability > 0.3) {
                        element.setAttribute("aifex_frequency", "sometimes");
                    }
                    else if (maxProbability > 0.01) {
                        element.setAttribute("aifex_frequency", "rarely");
                    }
                    else {
                        element.setAttribute("aifex_frequency", "never");
                    }
                    resolve();
                }));
            }
            return Promise.all(promises).then();
        });
    }
    attachStyleSheet(node) {
        const nodeChilds = Array.from(node.children);
        if (nodeChilds.some(node => node.hasAttribute("aifex_stylesheet"))) {
            return;
        }
        if (this.stylesheetElement) {
            node.appendChild(this.stylesheetElement.cloneNode(true));
        }
        else {
            this.stylesheetElement = document.createElement("style");
            this.stylesheetElement.setAttribute("type", "text/css");
            this.stylesheetElement.setAttribute("aifex_stylesheet", "true");
            const cssNode = document.createTextNode(cssStyle_1.default);
            this.stylesheetElement.appendChild(cssNode);
            node.appendChild(this.stylesheetElement);
        }
    }
    clear(ruleService) {
        return new Promise((resolve) => {
            const dom_elements = query_selector_shadow_dom_1.querySelectorAllDeep("[aifex_style]");
            for (const dom_element of dom_elements) {
                if (!ruleService.elementRules.has(dom_element)) {
                    dom_element.removeAttribute("aifex_frequency");
                    dom_element.removeAttribute("aifex_style");
                }
            }
            resolve();
        });
    }
    hide() {
        return new Promise(resolve => {
            const dom_elements = query_selector_shadow_dom_1.querySelectorAllDeep("[aifex_style]");
            for (const element of dom_elements) {
                element.setAttribute("aifex_style", false);
            }
            resolve();
        });
    }
    show() {
        return new Promise(resolve => {
            const dom_elements = query_selector_shadow_dom_1.querySelectorAllDeep("[aifex_style]");
            for (const element of dom_elements) {
                element.setAttribute("aifex_style", true);
            }
            resolve();
        });
    }
}
exports.default = ActionBorderView;


/***/ }),

/***/ "./src/tabScript/_ui/ActionsPopupView.ts":
/*!***********************************************!*\
  !*** ./src/tabScript/_ui/ActionsPopupView.ts ***!
  \***********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const query_selector_shadow_dom_1 = __webpack_require__(/*! query-selector-shadow-dom */ "./node_modules/query-selector-shadow-dom/src/querySelectorDeep.js");
const PROBABILITY_POPUP = "probabilityPopup";
class ActionsPopupView {
    constructor(onMouseHoverAction) {
        this.hoveredElement = null;
        this.elementToMouseHandlerMap = new Map();
        this.onMouseHoverAction = onMouseHoverAction;
    }
    init() {
        return new Promise(resolve => {
            const probabilityPopup = document.createElement("div");
            probabilityPopup.setAttribute("id", PROBABILITY_POPUP);
            document.body.appendChild(probabilityPopup);
            probabilityPopup.style.position = "absolute";
            document.body.addEventListener('mousemove', (e) => {
                let x = e.pageX;
                let bounding = document.body.getBoundingClientRect();
                if (e.pageX + probabilityPopup.offsetWidth > bounding.right) {
                    x = bounding.right - probabilityPopup.offsetWidth;
                }
                probabilityPopup.style.left = x + 'px';
                probabilityPopup.style.top = e.pageY + 'px';
            });
            setInterval(function () {
                if (this.hoveredElement) {
                    const hoveredElements = query_selector_shadow_dom_1.querySelectorAllDeep(':hover');
                    let found = false;
                    for (const hovered of hoveredElements) {
                        if (hovered === this.hoveredElement) {
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        return this.hide();
                    }
                }
            }, 1000);
            resolve();
        }).then(() => this.hide());
    }
    clear() {
        return new Promise((resolve) => {
            for (const element of this.elementToMouseHandlerMap.keys()) {
                const { show, hide } = this.elementToMouseHandlerMap.get(element);
                if (element) {
                    element.removeEventListener("mouseenter", show);
                    element.removeEventListener("mouseleave", hide);
                }
                this.elementToMouseHandlerMap.delete(element);
            }
            resolve();
        });
    }
    hide() {
        const probabilityPopup = document.getElementById(PROBABILITY_POPUP);
        probabilityPopup.style.visibility = "hidden";
        return Promise.resolve();
    }
    show() {
        const probabilityPopup = document.getElementById(PROBABILITY_POPUP);
        probabilityPopup.style.visibility = "visible";
        return Promise.resolve();
    }
    refresh(state) {
        return this.attach(state).then(() => {
            const probabilityPopup = document.getElementById(PROBABILITY_POPUP);
            while (probabilityPopup.firstChild) {
                probabilityPopup.removeChild(probabilityPopup.firstChild);
            }
            const P_elements = [];
            const actionList = state.elementActionListMap.get(this.hoveredElement);
            if (!actionList) {
                return Promise.resolve();
            }
            for (const action of Array.from(actionList).slice(0, 9)) {
                const probability = (action.probability * 100).toFixed(2);
                const P_element = document.createElement("p");
                P_element.classList.add("popupItem");
                const actionSpan = document.createElement("span");
                actionSpan.classList.add("popupAction");
                actionSpan.textContent = `${action.toString()}: `;
                const probabilitySpan = document.createElement("span");
                probabilitySpan.classList.add("popupProbability");
                probabilitySpan.textContent = `${probability}%`;
                P_element.appendChild(actionSpan);
                P_element.appendChild(probabilitySpan);
                P_elements.push(P_element);
            }
            if (P_elements.length > 0) {
                P_elements.forEach(p => probabilityPopup.appendChild(p));
            }
        });
    }
    attach(state) {
        return this.clear().then(() => {
            for (const element of state.elementActionListMap.keys()) {
                if (this.elementToMouseHandlerMap.has(element)) {
                    const { show, hide } = this.elementToMouseHandlerMap.get(element);
                    element.removeEventListener("mouseenter", show);
                    element.removeEventListener("mouseleave", hide);
                }
                let show = (event) => {
                    this.hoveredElement = event.target;
                    this.onMouseHoverAction();
                };
                let hide = () => {
                    this.hoveredElement = null;
                    this.hide();
                };
                this.elementToMouseHandlerMap.set(element, {
                    show,
                    hide
                });
                element.addEventListener("mouseenter", show);
                element.addEventListener("mouseleave", hide);
            }
        });
    }
}
exports.default = ActionsPopupView;


/***/ }),

/***/ "./src/tabScript/_ui/CommentPopupView.ts":
/*!***********************************************!*\
  !*** ./src/tabScript/_ui/CommentPopupView.ts ***!
  \***********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const COMMENT_SECTION = "commentSection";
const COMMENT_SECTION_HEANDER = "commentSectionHeader";
const COMMENT_SECTION_BODY = "commentSectionBody";
class CommentPopupView {
    constructor(onCommentPopupMove, onCommentUp) {
        this.onCommentPopupMove = onCommentPopupMove;
        this.onCommentUp = onCommentUp;
    }
    init(position) {
        return new Promise((resolve) => {
            this.position = position;
            let oldCommentSection = document.getElementById(COMMENT_SECTION);
            if (oldCommentSection) {
                oldCommentSection.remove();
            }
            this.section = document.createElement("div");
            this.section.style.visibility = "hidden";
            this.section.setAttribute("id", COMMENT_SECTION);
            document.body.appendChild(this.section);
            this.header = document.createElement("div");
            this.header.setAttribute("id", COMMENT_SECTION_HEANDER);
            this.body = document.createElement("div");
            this.body.setAttribute("id", COMMENT_SECTION_BODY);
            this.header.addEventListener("dblclick", this.dropdownCommentSectionBody);
            this.section.appendChild(this.header);
            this.section.appendChild(this.body);
            this.dragPopup();
            resolve();
        });
    }
    refresh(state) {
        if (!state.displayComments) {
            return this.hide();
        }
        return this.show(state).then(() => {
            if (state.isActive) {
                document.getElementById(COMMENT_SECTION).style.visibility = "visible";
            }
            else {
                this.hide();
            }
            let body = document.getElementById(COMMENT_SECTION_BODY);
            while (body.firstElementChild) {
                body.firstElementChild.remove();
            }
            this.setCommentSectionHeader(state.commentList);
            for (const comment of state.commentList) {
                this.addCommentInCommentSection(state.commentsUp, comment);
            }
        });
    }
    hide() {
        const commentSection = document.getElementById(COMMENT_SECTION);
        commentSection.hidden = true;
        return Promise.resolve();
    }
    show(state) {
        const commentSection = document.getElementById(COMMENT_SECTION);
        commentSection.hidden = false;
        return Promise.resolve();
    }
    setCommentSectionHeader(commentList) {
        let header = document.getElementById(COMMENT_SECTION_HEANDER);
        if (header.firstElementChild) {
            header.removeChild(header.firstElementChild);
        }
        let headerText = document.createElement("p");
        headerText.innerText = `Comments : ${commentList.length}`;
        header.classList.remove(...header.classList);
        if (commentList.length > 0) {
            header.classList.add("commentSectionHeaderNotEmpty");
        }
        else {
            header.classList.add("commentSectionHeaderEmpty");
        }
        header.appendChild(headerText);
    }
    addCommentInCommentSection(commentsUp, comment) {
        let body = document.getElementById(COMMENT_SECTION_BODY);
        let commentInfo = document.createElement("div");
        body.appendChild(commentInfo);
        let commentConfirmButton = document.createElement("button");
        if (!commentsUp.some(commentUp => commentUp.note === comment.note)) {
            commentConfirmButton.classList.add("commentUpButton");
            commentConfirmButton.innerText = "up";
            commentConfirmButton.addEventListener("click", (e) => this.confirmCommentCallback(e, comment));
            commentInfo.appendChild(commentConfirmButton);
        }
        let commentKind = document.createElement("span");
        commentKind.classList.add("commentKind");
        commentKind.innerText = comment.type;
        let commentMessage = document.createElement("span");
        commentMessage.classList.add("commentMessage");
        if (comment.note !== undefined) {
            commentMessage.innerText = comment.note;
        }
        let commentContext = document.createElement("div");
        commentContext.classList.add("commentContext");
        for (const distribution of comment.distributionList) {
            let contextDetail = document.createElement("div");
            let contextDetailOccurence = document.createElement("span");
            contextDetailOccurence.classList.add("commentOccurence");
            if (distribution.noteOccurence === 0) {
                continue;
            }
            contextDetailOccurence.innerText = `${distribution.noteOccurence} / ${distribution.occurence}̀`;
            contextDetail.appendChild(contextDetailOccurence);
            distribution.actions.forEach((action) => {
                const contextNode = document.createElement("span");
                contextNode.classList.add("commentActionContext");
                contextNode.innerText = action.toString();
                contextDetail.appendChild(contextNode);
            });
            commentContext.appendChild(contextDetail);
        }
        commentInfo.appendChild(commentKind);
        commentInfo.appendChild(commentMessage);
        commentInfo.appendChild(commentContext);
    }
    dropdownCommentSectionBody(e) {
        e.preventDefault();
        let sectionBody = document.getElementById(COMMENT_SECTION_BODY);
        if (sectionBody.style.display === "none") {
            sectionBody.style.display = "block";
        }
        else {
            sectionBody.style.display = "none";
        }
    }
    confirmCommentCallback(e, comment) {
        e.preventDefault();
        if (!e.target.disabled) {
            this.onCommentUp(comment).then(() => {
                e.target.remove();
            });
        }
    }
    dragPopup() {
        var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
        this.section.style.top = this.position.y;
        this.section.style.left = this.position.x;
        const dragMouseDownCallback = dragMouseDown.bind(this);
        const elementDragCallback = elementDrag.bind(this);
        const closeDragElementCallback = closeDragElement.bind(this);
        this.header.addEventListener('mousedown', dragMouseDownCallback);
        function dragMouseDown(e) {
            e = e || window.event;
            e.preventDefault();
            pos3 = e.clientX;
            pos4 = e.clientY;
            document.addEventListener("mouseup", closeDragElementCallback);
            document.addEventListener("mousemove", elementDragCallback);
        }
        function elementDrag(e) {
            e = e || window.event;
            e.preventDefault();
            pos1 = pos3 - e.clientX;
            pos2 = pos4 - e.clientY;
            pos3 = e.clientX;
            pos4 = e.clientY;
            this.section.style.top = (this.section.offsetTop - pos2) + "px";
            this.section.style.left = (this.section.offsetLeft - pos1) + "px";
        }
        function closeDragElement() {
            document.removeEventListener("mouseup", closeDragElementCallback);
            document.removeEventListener("mousemove", elementDragCallback);
            let x = this.section.style.left;
            let y = this.section.style.top;
            this.onCommentPopupMove({ x, y });
        }
    }
}
exports.default = CommentPopupView;


/***/ }),

/***/ "./src/tabScript/_ui/PageMutationHandler.ts":
/*!**************************************************!*\
  !*** ./src/tabScript/_ui/PageMutationHandler.ts ***!
  \**************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const MUTATION_REFRESH_CHECK = 3000;
const DOM_IDS = ["probabilityPopup", "commentSection", "commentSectionHeader", "commentSectionBody"];
class PageMutationHandler {
    constructor(onPageMutation) {
        this.onPageMutation = onPageMutation;
    }
    init() {
        this.lastMutation = Date.now();
        this.observer = new MutationObserver((records) => {
            let watchedPageHasMutated = true;
            for (const record of records) {
                for (const id of Object.values(DOM_IDS)) {
                    const element = document.getElementById(id);
                    if (element && element.contains(record.target)) {
                        watchedPageHasMutated = false;
                        break;
                    }
                }
                if (!watchedPageHasMutated) {
                    break;
                }
            }
            if (watchedPageHasMutated) {
                this.mutationHasOccured = true;
            }
        });
        let config = { attributes: true, childList: true, characterData: true, subtree: true };
        this.observer.observe(document.body, config);
        setInterval(() => {
            if (this.mutationHasOccured) {
                this.onPageMutation();
            }
        }, MUTATION_REFRESH_CHECK);
    }
}
exports.default = PageMutationHandler;


/***/ }),

/***/ "./src/tabScript/_ui/cssStyle.ts":
/*!***************************************!*\
  !*** ./src/tabScript/_ui/cssStyle.ts ***!
  \***************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.default = `

[aifex_style=true][aifex_frequency=null] {
  border: 4px solid #2196F3 !important;
}
[aifex_style=true][aifex_frequency=never] {
  border: 4px solid #2196F3 !important;
}
[aifex_style=true][aifex_frequency=rarely]  {
  border: 4px solid #9ACD32 !important;
}
[aifex_style=true][aifex_frequency=sometimes]  {
  border: 4px solid #FFA500 !important;
}
[aifex_style=true][aifex_frequency=often]  {
  border: 4px solid #ff0000 !important;
}
[aifex_style=true][aifex_frequency=session]  {
  border: 4px solid #00cc00 !important;
}
[aifex_style=true][aifex_frequency=followed]  {
  border: 4px solid #ff8000 !important;
}
[aifex_style=true][aifex_frequency=both]  {
  border: 4px solid #b30000 !important;
}

[aifex_style=true][aifex_next_action=true]  {
  border-style: dashed !important;
}

#probabilityPopup {
  background: rgba(30, 32, 44, .95);
  max-width: 400px;
  height: initial;
  margin-top: 1em;
  padding: 20px;
  font-size: 14px;
  line-height: 24px;
  min-width: 250px !important;
  position: absolute;
  text-align: left;
  will-change: transform;
  border-radius: 14px;
  box-shadow: rgba(0, 0, 0, 0.12) 0px 0px 8px 0px, rgba(0, 0, 0, 0.24) 0px 4px 8px 0px;
  visibility: hidden;
  z-index: 9999;
}

.popupAction {
  color: #bd93f9;
}

.popupProbability {
  color: #ff0000;
  margin-left: 5px;
}

.popupProbabilityFollowed {
  color: #ffA500;
  margin-left: 5px;
}

.popupCommentType{
  color: rgb(241, 250, 140)
}

.popupCommentDescription{
  color: rgb(238, 238, 238);
}

.comment{
  padding-left: 30px
}

#commentSection {
  position: fixed;
  background: rgba(30, 32, 44, .95);
  max-width: 400px;
  height: initial;
  padding: 20px;
  font-size: 14px;
  line-height: 24px;
  min-width: 250px !important;
  text-align: left;
  will-change: transform;
  border-radius: 14px;
  box-shadow: rgba(0, 0, 0, 0.12) 0px 0px 8px 0px, rgba(0, 0, 0, 0.24) 0px 4px 8px 0px;
  z-index: 9999;
}

#commentSectionHeader {
  border-radius: 14px;
  box-shadow: rgba(0, 0, 0, 0.12) 0px 0px 8px 0px, rgba(0, 0, 0, 0.24) 0px 4px 8px 0px;

  padding: 5px;
  cursor: move;
  z-index: 10;
  color: #fff;
}

#commentSectionBody {
  overflow: auto;
  padding: 10px;
}

.commentSectionHeaderEmpty {
  background-color: #2196F3;
}

.commentSectionHeaderNotEmpty {
  background-color: #FFA726;
  box-shadow: inset 0 1px #FFE0B2, 0 1px 2px rgba(0, 0, 0, 0.2);

}

.commentUpButton {
  color: darkblue;
  margin: 5px;
  border-color: #FB8C00;
  background: linear-gradient(to bottom, #FFB74D 0%, #FFA726 100%);
  box-shadow: inset 0 1px #FFE0B2, 0 1px 2px rgba(0, 0, 0, 0.2);
}

.commentContext {
  padding-left: 30px;
}

.commentOccurence {
  color: #bd93f9;
  display: inline-block;
}

.commentKind {
  color: #bd93f9;
}

.commentMessage {
  padding-left: 5px;
  color: #fff;
}

.commentActionContext {
  color: #61cbe0;
  padding-left: 5px;
}
`;


/***/ }),

/***/ "./src/tabScript/application/EventListenerApplication.ts":
/*!***************************************************************!*\
  !*** ./src/tabScript/application/EventListenerApplication.ts ***!
  \***************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
class EventListenerApplication {
    constructor(ruleService, backgroundMessageService) {
        this.ruleService = ruleService;
        this.handledEvents = [];
        this.newActionCallbacks = [];
        this.backgroundMessageService = backgroundMessageService;
        this.exploratoryListener = this.exploratoryListener.bind(this);
    }
    exploratoryListener(event) {
        if (!event.explored) {
            event.explored = true;
            const listenedElement = this.ruleService.getListenedElements(event);
            return this.ruleService.getMatchingRules(event, listenedElement).then((rules) => {
                if (rules && rules.length > 0) {
                    for (const rule of rules) {
                        const action = rule.makeAction(event, listenedElement);
                        if (action) {
                            return this.backgroundMessageService.sendAction(action).then(() => {
                                this.newActionCallbacks.forEach(callback => callback(action));
                            });
                        }
                        else
                            return Promise.resolve();
                    }
                }
            });
        }
        else {
            return Promise.resolve();
        }
    }
    addNewActionCallback(callback) {
        if (typeof callback === "function") {
            this.newActionCallbacks.push(callback);
        }
    }
    adaptToWebSite(webSite) {
        this.handledEvents = [];
        webSite.mappingList.forEach((mapping) => {
            let event = mapping.match.event;
            if (!this.handledEvents.includes(event)) {
                this.handledEvents.push(event);
            }
        });
    }
    unlisten() {
        this.handledEvents.forEach((handledEvent) => {
            window.removeEventListener(handledEvent, this.exploratoryListener, true);
        });
    }
    listen() {
        const events = this.ruleService.getEventsToHandle();
        this.handledEvents = events;
        this.handledEvents.forEach((handledEvent) => {
            window.addEventListener(handledEvent, this.exploratoryListener, true);
        });
    }
    onExplorationStarted() {
        this.listen();
        return Promise.resolve();
    }
    onExplorationStopped() {
        this.unlisten();
        return Promise.resolve();
    }
    onReload() {
        this.unlisten();
        this.listen();
        return Promise.resolve();
    }
}
exports.default = EventListenerApplication;


/***/ }),

/***/ "./src/tabScript/application/StyleApplication.ts":
/*!*******************************************************!*\
  !*** ./src/tabScript/application/StyleApplication.ts ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const PageMutationHandler_1 = __importDefault(__webpack_require__(/*! ../_ui/PageMutationHandler */ "./src/tabScript/_ui/PageMutationHandler.ts"));
const ActionBorderView_1 = __importDefault(__webpack_require__(/*! ../_ui/ActionBorderView */ "./src/tabScript/_ui/ActionBorderView.ts"));
const ActionsPopupView_1 = __importDefault(__webpack_require__(/*! ../_ui/ActionsPopupView */ "./src/tabScript/_ui/ActionsPopupView.ts"));
const CommentPopupView_1 = __importDefault(__webpack_require__(/*! ../_ui/CommentPopupView */ "./src/tabScript/_ui/CommentPopupView.ts"));
const REFRESH_INTERVAL = 8000;
class StyleApplication {
    constructor(state, ruleService, backgroundMessageService) {
        this.state = state;
        this.ruleService = ruleService;
        this.actionDisplay = new ActionBorderView_1.default();
        this.actionPopup = new ActionsPopupView_1.default(this.onMouseHoverAction.bind(this));
        this.commentPopup = new CommentPopupView_1.default(this.onCommentPopupMove.bind(this), this.onCommentUp.bind(this));
        this.backgroundMessageService = backgroundMessageService;
        this.mutationController = new PageMutationHandler_1.default(this.onPageMutation.bind(this));
    }
    init() {
        return Promise.all([
            this.mutationController.init(),
            this.actionPopup.init(),
            this.actionDisplay.init(this.state, this.ruleService),
            this.commentPopup.init(this.state.popupCommentPosition)
        ]).then(() => {
            setInterval(() => {
                this.refresh();
            }, REFRESH_INTERVAL);
            return this.refresh();
        });
    }
    show() {
        if (!this.state.isActive) {
            return Promise.resolve();
        }
        return Promise.all([
            this.actionDisplay.show(),
            this.actionPopup.attach(this.state),
            this.commentPopup.show(this.state)
        ])
            .then(() => { return; });
    }
    hide() {
        return Promise.all([
            this.actionDisplay.hide(),
            this.actionPopup.hide(),
            this.commentPopup.hide()
        ])
            .then(() => { return; });
    }
    refresh() {
        if (!this.state.isActive) {
            return Promise.resolve();
        }
        const refreshActionsPromise = this.backgroundMessageService.getProbabilityMap()
            .then((probabilityMap) => {
            this.state.elementActionListMap = probabilityMap.getActionsForElement(this.ruleService);
            return Promise.all([
                this.actionDisplay.refresh(this.state, this.ruleService),
                this.actionPopup.refresh(this.state),
            ]);
        });
        const refreshCommentsPromise = this.backgroundMessageService.getCommentList()
            .then((commentList) => {
            this.state.commentList = commentList;
            return this.commentPopup.refresh(this.state);
        });
        return Promise.all([
            refreshActionsPromise,
            refreshCommentsPromise
        ]).then(() => { });
    }
    onExplorationStopped() {
        this.state.isActive = false;
        return this.hide();
    }
    onExplorationStarted() {
        this.state.isActive = true;
        return this.show();
    }
    onActionPushed(action) {
        return this.refresh();
    }
    onReload() {
        return this.backgroundMessageService.getState()
            .then(state => {
            this.state = state;
            this.ruleService.loadRules(this.state.webSite);
        }).then(() => {
            return this.refresh();
        });
    }
    onPageMutation() {
        return this.refresh();
    }
    onCommentPopupMove(newPosition) {
        return this.backgroundMessageService.setCommentPopupPosition(newPosition);
    }
    onCommentUp(comment) {
        return this.backgroundMessageService.upComment(comment);
    }
    onMouseHoverAction() {
        if (this.state.isActive) {
            return this.actionPopup.refresh(this.state).then(() => {
                this.actionPopup.show();
            });
        }
        return Promise.resolve();
    }
}
exports.default = StyleApplication;


/***/ }),

/***/ "./src/tabScript/domain/Action.ts":
/*!****************************************!*\
  !*** ./src/tabScript/domain/Action.ts ***!
  \****************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
class Action {
    constructor(prefix, suffix) {
        this.prefix = prefix;
        this.suffix = suffix;
        this.probability = 0;
    }
    toString() {
        if (this.suffix) {
            return `${this.prefix}$${this.suffix}`;
        }
        else {
            return this.prefix;
        }
    }
    equals(action) {
        return ((this.prefix === action.prefix) && (this.suffix === action.suffix));
    }
    static parseAction(actionText) {
        const parts = actionText.split("$");
        if (parts.length === 1) {
            return new Action(parts[0]);
        }
        else if (parts.length === 2) {
            return new Action(parts[0], parts[1]);
        }
        else {
            throw new Error("Failed to parse action : " + actionText);
        }
    }
}
exports.default = Action;


/***/ }),

/***/ "./src/tabScript/domain/ActionProbabilityMap.ts":
/*!******************************************************!*\
  !*** ./src/tabScript/domain/ActionProbabilityMap.ts ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Action_1 = __importDefault(__webpack_require__(/*! ./Action */ "./src/tabScript/domain/Action.ts"));
class ActionProbabilityMap {
    constructor(map) {
        this.map = map;
    }
    getProbability(action) {
        const actionText = action.toString();
        return this.map.get(actionText);
    }
    getActions() {
        let actions = [];
        for (const key of this.map.keys()) {
            actions.push(Action_1.default.parseAction(key));
        }
    }
    equals(map2) {
        var testVal;
        if (!this.map || !map2) {
            return false;
        }
        if (this.map.size !== map2.size) {
            return false;
        }
        for (var [key, val] of this.map) {
            testVal = map2.get(key);
            if (testVal !== val || (testVal === undefined && !map2.has(key))) {
                return false;
            }
        }
        return true;
    }
    getActionsForElement(ruleService) {
        let elementActionsMap = new Map();
        for (let [actionText, probability] of this.map) {
            const action = Action_1.default.parseAction(actionText);
            const elements = ruleService.actionToElements(action);
            elements.forEach((element) => {
                if (!elementActionsMap.has(element)) {
                    elementActionsMap.set(element, []);
                }
                let actions = elementActionsMap.get(element);
                action.probability = probability;
                actions.push(action);
            });
        }
        return elementActionsMap;
    }
}
exports.default = ActionProbabilityMap;


/***/ }),

/***/ "./src/tabScript/domain/Comment.ts":
/*!*****************************************!*\
  !*** ./src/tabScript/domain/Comment.ts ***!
  \*****************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const CommentDistribution_1 = __importDefault(__webpack_require__(/*! ./CommentDistribution */ "./src/tabScript/domain/CommentDistribution.ts"));
class Comment {
    constructor(type, note) {
        this.type = type;
        this.note = note;
        this.distributionList = [];
    }
    addDistribution(noteOccurence, contextOccurence, context) {
        const distribution = new CommentDistribution_1.default(context, contextOccurence, noteOccurence);
        this.distributionList.push(distribution);
    }
    toString() {
        return `${this.type}: ${this.note}`;
    }
    static parseComment(commentText) {
        const parts = commentText.split("$");
        if (parts.length === 2) {
            return new Comment(parts[0], parts[1]);
        }
        else {
            throw new Error("Failed to parse comment : " + commentText);
        }
    }
}
exports.default = Comment;


/***/ }),

/***/ "./src/tabScript/domain/CommentDistribution.ts":
/*!*****************************************************!*\
  !*** ./src/tabScript/domain/CommentDistribution.ts ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
class CommentDistribution {
    constructor(actions = [], occurence, noteOccurence) {
        this.actions = actions;
        this.occurence = occurence;
        this.noteOccurence = noteOccurence;
    }
}
exports.default = CommentDistribution;


/***/ }),

/***/ "./src/tabScript/domain/State.ts":
/*!***************************************!*\
  !*** ./src/tabScript/domain/State.ts ***!
  \***************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
class State {
    constructor(commentsUp = [], displayComments, isActive = false, webSite, popupCommentPosition) {
        this.isActive = isActive;
        this.displayComments = displayComments;
        this.nextActions = [];
        this.webSite = webSite;
        this.commentList = [];
        this.commentsUp = commentsUp;
        this.popupCommentPosition = popupCommentPosition;
        this.elementActionListMap = new Map();
    }
}
exports.default = State;


/***/ }),

/***/ "./src/tabScript/domain/rules/ActionStrategy/IndexStrategy.ts":
/*!********************************************************************!*\
  !*** ./src/tabScript/domain/rules/ActionStrategy/IndexStrategy.ts ***!
  \********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const query_selector_shadow_dom_1 = __webpack_require__(/*! query-selector-shadow-dom */ "./node_modules/query-selector-shadow-dom/src/querySelectorDeep.js");
const Action_1 = __importDefault(__webpack_require__(/*! ../../Action */ "./src/tabScript/domain/Action.ts"));
class IndexStrategy {
    static makeAction(rule, event, listenedElement) {
        let matchingElements;
        if (rule.xpath) {
            let result = document.evaluate(rule.xpath, document, null, XPathResult.ANY_TYPE, null);
            matchingElements = [];
            let node = result.iterateNext();
            while (node) {
                matchingElements.push(node);
                node = result.iterateNext();
            }
        }
        else {
            matchingElements = query_selector_shadow_dom_1.querySelectorAllDeep(rule.css);
        }
        for (let i = 0; i < matchingElements.length; i++) {
            if (matchingElements[i] === listenedElement) {
                return new Action_1.default(rule.prefix, i.toString());
            }
        }
        return null;
    }
    static actionToElements(rule, action) {
        if (action.prefix !== rule.prefix) {
            return [];
        }
        const index = action.suffix;
        let elements;
        if (rule.xpath) {
            let result = document.evaluate(rule.xpath, document, null, XPathResult.ANY_TYPE, null);
            elements = [];
            let node = result.iterateNext();
            while (node) {
                elements.push(node);
                node = result.iterateNext();
            }
        }
        else {
            elements = query_selector_shadow_dom_1.querySelectorAllDeep(rule.css);
        }
        if (index) {
            if (elements.length > index) {
                return [elements[index]];
            }
            else {
                return [];
            }
        }
        else {
            return elements;
        }
    }
}
exports.default = IndexStrategy;


/***/ }),

/***/ "./src/tabScript/domain/rules/ActionStrategy/InnerTextStrategy.ts":
/*!************************************************************************!*\
  !*** ./src/tabScript/domain/rules/ActionStrategy/InnerTextStrategy.ts ***!
  \************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const query_selector_shadow_dom_1 = __webpack_require__(/*! query-selector-shadow-dom */ "./node_modules/query-selector-shadow-dom/src/querySelectorDeep.js");
const Action_1 = __importDefault(__webpack_require__(/*! ../../Action */ "./src/tabScript/domain/Action.ts"));
class InnerTextStrategy {
    static makeAction(rule, event, listenedElement) {
        return new Action_1.default(rule.prefix, listenedElement.innerText);
    }
    static actionToElements(rule, action) {
        if (action.prefix !== rule.prefix) {
            return [];
        }
        let elements;
        if (rule.xpath) {
            let result = document.evaluate(rule.xpath, document, null, XPathResult.ANY_TYPE, null);
            elements = [];
            let node = result.iterateNext();
            while (node) {
                elements.push(node);
                node = result.iterateNext();
            }
        }
        else {
            elements = query_selector_shadow_dom_1.querySelectorAllDeep(rule.css);
        }
        if (action.suffix) {
            return elements.filter(domElement => domElement.innerText.trim() === action.suffix.trim());
        }
        else {
            return elements;
        }
    }
}
exports.default = InnerTextStrategy;


/***/ }),

/***/ "./src/tabScript/domain/rules/ActionStrategy/SimpleStrategy.ts":
/*!*********************************************************************!*\
  !*** ./src/tabScript/domain/rules/ActionStrategy/SimpleStrategy.ts ***!
  \*********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const query_selector_shadow_dom_1 = __webpack_require__(/*! query-selector-shadow-dom */ "./node_modules/query-selector-shadow-dom/src/querySelectorDeep.js");
const Action_1 = __importDefault(__webpack_require__(/*! ../../Action */ "./src/tabScript/domain/Action.ts"));
class SimpleStrategy {
    static makeAction(rule, event, listenedElement) {
        return new Action_1.default(rule.prefix);
    }
    static actionToElements(rule, action) {
        if (action.prefix !== rule.prefix) {
            return [];
        }
        let elements;
        if (rule.xpath) {
            let result = document.evaluate(rule.xpath, document, null, XPathResult.ANY_TYPE, null);
            elements = [];
            let node = result.iterateNext();
            while (node) {
                elements.push(node);
                node = result.iterateNext();
            }
        }
        else {
            elements = query_selector_shadow_dom_1.querySelectorAllDeep(rule.css);
        }
        return elements;
    }
}
exports.default = SimpleStrategy;


/***/ }),

/***/ "./src/tabScript/domain/rules/ActionStrategy/ValueStrategy.ts":
/*!********************************************************************!*\
  !*** ./src/tabScript/domain/rules/ActionStrategy/ValueStrategy.ts ***!
  \********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const query_selector_shadow_dom_1 = __webpack_require__(/*! query-selector-shadow-dom */ "./node_modules/query-selector-shadow-dom/src/querySelectorDeep.js");
const Action_1 = __importDefault(__webpack_require__(/*! ../../Action */ "./src/tabScript/domain/Action.ts"));
class ValueStrategy {
    static makeAction(rule, event, listenedElement) {
        return new Action_1.default(rule.prefix, event.target.value);
    }
    static actionToElements(rule, action) {
        if (action.prefix !== rule.prefix) {
            return [];
        }
        let elements;
        if (rule.xpath) {
            let result = document.evaluate(rule.xpath, document, null, XPathResult.ANY_TYPE, null);
            elements = [];
            let node = result.iterateNext();
            while (node) {
                elements.push(node);
                node = result.iterateNext();
            }
        }
        else {
            elements = query_selector_shadow_dom_1.querySelectorAllDeep(rule.css);
        }
        return elements;
    }
}
exports.default = ValueStrategy;


/***/ }),

/***/ "./src/tabScript/domain/rules/Rule.ts":
/*!********************************************!*\
  !*** ./src/tabScript/domain/rules/Rule.ts ***!
  \********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const IndexStrategy_1 = __importDefault(__webpack_require__(/*! ./ActionStrategy/IndexStrategy */ "./src/tabScript/domain/rules/ActionStrategy/IndexStrategy.ts"));
const SimpleStrategy_1 = __importDefault(__webpack_require__(/*! ./ActionStrategy/SimpleStrategy */ "./src/tabScript/domain/rules/ActionStrategy/SimpleStrategy.ts"));
const InnerTextStrategy_1 = __importDefault(__webpack_require__(/*! ./ActionStrategy/InnerTextStrategy */ "./src/tabScript/domain/rules/ActionStrategy/InnerTextStrategy.ts"));
const ValueStrategy_1 = __importDefault(__webpack_require__(/*! ./ActionStrategy/ValueStrategy */ "./src/tabScript/domain/rules/ActionStrategy/ValueStrategy.ts"));
class Rule {
    constructor(prefix, suffix, event, css, xpath, code, key) {
        this.event = event;
        this.code = code;
        this.css = css;
        this.xpath = xpath;
        this.prefix = prefix;
        this.suffix = suffix;
        this.key = key;
        switch (suffix) {
            case "index":
                this.strategy = IndexStrategy_1.default;
                break;
            case "value":
                this.strategy = ValueStrategy_1.default;
                break;
            case "innerText":
                this.strategy = InnerTextStrategy_1.default;
                break;
            case "none":
                this.strategy = SimpleStrategy_1.default;
                break;
            default:
                this.strategy = SimpleStrategy_1.default;
        }
    }
    match(event) {
        if (event.type !== this.event) {
            return false;
        }
        if (this.event === "keyup" || this.event === "keydown" || this.event === "keypress") {
            if (this.code && event.code !== this.code) {
                return false;
            }
            if (this.key && event.key !== this.key) {
                return false;
            }
        }
        return true;
    }
    makeAction(event, listenedElement) {
        console.log('make action CSS:', this.css);
        console.log('make action Xpath:', this.css);
        return this.strategy.makeAction(this, event, listenedElement);
    }
    actionToElements(action) {
        return this.strategy.actionToElements(this, action);
    }
}
exports.default = Rule;


/***/ }),

/***/ "./src/tabScript/domain/rules/RuleRepository.ts":
/*!******************************************************!*\
  !*** ./src/tabScript/domain/rules/RuleRepository.ts ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Rule_1 = __importDefault(__webpack_require__(/*! ./Rule */ "./src/tabScript/domain/rules/Rule.ts"));
class RuleRepository {
    constructor() {
        this.rulePrefixToRuleMap = new Map();
    }
    addRule(data) {
        const rule = new Rule_1.default(data.output.prefix, data.output.suffix, data.match.event, data.match.css, data.match.xpath, data.match.code, data.match.key);
        if (!this.rulePrefixToRuleMap.has(rule.prefix)) {
            this.rulePrefixToRuleMap.set(rule.prefix, []);
        }
        this.rulePrefixToRuleMap.get(rule.prefix).push(rule);
    }
    getRulesByPrefix(prefix) {
        return this.rulePrefixToRuleMap.get(prefix);
    }
    getRules() {
        const rulesArrayList = Array.from(this.rulePrefixToRuleMap.values());
        let rules = [];
        rulesArrayList.forEach(ruleList => {
            rules = rules.concat([...ruleList]);
        });
        return rules;
    }
}
exports.default = RuleRepository;


/***/ }),

/***/ "./src/tabScript/domain/rules/RuleService.ts":
/*!***************************************************!*\
  !*** ./src/tabScript/domain/rules/RuleService.ts ***!
  \***************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const RuleRepository_1 = __importDefault(__webpack_require__(/*! ./RuleRepository */ "./src/tabScript/domain/rules/RuleRepository.ts"));
const query_selector_shadow_dom_1 = __webpack_require__(/*! query-selector-shadow-dom */ "./node_modules/query-selector-shadow-dom/src/querySelectorDeep.js");
class RuleService {
    constructor() {
        this.ruleRepository = undefined;
        this.elementRules = new Map();
    }
    getEventsToHandle() {
        return [...new Set(this.ruleRepository.getRules().map((rule) => rule.event))];
    }
    loadRules(website) {
        let mappingList = website.mappingList;
        this.ruleRepository = new RuleRepository_1.default();
        mappingList.forEach((mapping) => {
            this.ruleRepository.addRule(mapping);
        });
    }
    attachRulesToElements() {
        if (this.ruleRepository) {
            this.ruleRepository.getRules().forEach((rule) => {
                let elements;
                if (rule.xpath) {
                    let result = document.evaluate(rule.xpath, document, null, XPathResult.ANY_TYPE, null);
                    elements = [];
                    let node = result.iterateNext();
                    while (node) {
                        elements.push(node);
                        node = result.iterateNext();
                    }
                }
                else {
                    elements = query_selector_shadow_dom_1.querySelectorAllDeep(rule.css);
                }
                for (const dom_element of elements) {
                    if (!this.elementRules.has(dom_element)) {
                        this.elementRules.set(dom_element, []);
                    }
                    let rulesOnElement = this.elementRules.get(dom_element);
                    rulesOnElement.push(rule);
                }
            });
        }
    }
    getMatchingRules(event, listenedElement) {
        return new Promise((resolve) => {
            const rules = this.elementRules.get(listenedElement);
            const matchingRules = [];
            if (rules) {
                for (const rule of rules) {
                    if (rule.match(event)) {
                        matchingRules.push(rule);
                    }
                }
            }
            resolve(matchingRules);
        });
    }
    getListenedElements(event) {
        const eventTarget = event.composedPath()[0];
        for (const [element] of this.elementRules) {
            if (eventTarget instanceof Node && element.contains(eventTarget)) {
                return element;
            }
        }
    }
    actionToElements(action) {
        const rules = this.ruleRepository.getRulesByPrefix(action.prefix);
        const elementSet = new Set();
        if (rules && rules.length > 0) {
            for (const rule of rules) {
                let elementsForRule = rule.actionToElements(action);
                elementsForRule.forEach(element => elementSet.add(element));
            }
        }
        return [...elementSet];
    }
}
exports.default = RuleService;


/***/ }),

/***/ "./src/tabScript/index.ts":
/*!********************************!*\
  !*** ./src/tabScript/index.ts ***!
  \********************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const EventListenerApplication_1 = __importDefault(__webpack_require__(/*! ./application/EventListenerApplication */ "./src/tabScript/application/EventListenerApplication.ts"));
const RuleService_1 = __importDefault(__webpack_require__(/*! ./domain/rules/RuleService */ "./src/tabScript/domain/rules/RuleService.ts"));
const StyleApplication_1 = __importDefault(__webpack_require__(/*! ./application/StyleApplication */ "./src/tabScript/application/StyleApplication.ts"));
const ChromeBackgroundMessageService_1 = __importDefault(__webpack_require__(/*! ./_infra/ChromeBackgroundMessageService */ "./src/tabScript/_infra/ChromeBackgroundMessageService.ts"));
const ChromeMessageListener_1 = __importDefault(__webpack_require__(/*! ./_infra/ChromeMessageListener */ "./src/tabScript/_infra/ChromeMessageListener.ts"));
console.log("AIFEX script is running.");
const ruleService = new RuleService_1.default();
const backgroundMessageService = new ChromeBackgroundMessageService_1.default();
backgroundMessageService.getState().then(state => {
    ruleService.loadRules(state.webSite);
    const styleApplication = new StyleApplication_1.default(state, ruleService, backgroundMessageService);
    styleApplication.init();
    const eventListener = new EventListenerApplication_1.default(ruleService, backgroundMessageService);
    eventListener.listen();
    const backgroundMessageListener = new ChromeMessageListener_1.default(styleApplication, eventListener);
    backgroundMessageListener.listenBackground();
    eventListener.addNewActionCallback(() => styleApplication.onActionPushed);
});


/***/ })

/******/ });
//# sourceMappingURL=tabScript.js.map