(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	else if(typeof define === 'function' && define.amd)
		define([], factory);
	else if(typeof exports === 'object')
		exports["main"] = factory();
	else
		root["main"] = factory();
})((typeof self !== 'undefined' ? self : this), function() {
return /******/ (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 = 0);
/******/ })
/************************************************************************/
/******/ ({

/***/ "./GithubBitFactory.ts":
/*!*****************************!*\
  !*** ./GithubBitFactory.ts ***!
  \*****************************/
/*! exports provided: GithubBitFactory */
/*! exports used: GithubBitFactory */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return GithubBitFactory; });
/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lodash */ "lodash");
/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_0__);


/**
 * Creates bits out of github models.
 */
class GithubBitFactory {
  constructor(utils) {
    this.utils = utils;
  }
  /**
   * Creates a new bit from a given Github issue.
   */


  createTaskBit(issue, comments) {
    const createdAt = new Date(issue.createdAt).getTime();
    const updatedAt = new Date(issue.updatedAt).getTime();
    const data = {
      closed: issue.closed,
      body: issue.body,
      comments: comments.map(comment => {
        // note: if user is removed on a github comment will have author set to "null"
        return {
          author: comment.author ? {
            avatarUrl: comment.author.avatarUrl,
            login: comment.author.login,
            email: comment.author.email
          } : undefined,
          createdAt: comment.createdAt,
          body: comment.body
        };
      }),
      author: issue.author ? {
        avatarUrl: issue.author.avatarUrl,
        login: issue.author.login,
        email: issue.author.email
      } : undefined,
      labels: issue.labels.edges.map(label => ({
        name: label.node.name,
        description: label.node.description,
        color: label.node.color,
        url: label.node.url
      }))
    };
    return this.utils.createBit({
      type: 'task',
      originalId: issue.id,
      title: issue.title,
      body: issue.bodyText,
      webLink: issue.url,
      location: {
        id: issue.repository.id,
        name: issue.repository.name,
        webLink: issue.repository.url,
        desktopLink: ''
      },
      data,
      bitCreatedAt: createdAt,
      bitUpdatedAt: updatedAt
    });
  }
  /**
   * Finds all participated people in a github issue and creates app
   * people from them.
   */


  createPersonBitFromIssue(issue) {
    return issue.participants.edges.map(user => user.node).filter(user => !!user).map(githubPerson => this.createPersonBitFromGithubUser(githubPerson));
  }
  /**
   * Finds all participated people in a github pull request and creates app
   * people from them.
   */


  createPersonBitFromPullRequest(pr) {
    const commits = pr.commits.edges.map(edge => edge.node.commit);
    const reviews = pr.reviews.edges.map(edge => edge.node);
    const githubPeople = Object(lodash__WEBPACK_IMPORTED_MODULE_0__["uniqBy"])([pr.author, ...pr.participants.edges.map(user => user.node), ...reviews.map(user => user.author), ...commits.filter(commit => !!commit.user).map(commit => commit.user)], 'id').filter(user => !!user);
    const usersFromCommit = commits.filter(commit => {
      return !commit.user && githubPeople.find(person => person.email === commit.email);
    });
    return [...githubPeople.map(githubPerson => this.createPersonBitFromGithubUser(githubPerson)), ...usersFromCommit.map(commit => this.createPersonBitFromCommit(commit))];
  }
  /**
   * Creates a single app person from given Github user.
   */


  createPersonBitFromGithubUser(githubPerson) {
    return this.utils.createBit({
      type: 'person',
      originalId: githubPerson.id,
      title: githubPerson.login,
      email: githubPerson.email,
      photo: githubPerson.avatarUrl,
      webLink: "https://github.com/" + githubPerson.login
    });
  }
  /**
   * Creates a single app person from a commit.
   */


  createPersonBitFromCommit(commit) {
    return this.utils.createBit({
      type: 'person',
      originalId: commit.email,
      title: commit.name,
      email: commit.email,
      photo: commit.avatarUrl
    });
  }

}

/***/ }),

/***/ "./GithubLoader.ts":
/*!*************************!*\
  !*** ./GithubLoader.ts ***!
  \*************************/
/*! exports provided: GithubLoader */
/*! exports used: GithubLoader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return GithubLoader; });
/* harmony import */ var _o_kit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @o/kit */ "@o/kit");
/* harmony import */ var _o_kit__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_o_kit__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _GithubQueries__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./GithubQueries */ "./GithubQueries.ts");


/**
 * Defines a loading throttling.
 * This is required to not overload user network with service queries.
 */

const THROTTLING = {
  /**
   * Delay before organizations list load.
   */
  organizations: 100,

  /**
   * Delay before file repositories load.
   */
  repositories: 100,

  /**
   * Delay before issues load.
   */
  issues: 100,

  /**
   * Delay before issue or pull request comments load.
   */
  comments: 100,

  /**
   * Delay before pull requests load.
   */
  pullRequests: 100,

  /**
   * Delay before file users load.
   */
  users: 100
  /**
   * Options for loadIssues and loadPullRequests methods.
   */

};

/**
 * Performs requests GitHub API.
 */
class GithubLoader {
  constructor(app, log) {
    this.app = void 0;
    this.log = void 0;
    this.loader = void 0;
    this.totalCost = 0;
    this.remainingCost = 0;
    this.app = app;
    this.log = log || new _o_kit__WEBPACK_IMPORTED_MODULE_0__["Logger"]('service:github:loader:' + app.id);
    this.loader = new _o_kit__WEBPACK_IMPORTED_MODULE_0__["ServiceLoader"](this.app, this.log, {
      baseUrl: 'https://api.github.com/graphql',
      headers: {
        Authorization: "Bearer " + this.app.token
      }
    });
  }
  /**
   * Loads all user organizations.
   */


  async loadOrganizations() {
    this.log.verbose('loading organizations');
    const organizations = await this.loadOrganizationsByCursor();
    this.log.verbose("loading is finished. Loaded " + organizations.length + " issues. " + ("Total query cost: " + this.totalCost + "/" + this.remainingCost), organizations);
    return organizations;
  }
  /**
   * Loads all user repositories.
   */


  async loadUserRepositories() {
    this.log.timer('load API repositories');
    const repositories = await this.loadRepositoriesByCursor();
    this.log.verbose("loaded " + repositories.length + " repositories. " + ("Total query cost: " + this.totalCost + "/" + this.remainingCost), repositories);
    this.log.timer('load API repositories', repositories);
    return repositories;
  }
  /**
   * Loads repository information for all given repository names.
   */


  async loadRepositories(names) {
    this.log.vtimer('repositories load', names);
    const repositories = [];

    for (let name of names) {
      await Object(_o_kit__WEBPACK_IMPORTED_MODULE_0__["sleep"])(THROTTLING.repositories);
      const [organization, repositoryName] = name.replace('http://github.com/', '').replace('https://github.com/', '').split('/');
      const result = await this.load(_GithubQueries__WEBPACK_IMPORTED_MODULE_1__[/* GithubQueries */ "a"].repository(), {
        owner: organization,
        name: repositoryName
      });
      repositories.push(result.repository);
    }

    this.log.vtimer('repositories load', repositories);
    return repositories;
  }
  /**
   * Loads all issues and executes a given callback for each loaded issue.
   */


  async loadIssues(options) {
    const loadRecursively = async options => {
      await Object(_o_kit__WEBPACK_IMPORTED_MODULE_0__["sleep"])(THROTTLING.issues);
      const {
        organization,
        repository,
        cursor,
        loadedCount,
        handler
      } = options;
      const first = 50; // number of issues to load per page

      const results = await this.load(_GithubQueries__WEBPACK_IMPORTED_MODULE_1__[/* GithubQueries */ "a"].issues(), {
        organization,
        repository,
        cursor,
        first
      }); // query was made. calculate total costs

      this.totalCost += results.rateLimit.cost;
      this.remainingCost = results.rateLimit.remaining;
      const hasNextPage = results.repository.issues.pageInfo.hasNextPage;
      const issues = results.repository.issues.nodes;
      const totalCount = results.repository.issues.totalCount;
      const lastEdgeCursor = hasNextPage ? results.repository.issues.pageInfo.endCursor : undefined;
      this.log.verbose(issues.length + " issues were loaded (" + (loadedCount + issues.length) + " of " + totalCount + ")", results); // run streaming callback for each loaded issue

      for (let i = 0; i < issues.length; i++) {
        try {
          const isLast = i === issues.length - 1 && hasNextPage === false;
          const result = await handler(issues[i], lastEdgeCursor, loadedCount + issues.length, isLast); // if callback returned true we don't continue syncing

          if (result === false) {
            this.log.info('stopped issues syncing, no need to sync more', {
              issue: issues[i],
              index: i
            });
            return; // return from the function, not from the loop!
          }
        } catch (error) {
          this.log.warning('error during issue handling', issues[i], error);
        }
      } // if there is a next page we execute next query to api to get all repository issues
      // to get next issues we need a cursor from the last loaded edge
      // and tell github to load issues "after" that cursor
      // cursor basically is a token github returns


      if (hasNextPage) {
        await loadRecursively({
          organization,
          repository,
          cursor: lastEdgeCursor,
          loadedCount: loadedCount + issues.length,
          handler
        });
      }
    };

    this.log.vtimer("sync " + options.organization + "/" + options.repository + " issues");
    await loadRecursively(options);
    this.log.vtimer("sync " + options.organization + "/" + options.repository + " issues");
  }
  /**
   * Loads all pull requests and executes a given callback for each loaded issue.
   */


  async loadPullRequests(options) {
    const loadRecursively = async options => {
      await Object(_o_kit__WEBPACK_IMPORTED_MODULE_0__["sleep"])(THROTTLING.pullRequests);
      const {
        organization,
        repository,
        cursor,
        loadedCount,
        handler
      } = options;
      const first = 50; // number of issues to load per page

      const results = await this.load(_GithubQueries__WEBPACK_IMPORTED_MODULE_1__[/* GithubQueries */ "a"].pullRequests(), {
        organization,
        repository,
        cursor,
        first
      }); // query was made. calculate total costs

      this.totalCost += results.rateLimit.cost;
      this.remainingCost = results.rateLimit.remaining;
      const hasNextPage = results.repository.pullRequests.pageInfo.hasNextPage;
      const pullRequests = results.repository.pullRequests.nodes;
      const totalCount = results.repository.pullRequests.totalCount;
      const lastEdgeCursor = hasNextPage ? results.repository.pullRequests.pageInfo.endCursor : undefined;
      this.log.verbose(pullRequests.length + " pull request were loaded (" + (loadedCount + pullRequests.length) + " of " + totalCount + ")", results); // run streaming callback for each loaded issue

      for (let i = 0; i < pullRequests.length; i++) {
        try {
          const isLast = i === pullRequests.length - 1 && hasNextPage === false;
          const result = await handler(pullRequests[i], lastEdgeCursor, loadedCount + pullRequests.length, isLast); // if callback returned true we don't continue syncing

          if (result === false) {
            this.log.info('stopped pull request syncing, no need to sync more', {
              pullRequest: pullRequests[i],
              index: i
            });
            return; // return from the function, not from the loop!
          }
        } catch (error) {
          this.log.warning('Error during pull request handling ', pullRequests[i], error);
        }
      } // if there is a next page we execute next query to api to get all repository issues
      // to get next issues we need a cursor from the last loaded edge
      // and tell github to load issues "after" that cursor
      // cursor basically is a token github returns


      if (hasNextPage) {
        await loadRecursively({
          organization,
          repository,
          cursor: lastEdgeCursor,
          loadedCount: loadedCount + pullRequests.length,
          handler
        });
      }
    };

    this.log.vtimer("sync " + options.organization + "/" + options.repository + " pull requests");
    await loadRecursively(options);
    this.log.vtimer("sync " + options.organization + "/" + options.repository + " pull requests");
  }
  /**
   * Loads all issue/pull request comments.
   */


  async loadComments(organization, repository, issueOrPrNumber, cursor, loadedCount) {
    if (loadedCount === void 0) {
      loadedCount = 0;
    }

    await Object(_o_kit__WEBPACK_IMPORTED_MODULE_0__["sleep"])(THROTTLING.comments); // send a request to the github and load first/next 100 issues

    const first = 100; // number of issues to load per page

    const results = await this.load(_GithubQueries__WEBPACK_IMPORTED_MODULE_1__[/* GithubQueries */ "a"].comments(), {
      organization,
      repository,
      cursor,
      first,
      issueOrPrNumber
    }); // query was made. calculate total costs

    this.totalCost += results.rateLimit.cost;
    this.remainingCost = results.rateLimit.remaining;
    const commentsNode = results.repository.issueOrPullRequest.comments;
    const comments = commentsNode.nodes;
    const totalCount = commentsNode.totalCount;
    loadedCount += comments.length;
    this.log.verbose(comments.length + " comments were loaded (" + loadedCount + " of " + totalCount + ")", results); // if there is a next page we execute next query to api to get all repository issues
    // to get next issues we need a cursor from the last loaded edge
    // and tell github to load issues "after" that cursor
    // cursor basically is a token github returns

    if (commentsNode.pageInfo.hasNextPage) {
      const lastEdgeCursor = commentsNode.pageInfo.endCursor;
      const nextPageComments = await this.loadComments(organization, repository, issueOrPrNumber, lastEdgeCursor, loadedCount);
      return [...comments, ...nextPageComments];
    }

    return comments;
  }
  /**
   * Loads github people.
   */


  async loadPeople(organization) {
    this.log.verbose("Loading " + organization + " people");
    const people = await this.loadPeopleByCursor(organization);
    this.log.verbose("Loading is finished. Loaded " + people.length + " issues. " + ("Total query cost: " + this.totalCost + "/" + this.remainingCost), people);
    return people;
  }

  async loadOrganizationsByCursor(cursor) {
    await Object(_o_kit__WEBPACK_IMPORTED_MODULE_0__["sleep"])(THROTTLING.organizations); // send a request to the github and load first/next 100 repositories

    const results = await this.load(_GithubQueries__WEBPACK_IMPORTED_MODULE_1__[/* GithubQueries */ "a"].organizations(), {
      cursor
    }); // query was made. calculate total costs

    this.totalCost += results.rateLimit.cost;
    this.remainingCost = results.rateLimit.remaining;
    const edges = results.viewer.organizations.edges;
    const organizations = edges.map(edge => edge.node);
    const totalCount = results.viewer.organizations.totalCount;
    this.log.verbose(organizations.length + " organizations were loaded", results);

    if (results.viewer.organizations.pageInfo.hasNextPage) {
      const lastEdgeCursor = edges[edges.length - 1].cursor;
      this.log.verbose("loading next 100 organizations. Total count is " + totalCount);
      const nextPageOrganizations = await this.loadOrganizationsByCursor(lastEdgeCursor);
      return [...organizations, ...nextPageOrganizations];
    }

    return organizations;
  }

  async loadRepositoriesByCursor(cursor) {
    await Object(_o_kit__WEBPACK_IMPORTED_MODULE_0__["sleep"])(THROTTLING.repositories); // send a request to the github and load first/next 100 repositories

    const results = await this.load(_GithubQueries__WEBPACK_IMPORTED_MODULE_1__[/* GithubQueries */ "a"].userRepositories(), {
      cursor
    }); // query was made. calculate total costs

    this.totalCost += results.rateLimit.cost;
    this.remainingCost = results.rateLimit.remaining;
    const edges = results.viewer.repositories.edges;
    const repositories = edges.map(edge => edge.node);
    const totalCount = results.viewer.repositories.totalCount;
    this.log.verbose(repositories.length + " repositories were loaded", results);

    if (results.viewer.repositories.pageInfo.hasNextPage) {
      const lastEdgeCursor = edges[edges.length - 1].cursor;
      this.log.verbose("loading next 100 repositories. Total count is " + totalCount);
      const nextPageRepositories = await this.loadRepositoriesByCursor(lastEdgeCursor);
      return [...repositories, ...nextPageRepositories];
    }

    return repositories;
  }

  async loadPeopleByCursor(organization, cursor) {
    await Object(_o_kit__WEBPACK_IMPORTED_MODULE_0__["sleep"])(THROTTLING.users); // send a request to the github and load first/next 100 people

    this.log.verbose("Loading " + (cursor ? 'next' : 'first') + " 100 people");
    const results = await this.load(_GithubQueries__WEBPACK_IMPORTED_MODULE_1__[/* GithubQueries */ "a"].people(), {
      organization,
      cursor
    }); // query was made. calculate total costs

    this.totalCost += results.rateLimit.cost;
    this.remainingCost = results.rateLimit.remaining;
    const edges = results.organization.members.edges;
    const issues = edges.map(edge => edge.node);

    if (!cursor) {
      this.log.verbose(issues.length + " people were loaded");
      this.log.verbose("There are " + results.organization.members.totalCount + " people in the repository");
    } else {
      this.log.verbose("Next " + issues.length + " people were loaded");
    } // if there is a next page we execute next query to api to get all repository people
    // to get next people we need a cursor from the last loaded edge
    // and tell github to load people "after" that cursor
    // cursor basically is a token github returns


    if (results.organization.members.pageInfo.hasNextPage) {
      const lastEdgeCursor = edges[edges.length - 1].cursor;
      const nextPageIssues = await this.loadPeopleByCursor(lastEdgeCursor);
      return [...issues, ...nextPageIssues];
    }

    return issues;
  }
  /**
   * Executes load query.
   */


  async load(query, variables) {
    const queryName = query.substr(0, query.indexOf('(') !== -1 ? query.indexOf('(') : query.length).replace('query', '').replace('mutation', '').trim().concat('(', JSON.stringify(variables), ')');
    const result = await this.loader.load({
      path: '?' + queryName,
      method: 'post',
      body: JSON.stringify({
        query,
        variables
      })
    });
    return result.data;
  }

}

/***/ }),

/***/ "./GithubQueries.ts":
/*!**************************!*\
  !*** ./GithubQueries.ts ***!
  \**************************/
/*! exports provided: GithubQueries */
/*! exports used: GithubQueries */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return GithubQueries; });
/**
 * Github Queries.
 */
class GithubQueries {
  /**
   * User repositories query.
   */
  static userRepositories() {
    return "\nquery GithubUserRepositoriesQuery($cursor: String) {\n  viewer {\n    repositories(first: 100, after: $cursor) {\n      totalCount\n      pageInfo {\n        hasNextPage\n      }\n      edges {\n        cursor\n        node {\n          id\n          name\n          nameWithOwner\n          url\n          pushedAt\n          updatedAt\n          issues(first: 1, orderBy: { direction: DESC, field: UPDATED_AT }) {\n            totalCount\n            nodes {\n              updatedAt\n            }\n          }\n          pullRequests(first: 1, orderBy: { direction: DESC, field: UPDATED_AT }) {\n            totalCount\n            nodes {\n              updatedAt\n            }\n          }\n        }\n      }\n    }\n  }\n  rateLimit {\n    limit\n    cost\n    remaining\n    resetAt\n  }\n}\n";
  }
  /**
   * Repository query.
   */


  static repository() {
    return "\nquery GithubRepositoryQuery($owner: String!, $name: String!) {\n  repository(owner: $owner, name: $name) {\n    id\n    name\n    nameWithOwner\n    url\n    pushedAt\n    updatedAt\n    issues(first: 1, orderBy: { direction: DESC, field: UPDATED_AT }) {\n      totalCount\n      nodes {\n        updatedAt\n      }\n    }\n    pullRequests(first: 1, orderBy: { direction: DESC, field: UPDATED_AT }) {\n      totalCount\n      nodes {\n        updatedAt\n      }\n    }\n  }\n  rateLimit {\n    limit\n    cost\n    remaining\n    resetAt\n  }\n}\n";
  }

  static organizations() {
    return "\nquery GithubOrganizationsQuery($cursor: String) {\n  viewer {\n    organizations(first: 100, after: $cursor) {\n      totalCount\n      pageInfo {\n        hasNextPage\n      }\n      edges {\n        cursor\n        node {\n          id\n          name\n        }\n      }\n    }\n  }\n  rateLimit {\n    limit\n    cost\n    remaining\n    resetAt\n  }\n}\n";
  }
  /**
   * Issues query.
   */


  static issues() {
    return "\nquery GithubIssueQuery($organization: String!, $repository: String!, $first: Int!, $cursor: String) {\n  repository(owner: $organization, name: $repository) {\n    id\n    name\n    issues(first: $first, after: $cursor, orderBy: { direction: DESC, field: UPDATED_AT }) {\n      totalCount\n      pageInfo {\n        endCursor\n        hasNextPage\n      }\n      nodes {\n        id\n        title\n        number\n        body\n        bodyText\n        updatedAt\n        createdAt\n        url\n        closed\n        repository {\n          id\n          name\n          url\n          owner {\n            login\n          }\n        }\n        author {\n          ... on User {\n            id\n            login\n            location\n            avatarUrl\n            bio\n            email\n            name\n          }\n        }\n        comments {\n          totalCount\n        }\n        participants(first: 100) {\n          edges {\n            node {\n              ... on User {\n                id\n                login\n                location\n                avatarUrl\n                bio\n                email\n                name\n              }\n            }\n          }\n        }\n        labels(first: 10) {\n          edges {\n            node {\n              name\n              description\n              color\n              url\n            }\n          }\n        }\n      }\n    }\n  }\n  rateLimit {\n    limit\n    cost\n    remaining\n    resetAt\n  }\n}\n";
  }
  /**
   * Issue comments query.
   */


  static comments() {
    return "\nquery GithubCommentsQuery($organization: String!, $repository: String!, $issueOrPrNumber: Int!, $first: Int!, $cursor: String) {\n  repository(owner: $organization, name: $repository) {\n    id\n    name\n    issueOrPullRequest(number: $issueOrPrNumber) {\n      ... on Issue {\n        comments(first: $first, after: $cursor) {\n          totalCount\n          pageInfo {\n            endCursor\n            hasNextPage\n          }\n          nodes {\n            createdAt\n            body\n            author {\n              ... on User {\n                id\n                login\n                location\n                avatarUrl\n                bio\n                email\n                name\n              }\n            }\n          }\n        }\n      }\n      ... on PullRequest {\n        comments(first: $first, after: $cursor) {\n          totalCount\n          pageInfo {\n            endCursor\n            hasNextPage\n          }\n          nodes {\n            createdAt\n            body\n            author {\n              ... on User {\n                id\n                login\n                location\n                avatarUrl\n                bio\n                email\n                name\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n  rateLimit {\n    limit\n    cost\n    remaining\n    resetAt\n  }\n}\n";
  }
  /**
   * Pull requests query.
   */


  static pullRequests() {
    return "\nquery GithubPullRequestsQuery($organization: String!, $repository: String!, $first: Int!, $cursor: String) {\n  repository(owner: $organization, name: $repository) {\n    id\n    name\n    pullRequests(first: $first, after: $cursor, orderBy: { direction: DESC, field: UPDATED_AT }) {\n      totalCount\n      pageInfo {\n        endCursor\n        hasNextPage\n      }\n      nodes {\n        id\n        title\n        number\n        body\n        bodyText\n        updatedAt\n        createdAt\n        url\n        closed\n        repository {\n          id\n          name\n          url\n          owner {\n            login\n          }\n        }\n        author {\n          ... on User {\n            id\n            login\n            location\n            avatarUrl\n            bio\n            email\n            name\n          }\n        }\n        assignees(first: 100) {\n          edges {\n            node {\n              ... on User {\n                id\n                login\n                location\n                avatarUrl\n                bio\n                email\n                name\n              }\n            }\n          }\n        }\n        comments(first: 100) {\n          edges {\n            node {\n              author {\n                ... on User {\n                  id\n                  login\n                  location\n                  avatarUrl\n                  bio\n                  email\n                  name\n                }\n              }\n              createdAt\n              body\n            }\n          }\n        }\n        commits(first: 100) {\n          edges {\n            node {\n              commit {\n                author {\n                  email\n                  name\n                  avatarUrl\n                  user {\n                    ... on User {\n                      id\n                      login\n                      location\n                      avatarUrl\n                      bio\n                      email\n                      name\n                    }\n                  }\n                }\n              }\n            }\n          }\n        }\n        labels(first: 10) {\n          edges {\n            node {\n              name\n              description\n              color\n              url\n            }\n          }\n        }\n        participants(first: 100) {\n          edges {\n            node {\n              ... on User {\n                id\n                login\n                location\n                avatarUrl\n                bio\n                email\n                name\n              }\n            }\n          }\n        }\n        reviews(first: 100) {\n          edges {\n            node {\n              author {\n                ... on User {\n                  id\n                  login\n                  location\n                  avatarUrl\n                  bio\n                  email\n                  name\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n  rateLimit {\n    limit\n    cost\n    remaining\n    resetAt\n  }\n}\n";
  }
  /**
   * People query.
   */


  static people() {
    return "\nquery GithubPeopleQuery($organization: String!, $cursor: String) {\n  organization(login: $organization) {\n    members(first: 100, after: $cursor) {\n      totalCount\n      pageInfo {\n        hasNextPage\n      }\n      edges {\n        cursor\n        node {\n          id\n          login\n          location\n          avatarUrl\n          bio\n          email\n          name\n        }\n      }\n    }\n  }\n  rateLimit {\n    limit\n    cost\n    remaining\n    resetAt\n  }\n}\n";
  }

}

/***/ }),

/***/ "./GithubSettings.tsx":
/*!****************************!*\
  !*** ./GithubSettings.tsx ***!
  \****************************/
/*! exports provided: GithubSettings */
/*! exports used: GithubSettings */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return GithubSettings; });
/* harmony import */ var _o_kit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @o/kit */ "@o/kit");
/* harmony import */ var _o_kit__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_o_kit__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _o_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @o/ui */ "@o/ui");
/* harmony import */ var _o_ui__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_o_ui__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react */ "react");
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var _GithubLoader__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./GithubLoader */ "./GithubLoader.ts");





function GithubSettings() {
  const app = Object(_o_kit__WEBPACK_IMPORTED_MODULE_0__["useApp"])();
  const [repos, setRepos] = Object(_o_kit__WEBPACK_IMPORTED_MODULE_0__["useAppState"])(app.id + "-repositories", []);
  const whitelist = Object(_o_kit__WEBPACK_IMPORTED_MODULE_0__["useWhiteList"])(app.id + "-whitelist", {
    getAll() {
      return (repos || []).map(repo => repo.nameWithOwner);
    }

  }); // load and set repositories when app changes

  Object(react__WEBPACK_IMPORTED_MODULE_2__["useEffect"])(() => {
    if (!app) return;
    const loader = new _GithubLoader__WEBPACK_IMPORTED_MODULE_3__[/* GithubLoader */ "a"](app);
    loader.loadUserRepositories().then(next => {
      setRepos(() => next);
    });
  }, [app && app.token]);
  return react__WEBPACK_IMPORTED_MODULE_2__["createElement"](react__WEBPACK_IMPORTED_MODULE_2__["Fragment"], null, react__WEBPACK_IMPORTED_MODULE_2__["createElement"](_o_kit__WEBPACK_IMPORTED_MODULE_0__["SettingManageRow"], {
    app: app,
    whitelist: whitelist
  }), react__WEBPACK_IMPORTED_MODULE_2__["createElement"](_o_ui__WEBPACK_IMPORTED_MODULE_1__["View"], {
    flex: 1,
    opacity: whitelist.isWhitelisting ? 0.5 : 1,
    pointerEvents: whitelist.isWhitelisting ? 'none' : 'inherit'
  }, react__WEBPACK_IMPORTED_MODULE_2__["createElement"](_o_ui__WEBPACK_IMPORTED_MODULE_1__["Table"], {
    selectable: "multi",
    columns: {
      repo: 'Repository',
      org: 'Organization',
      lastCommit: 'Last Commit',
      numIssues: 'Open Issues',
      active: {
        value: 'Active',
        type: _o_ui__WEBPACK_IMPORTED_MODULE_1__["DataType"].boolean,

        onChange(index) {
          whitelist.toggleWhitelisted(repos[index].nameWithOwner);
        }

      }
    },
    defaultSortOrder: {
      key: 'lastCommit',
      direction: 'up'
    },
    items: (repos || []).map(repository => {
      const [orgName] = repository.nameWithOwner.split('/');
      return {
        org: orgName,
        repo: repository.name,
        lastCommit: new Date(repository.pushedAt),
        numIssues: repository.issues.totalCount,
        active: whitelist.getWhitelisted(repository.nameWithOwner)
      };
    })
  })));
}
GithubSettings.displayName = "GithubSettings";

/***/ }),

/***/ "./GithubSyncer.node.ts":
/*!******************************!*\
  !*** ./GithubSyncer.node.ts ***!
  \******************************/
/*! exports provided: GithubSyncer */
/*! exports used: GithubSyncer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return GithubSyncer; });
/* harmony import */ var _GithubBitFactory__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./GithubBitFactory */ "./GithubBitFactory.ts");
/* harmony import */ var _GithubLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./GithubLoader */ "./GithubLoader.ts");



/**
 * Syncs Github.
 *
 * One important note regarding to github bits syncing - issues and PRs in github never be removed,
 * which means we never remove github bits during regular sync.
 * We only remove when some app change (for example user don't sync specific repository anymore).
 */
const GithubSyncer = async (_ref) => {
  let {
    app,
    log,
    utils
  } = _ref;
  const data = app.data;
  const loader = new _GithubLoader__WEBPACK_IMPORTED_MODULE_1__[/* GithubLoader */ "a"](app, log);
  const factory = new _GithubBitFactory__WEBPACK_IMPORTED_MODULE_0__[/* GithubBitFactory */ "a"](utils);
  /**
   * Handles a single issue or pull request from loaded issues/PRs stream.
   */

  const handleIssueOrPullRequest = async options => {
    const {
      type,
      issueOrPullRequest,
      organization,
      repositoryName,
      cursor,
      loadedCount,
      lastIssue,
      lastSyncInfo
    } = options;
    const updatedAt = new Date(issueOrPullRequest.updatedAt).getTime(); // if we have synced stuff previously already, we need to prevent same issues syncing
    // check if issue's updated date is newer than our last synced date

    if (lastSyncInfo.lastSyncedDate && updatedAt <= lastSyncInfo.lastSyncedDate) {
      log.info('reached last synced date, stop syncing...', {
        issueOrPullRequest,
        updatedAt,
        lastSyncInfo
      }); // if its actually older we don't need to sync this issue and all next ones (since they are sorted by updated date)

      if (lastSyncInfo.lastCursorSyncedDate) {
        // important check, because we can be in this block without loading by cursor
        lastSyncInfo.lastSyncedDate = lastSyncInfo.lastCursorSyncedDate;
      }

      lastSyncInfo.lastCursor = undefined;
      lastSyncInfo.lastCursorSyncedDate = undefined;
      lastSyncInfo.lastCursorLoadedCount = undefined;
      await utils.updateAppData();
      return false; // this tells from the callback to stop issue proceeding
    } // for the first ever synced issue we store its updated date, and once sync is done,
    // next time we make sync again we don't want to sync issues less then this date


    if (!lastSyncInfo.lastCursorSyncedDate) {
      lastSyncInfo.lastCursorSyncedDate = updatedAt;
      log.info('looks like its the first syncing issue, set last synced date', lastSyncInfo);
      await utils.updateAppData();
    }

    const comments = issueOrPullRequest.comments.totalCount > 0 ? await loader.loadComments(organization, repositoryName, issueOrPullRequest.number) : []; // load issue bit from the database

    const bit = factory.createTaskBit(issueOrPullRequest, comments);

    if (type === 'issue') {
      bit.people = factory.createPersonBitFromIssue(issueOrPullRequest);
    } else {
      // pull request
      bit.people = factory.createPersonBitFromPullRequest(issueOrPullRequest);
    }

    await utils.saveBits(bit.people);
    await utils.saveBit(bit); // in the case if its the last issue we need to cleanup last cursor stuff and save last synced date

    if (lastIssue) {
      log.info('looks like its the last issue in this sync, removing last cursor and app last sync date', lastSyncInfo);
      lastSyncInfo.lastSyncedDate = lastSyncInfo.lastCursorSyncedDate;
      lastSyncInfo.lastCursor = undefined;
      lastSyncInfo.lastCursorSyncedDate = undefined;
      lastSyncInfo.lastCursorLoadedCount = undefined;
      await utils.updateAppData();
      return true;
    } // update last sync settings to make sure we continue from the last point in the case if application will stop


    if (lastSyncInfo.lastCursor !== cursor) {
      log.verbose('updating last cursor in settings', {
        cursor
      });
      lastSyncInfo.lastCursor = cursor;
      lastSyncInfo.lastCursorLoadedCount = loadedCount;
      await utils.updateAppData();
    }

    return true;
  }; // load repositories from the API first


  let repositories = await loader.loadUserRepositories(); // get whitelist, if its not defined just return all loaded repositories

  const values = data.values;

  if (values.whitelist !== undefined) {
    log.info('whitelist is defined, filtering settings by a whitelist', values.whitelist);
    repositories = repositories.filter(repository => {
      return values.whitelist.indexOf(repository.nameWithOwner) !== -1;
    });
    log.info('filtered repositories by whitelist', repositories);
  } // if it was defined return filtered repositories


  if (values.externalRepositories && values.externalRepositories.length > 0) {
    log.info('externalRepositories were found', values.externalRepositories);
    repositories.push(...(await loader.loadRepositories(values.externalRepositories)));
  }

  if (!repositories.length) {
    log.info('no repositories were selected in the settings, skip sync');
    return;
  } // initial default settings


  if (!data.values.lastSyncIssues) data.values.lastSyncIssues = {};
  if (!data.values.lastSyncPullRequests) data.values.lastSyncPullRequests = {}; // go through all repositories and sync them all

  log.timer('load api bits and people');

  for (let repository of repositories) {
    await utils.isAborted();
    if (!data.values.lastSyncIssues[repository.nameWithOwner]) data.values.lastSyncIssues[repository.nameWithOwner] = {};
    if (!data.values.lastSyncPullRequests[repository.nameWithOwner]) data.values.lastSyncPullRequests[repository.nameWithOwner] = {};
    const lastSyncIssues = data.values.lastSyncIssues[repository.nameWithOwner];
    const lastSyncPullRequests = data.values.lastSyncPullRequests[repository.nameWithOwner];
    const [organization, repositoryName] = repository.nameWithOwner.split('/'); // compare repository's first issue updated date with our last synced date to make sure
    // something has changed since our last sync. If nothing was changed we skip issues sync

    if (lastSyncIssues.lastSyncedDate && repository.issues.nodes.length && new Date(repository.issues.nodes[0].updatedAt).getTime() === lastSyncIssues.lastSyncedDate) {
      log.verbose("looks like nothing was changed in a " + repository.nameWithOwner + " repository issues from our last sync, skipping");
    } else {
      // load repository issues and sync them in a stream
      await loader.loadIssues({
        organization,
        repository: repositoryName,
        cursor: lastSyncIssues.lastCursor,
        loadedCount: lastSyncIssues.lastCursorLoadedCount || 0,
        handler: (issue, cursor, loadedCount, isLast) => {
          return handleIssueOrPullRequest({
            type: 'issue',
            issueOrPullRequest: issue,
            organization,
            repositoryName,
            cursor,
            loadedCount,
            lastIssue: isLast,
            lastSyncInfo: lastSyncIssues
          });
        }
      });
    } // compare repository's first PR updated date with our last synced date to make sure
    // something has changed since our last sync. If nothing was changed we skip PRs sync


    if (lastSyncPullRequests.lastSyncedDate && repository.pullRequests.nodes.length && new Date(repository.pullRequests.nodes[0].updatedAt).getTime() === lastSyncPullRequests.lastSyncedDate) {
      log.verbose("looks like nothing was changed in a " + repository.nameWithOwner + " repository PRs from our last sync, skipping");
    } else {
      // load repository pull requests and sync them in a stream
      await loader.loadPullRequests({
        organization,
        repository: repositoryName,
        cursor: lastSyncPullRequests.lastCursor,
        loadedCount: lastSyncPullRequests.lastCursorLoadedCount || 0,
        handler: (issue, cursor, loadedCount, isLast) => {
          return handleIssueOrPullRequest({
            type: 'pull-request',
            issueOrPullRequest: issue,
            organization,
            repositoryName,
            cursor,
            loadedCount,
            lastIssue: isLast,
            lastSyncInfo: lastSyncPullRequests
          });
        }
      });
    }
  }

  log.timer('load api bits and people');
};

/***/ }),

/***/ "./GithubSyncerWorker.node.ts":
/*!************************************!*\
  !*** ./GithubSyncerWorker.node.ts ***!
  \************************************/
/*! exports provided: GithubSyncerWorker */
/*! exports used: GithubSyncerWorker */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return GithubSyncerWorker; });
/* harmony import */ var _o_worker_kit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @o/worker-kit */ "@o/worker-kit");
/* harmony import */ var _o_worker_kit__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_o_worker_kit__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _GithubSyncer_node__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./GithubSyncer.node */ "./GithubSyncer.node.ts");


const GithubSyncerWorker = async () => {
  const syncer = new _o_worker_kit__WEBPACK_IMPORTED_MODULE_0__["Syncer"]({
    id: 'github',
    appIdentifier: 'github',
    name: 'Github',
    runner: _GithubSyncer_node__WEBPACK_IMPORTED_MODULE_1__[/* GithubSyncer */ "a"],
    interval: 1000 * 60 * 5 // 5 minutes

  });
  await syncer.start();
};

/***/ }),

/***/ "./api.node.ts":
/*!*********************!*\
  !*** ./api.node.ts ***!
  \*********************/
/*! exports provided: GithubApi */
/*! exports used: GithubApi */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return GithubApi; });
const Octokit = __webpack_require__(/*! @octokit/rest */ "@octokit/rest");
/**
 * @see https://octokit.github.io/rest.js/
 */


const GithubApi = app => {
  const octokit = new Octokit({
    auth: 'token ' + app.token
  });
  return {
    getRepository(params) {
      return octokit.repos.get(params);
    },

    listRepositories(params) {
      return octokit.repos.list(params);
    },

    listRepositoriesForOrg(params) {
      return octokit.repos.listForOrg(params);
    },

    createIssue(params) {
      return octokit.issues.create(params);
    },

    getIssue(params) {
      return octokit.issues.get(params);
    },

    listIssues(params) {
      return octokit.issues.list(params);
    },

    getOrganization(params) {
      return octokit.orgs.get(params);
    },

    listOrganizations(params) {
      return octokit.orgs.list(params);
    },

    createPull(params) {
      return octokit.pulls.create(params);
    },

    getPull(params) {
      return octokit.pulls.get(params);
    },

    listPulls(params) {
      return octokit.pulls.list(params);
    }

  };
};

/***/ }),

/***/ "./graph.node.ts":
/*!***********************!*\
  !*** ./graph.node.ts ***!
  \***********************/
/*! exports provided: graph */
/*! exports used: graph */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return graph; });
async function graph(app) {
  return {
    remoteHttpLink: {
      uri: 'https://api.github.com/graphql',
      fetch,
      headers: {
        Authorization: "bearer " + app.token
      }
    }
  };
}

/***/ }),

/***/ "./index.tsx":
/*!*******************!*\
  !*** ./index.tsx ***!
  \*******************/
/*! exports provided: default */
/*! all exports used */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _o_kit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @o/kit */ "@o/kit");
/* harmony import */ var _o_kit__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_o_kit__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _api_node__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./api.node */ "./api.node.ts");
/* harmony import */ var _GithubSettings__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./GithubSettings */ "./GithubSettings.tsx");
/* harmony import */ var _GithubSyncerWorker_node__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./GithubSyncerWorker.node */ "./GithubSyncerWorker.node.ts");
/* harmony import */ var _graph_node__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./graph.node */ "./graph.node.ts");





/* harmony default export */ __webpack_exports__["default"] = (Object(_o_kit__WEBPACK_IMPORTED_MODULE_0__["createApp"])({
  id: 'github',
  name: 'Github',
  itemType: 'task',
  auth: 'github',
  finishAuth: async (app, values) => {
    app.name = values.info.username;
    return app;
  },
  settings: _GithubSettings__WEBPACK_IMPORTED_MODULE_2__[/* GithubSettings */ "a"],
  api: _api_node__WEBPACK_IMPORTED_MODULE_1__[/* GithubApi */ "a"],
  workers: [_GithubSyncerWorker_node__WEBPACK_IMPORTED_MODULE_3__[/* GithubSyncerWorker */ "a"]],
  graph: _graph_node__WEBPACK_IMPORTED_MODULE_4__[/* graph */ "a"],
  icon: "\n  <svg version=\"1.1\" id=\"Capa_1\" x=\"0px\" y=\"0px\" width=\"438.549px\" height=\"438.549px\" viewBox=\"0 0 438.549 438.549\" style=\"enable-background:new 0 0 438.549 438.549;\">\n    <g>\n      <path fill=\"#000\" d=\"M409.132,114.573c-19.608-33.596-46.205-60.194-79.798-79.8C295.736,15.166,259.057,5.365,219.271,5.365\n        c-39.781,0-76.472,9.804-110.063,29.408c-33.596,19.605-60.192,46.204-79.8,79.8C9.803,148.168,0,184.854,0,224.63\n        c0,47.78,13.94,90.745,41.827,128.906c27.884,38.164,63.906,64.572,108.063,79.227c5.14,0.954,8.945,0.283,11.419-1.996\n        c2.475-2.282,3.711-5.14,3.711-8.562c0-0.571-0.049-5.708-0.144-15.417c-0.098-9.709-0.144-18.179-0.144-25.406l-6.567,1.136\n        c-4.187,0.767-9.469,1.092-15.846,1c-6.374-0.089-12.991-0.757-19.842-1.999c-6.854-1.231-13.229-4.086-19.13-8.559\n        c-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559\n        c-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-0.951-2.568-2.098-3.711-3.429c-1.142-1.331-1.997-2.663-2.568-3.997\n        c-0.572-1.335-0.098-2.43,1.427-3.289c1.525-0.859,4.281-1.276,8.28-1.276l5.708,0.853c3.807,0.763,8.516,3.042,14.133,6.851\n        c5.614,3.806,10.229,8.754,13.846,14.842c4.38,7.806,9.657,13.754,15.846,17.847c6.184,4.093,12.419,6.136,18.699,6.136\n        c6.28,0,11.704-0.476,16.274-1.423c4.565-0.952,8.848-2.383,12.847-4.285c1.713-12.758,6.377-22.559,13.988-29.41\n        c-10.848-1.14-20.601-2.857-29.264-5.14c-8.658-2.286-17.605-5.996-26.835-11.14c-9.235-5.137-16.896-11.516-22.985-19.126\n        c-6.09-7.614-11.088-17.61-14.987-29.979c-3.901-12.374-5.852-26.648-5.852-42.826c0-23.035,7.52-42.637,22.557-58.817\n        c-7.044-17.318-6.379-36.732,1.997-58.24c5.52-1.715,13.706-0.428,24.554,3.853c10.85,4.283,18.794,7.952,23.84,10.994\n        c5.046,3.041,9.089,5.618,12.135,7.708c17.705-4.947,35.976-7.421,54.818-7.421s37.117,2.474,54.823,7.421l10.849-6.849\n        c7.419-4.57,16.18-8.758,26.262-12.565c10.088-3.805,17.802-4.853,23.134-3.138c8.562,21.509,9.325,40.922,2.279,58.24\n        c15.036,16.18,22.559,35.787,22.559,58.817c0,16.178-1.958,30.497-5.853,42.966c-3.9,12.471-8.941,22.457-15.125,29.979\n        c-6.191,7.521-13.901,13.85-23.131,18.986c-9.232,5.14-18.182,8.85-26.84,11.136c-8.662,2.286-18.415,4.004-29.263,5.146\n        c9.894,8.562,14.842,22.077,14.842,40.539v60.237c0,3.422,1.19,6.279,3.572,8.562c2.379,2.279,6.136,2.95,11.276,1.995\n        c44.163-14.653,80.185-41.062,108.068-79.226c27.88-38.161,41.825-81.126,41.825-128.906\n        C438.536,184.851,428.728,148.168,409.132,114.573z\"/>\n    </g>\n  </svg>\n  ",
  iconLight: "\n  <svg id=\"Capa_1\" x=\"0px\" y=\"0px\" width=\"512px\" height=\"512px\" viewBox=\"0 0 438.549 438.549\" style=\"enable-background:new 0 0 438.549 438.549;\">\n    <g>\n      <path d=\"M409.132,114.573c-19.608-33.596-46.205-60.194-79.798-79.8C295.736,15.166,259.057,5.365,219.271,5.365   c-39.781,0-76.472,9.804-110.063,29.408c-33.596,19.605-60.192,46.204-79.8,79.8C9.803,148.168,0,184.854,0,224.63   c0,47.78,13.94,90.745,41.827,128.906c27.884,38.164,63.906,64.572,108.063,79.227c5.14,0.954,8.945,0.283,11.419-1.996   c2.475-2.282,3.711-5.14,3.711-8.562c0-0.571-0.049-5.708-0.144-15.417c-0.098-9.709-0.144-18.179-0.144-25.406l-6.567,1.136   c-4.187,0.767-9.469,1.092-15.846,1c-6.374-0.089-12.991-0.757-19.842-1.999c-6.854-1.231-13.229-4.086-19.13-8.559   c-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559   c-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-0.951-2.568-2.098-3.711-3.429c-1.142-1.331-1.997-2.663-2.568-3.997   c-0.572-1.335-0.098-2.43,1.427-3.289c1.525-0.859,4.281-1.276,8.28-1.276l5.708,0.853c3.807,0.763,8.516,3.042,14.133,6.851   c5.614,3.806,10.229,8.754,13.846,14.842c4.38,7.806,9.657,13.754,15.846,17.847c6.184,4.093,12.419,6.136,18.699,6.136   c6.28,0,11.704-0.476,16.274-1.423c4.565-0.952,8.848-2.383,12.847-4.285c1.713-12.758,6.377-22.559,13.988-29.41   c-10.848-1.14-20.601-2.857-29.264-5.14c-8.658-2.286-17.605-5.996-26.835-11.14c-9.235-5.137-16.896-11.516-22.985-19.126   c-6.09-7.614-11.088-17.61-14.987-29.979c-3.901-12.374-5.852-26.648-5.852-42.826c0-23.035,7.52-42.637,22.557-58.817   c-7.044-17.318-6.379-36.732,1.997-58.24c5.52-1.715,13.706-0.428,24.554,3.853c10.85,4.283,18.794,7.952,23.84,10.994   c5.046,3.041,9.089,5.618,12.135,7.708c17.705-4.947,35.976-7.421,54.818-7.421s37.117,2.474,54.823,7.421l10.849-6.849   c7.419-4.57,16.18-8.758,26.262-12.565c10.088-3.805,17.802-4.853,23.134-3.138c8.562,21.509,9.325,40.922,2.279,58.24   c15.036,16.18,22.559,35.787,22.559,58.817c0,16.178-1.958,30.497-5.853,42.966c-3.9,12.471-8.941,22.457-15.125,29.979   c-6.191,7.521-13.901,13.85-23.131,18.986c-9.232,5.14-18.182,8.85-26.84,11.136c-8.662,2.286-18.415,4.004-29.263,5.146   c9.894,8.562,14.842,22.077,14.842,40.539v60.237c0,3.422,1.19,6.279,3.572,8.562c2.379,2.279,6.136,2.95,11.276,1.995   c44.163-14.653,80.185-41.062,108.068-79.226c27.88-38.161,41.825-81.126,41.825-128.906   C438.536,184.851,428.728,148.168,409.132,114.573z\" fill=\"#FFFFFF\"/>\n    </g>\n  </svg>\n  "
}));

/***/ }),

/***/ 0:
/*!*************************!*\
  !*** multi ./index.tsx ***!
  \*************************/
/*! no static exports found */
/*! all exports used */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(/*! /Users/nw/projects/motion/orbit/apps/github-app/index.tsx */"./index.tsx");


/***/ }),

/***/ "@o/kit":
/*!*************************!*\
  !*** external "@o/kit" ***!
  \*************************/
/*! no static exports found */
/*! exports used: Logger, ServiceLoader, SettingManageRow, createApp, sleep, useApp, useAppState, useWhiteList */
/***/ (function(module, exports) {

module.exports = require("@o/kit");

/***/ }),

/***/ "@o/ui":
/*!************************!*\
  !*** external "@o/ui" ***!
  \************************/
/*! no static exports found */
/*! exports used: DataType, Table, View */
/***/ (function(module, exports) {

module.exports = require("@o/ui");

/***/ }),

/***/ "@o/worker-kit":
/*!********************************!*\
  !*** external "@o/worker-kit" ***!
  \********************************/
/*! no static exports found */
/*! exports used: Syncer */
/***/ (function(module, exports) {

module.exports = require("@o/worker-kit");

/***/ }),

/***/ "@octokit/rest":
/*!********************************!*\
  !*** external "@octokit/rest" ***!
  \********************************/
/*! no static exports found */
/*! all exports used */
/***/ (function(module, exports) {

module.exports = require("@octokit/rest");

/***/ }),

/***/ "lodash":
/*!*************************!*\
  !*** external "lodash" ***!
  \*************************/
/*! no static exports found */
/*! exports used: uniqBy */
/***/ (function(module, exports) {

module.exports = require("lodash");

/***/ }),

/***/ "react":
/*!************************!*\
  !*** external "react" ***!
  \************************/
/*! no static exports found */
/*! exports used: Fragment, createElement, useEffect */
/***/ (function(module, exports) {

module.exports = require("react");

/***/ })

/******/ });
});
//# sourceMappingURL=index.node.js.map